private static void ValidateQueryOptionAllowed(AllowedQueryOptions queryOption, AllowedQueryOptions allowed) { if ((queryOption & allowed) == AllowedQueryOptions.None) { throw new ODataException(Error.Format(SRResources.NotAllowedQueryOption, queryOption, "AllowedQueryOptions")); } }
string GetName(AllowedQueryOptions option) { #pragma warning disable CA1308 // Normalize strings to uppercase var name = option.ToString().ToLowerInvariant(); #pragma warning restore CA1308 return(Settings.NoDollarPrefix ? name : name.Insert(0, "$")); }
/// <summary> /// Allows the specified query options. /// </summary> /// <param name="queryOptions">One or more <see cref="AllowedQueryOptions">allowed query options</see>.</param> /// <returns>The original <see cref="ODataActionQueryOptionsConventionBuilder{T}"/>.</returns> public virtual ODataActionQueryOptionsConventionBuilder <T> Allow(AllowedQueryOptions queryOptions) { Contract.Ensures(Contract.Result <ODataActionQueryOptionsConventionBuilder <T> >() != null); ValidationSettings.AllowedQueryOptions |= queryOptions; return(this); }
/// <summary> /// Apply the individual query to the given IQueryable in the right order. /// </summary> /// <param name="query">The original <see cref="IQueryable"/>.</param> /// <param name="ignoreQueryOptions">The query parameters that are already applied in queries.</param> /// <returns>The new <see cref="IQueryable"/> after the query has been applied to.</returns> public virtual IQueryable ApplyTo(IQueryable query, AllowedQueryOptions ignoreQueryOptions) { _ignoreQueryOptions = ignoreQueryOptions; ODataQuerySettings querySettings = Context.GetODataQuerySettings(); return(ApplyTo(query, querySettings)); }
/// <summary> /// No construtor, cria uma nova configuração de validação para odata /// </summary> public ODataQueryOptionsValidateAttribute(AllowedQueryOptions allowedQueryOptions = AllowedQueryOptions.All ^ AllowedQueryOptions.Expand) { oDataValidationSettings = new ODataValidationSettings() { AllowedQueryOptions = allowedQueryOptions }; }
public sealed override ValueTask <IQueryable> GetAsync(ODataQueryOptions <TEntity> options, ODataQuerySettings querySettings, AllowedQueryOptions ignoreQueryOptions) { var query = PrepareQuery(ref options, ref querySettings, ref ignoreQueryOptions); var result = ApplyQueryOptions(query, options, querySettings, ignoreQueryOptions); return(new ValueTask <IQueryable>(result)); }
string GetName(AllowedQueryOptions option) { Contract.Requires(option == Filter || (option > Filter && option < Supported && ((int)option % 2 == 0))); #pragma warning disable CA1308 // Normalize strings to uppercase var name = option.ToString().ToLowerInvariant(); #pragma warning restore CA1308 return(Settings.NoDollarPrefix ? name : name.Insert(0, "$")); }
public ODataValidationSettings() { // default it to all the operators _allowedArithmeticOperators = AllowedArithmeticOperators.All; _allowedFunctionNames = AllowedFunctionNames.AllFunctionNames; _allowedLogicalOperators = AllowedLogicalOperators.All; _allowedQueryParameters = AllowedQueryOptions.All; _allowedOrderByProperties = new Collection<string>(); }
public ODataValidationSettings() { // default it to all the operators _allowedArithmeticOperators = AllowedArithmeticOperators.All; _allowedFunctionNames = AllowedFunctionNames.AllFunctionNames; _allowedLogicalOperators = AllowedLogicalOperators.All; _allowedQueryParameters = AllowedQueryOptions.All; _allowedOrderByProperties = new Collection <string>(); }
bool IsOrderByEnabled(ModelBoundQuerySettings querySettings) { if (!querySettings.DefaultEnableOrderBy.HasValue) { return(AllowedQueryOptions.HasFlag(OrderBy) || querySettings.OrderByConfigurations.Any(p => p.Value)); } return(querySettings.DefaultEnableOrderBy.Value || querySettings.OrderByConfigurations.Any(p => p.Value)); }
bool IsFilterEnabled(ModelBoundQuerySettings querySettings) { if (!querySettings.DefaultEnableFilter.HasValue) { return(AllowedQueryOptions.HasFlag(Filter) || querySettings.FilterConfigurations.Any(p => p.Value)); } return(querySettings.DefaultEnableFilter.Value || querySettings.FilterConfigurations.Any(p => p.Value)); }
bool IsExpandEnabled(ModelBoundQuerySettings querySettings) { if (!querySettings.DefaultExpandType.HasValue) { return(AllowedQueryOptions.HasFlag(Expand) || querySettings.ExpandConfigurations.Any(p => p.Value.ExpandType != Disabled)); } return(querySettings.DefaultExpandType.Value != Disabled || querySettings.ExpandConfigurations.Any(p => p.Value.ExpandType != Disabled)); }
bool IsSelectEnabled(ModelBoundQuerySettings querySettings) { if (!querySettings.DefaultSelectType.HasValue) { return(AllowedQueryOptions.HasFlag(Select) || querySettings.SelectConfigurations.Any(p => p.Value != Disabled)); } return(querySettings.DefaultSelectType.Value != Disabled || querySettings.SelectConfigurations.Any(p => p.Value != Disabled)); }
public void UnsupportedQueryOptions_SucceedIfGroupAllowed(AllowedQueryOptions unused, string query, string unusedName) { // Arrange HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Get, new Uri("http://localhost/?$" + query)); ODataQueryOptions option = new ODataQueryOptions(_context, message); ODataValidationSettings settings = new ODataValidationSettings() { AllowedQueryOptions = AllowedQueryOptions.All & ~AllowedQueryOptions.Supported, }; // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, settings)); }
internal ODataAttributeVisitor( ODataQueryOptionDescriptionContext context, IEdmModel?model, AllowedQueryOptions allowedQueryOptions, Type?resultType, bool singleResult) { this.context = context; AllowedQueryOptions = allowedQueryOptions; this.resultType = resultType; IsSingleResult = singleResult; this.model = model; typeResolver = new StructuredTypeResolver(model); }
private static TEntity ApplyQueryOptions(TEntity entity, ODataQueryOptions options, ODataQuerySettings querySettings, AllowedQueryOptions ignoreQueryOptions) { _ = entity ?? throw new ArgumentNullException(nameof(entity)); if (options == null) { return(entity); } querySettings = querySettings ?? new ODataQuerySettings(); var result = options.ApplyTo(entity, querySettings, ignoreQueryOptions) as TEntity; return(result); }
public void All_Contains_AllQueryOptions() { AllowedQueryOptions allQueryOptions = 0; foreach (AllowedQueryOptions allowedQueryOption in Enum.GetValues(typeof(AllowedQueryOptions))) { if (allowedQueryOption != AllowedQueryOptions.All) { allQueryOptions = allQueryOptions | allowedQueryOption; } } Assert.Equal(AllowedQueryOptions.All, allQueryOptions); }
public void AllowedQueryOptions_SucceedIfAllowed(AllowedQueryOptions allow, string query, string unused) { // Arrange var message = RequestFactory.Create(HttpMethod.Get, "http://localhost/?$" + query); ODataQueryOptions option = new ODataQueryOptions(_context, message); ODataValidationSettings settings = new ODataValidationSettings() { AllowedQueryOptions = allow, }; // Act & Assert Assert.NotNull(unused); ExceptionAssert.DoesNotThrow(() => _validator.Validate(option, settings)); }
public void UnsupportedQueryOptions_SucceedIfGroupAllowed(AllowedQueryOptions unused, string query, string unusedName) { // Arrange var message = RequestFactory.Create(HttpMethod.Get, "http://localhost/?$" + query); ODataQueryOptions option = new ODataQueryOptions(_context, message); ODataValidationSettings settings = new ODataValidationSettings() { AllowedQueryOptions = AllowedQueryOptions.All & ~AllowedQueryOptions.Supported, }; // Act & Assert Assert.Equal(unused, settings.AllowedQueryOptions); //Equal because only Delta token is unsupported. Assert.NotNull(unusedName); ExceptionAssert.DoesNotThrow(() => _validator.Validate(option, settings)); }
public void SupportedQueryOptions_SucceedIfGroupAllowed(AllowedQueryOptions unused, string query, string unusedName) { // Arrange var message = RequestFactory.Create("Get", "http://localhost/?$" + query, setupAction: null); ODataQueryOptions option = new ODataQueryOptions(_context, message); ODataValidationSettings settings = new ODataValidationSettings() { AllowedQueryOptions = AllowedQueryOptions.Supported, }; // Act & Assert Assert.NotEqual(unused, settings.AllowedQueryOptions); Assert.NotNull(unusedName); ExceptionAssert.DoesNotThrow(() => _validator.Validate(option, settings)); }
private static IQueryable ApplyQueryOptions(IQueryable <TEntity> query, ODataQueryOptions options, ODataQuerySettings querySettings, AllowedQueryOptions ignoreQueryOptions) { _ = query ?? throw new ArgumentNullException(nameof(query)); if (options == null) { return(query); } var result = querySettings == null ? options.ApplyTo(query, ignoreQueryOptions) : options.ApplyTo(query, querySettings, ignoreQueryOptions); return(result); }
public void AllowedQueryOptions_SucceedIfAllowed(AllowedQueryOptions allow, string query, string unused) { // Arrange HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Get, new Uri("http://localhost/?$" + query)); message.EnableHttpDependencyInjectionSupport(); ODataQueryOptions option = new ODataQueryOptions(_context, message); ODataValidationSettings settings = new ODataValidationSettings() { AllowedQueryOptions = allow, }; // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, settings)); }
public void Validate_DoesNotThrow_ForAllowedQueryOptions(string queryOptionName, string queryValue, AllowedQueryOptions queryOption) { // Arrange HttpRequestMessage message = new HttpRequestMessage( HttpMethod.Get, new Uri("http://localhost/?$" + queryOptionName + "=" + queryValue) ); ODataQueryOptions option = new ODataQueryOptions(_context, message); ODataValidationSettings settings = new ODataValidationSettings() { AllowedQueryOptions = queryOption }; // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, settings)); }
public void UnsupportedQueryOptions_ThrowIfGroupNotAllowed(AllowedQueryOptions unused, string query, string optionName) { // Arrange var message = new HttpRequestMessage(HttpMethod.Get, new Uri("http://localhost/?" + query)); var option = new ODataQueryOptions(_context, message); var expectedMessage = string.Format( "Query option '{0}' is not allowed. " + "To allow it, set the 'AllowedQueryOptions' property on EnableQueryAttribute or QueryValidationSettings.", optionName); var settings = new ODataValidationSettings() { AllowedQueryOptions = AllowedQueryOptions.Supported, }; // Act & Assert Assert.Throws <ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void AllowedQueryOptions_ThrowIfNotAllowed(AllowedQueryOptions exclude, string query, string optionName) { // Arrange var message = RequestFactory.Create(HttpMethod.Get, "http://localhost/?" + query); var option = new ODataQueryOptions(_context, message); var expectedMessage = string.Format( "Query option '{0}' is not allowed. " + "To allow it, set the 'AllowedQueryOptions' property on EnableQueryAttribute or QueryValidationSettings.", optionName); var settings = new ODataValidationSettings() { AllowedQueryOptions = AllowedQueryOptions.All & ~exclude, }; // Act & Assert ExceptionAssert.Throws <ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void SupportedQueryOptions_ThrowIfGroupNotAllowed(AllowedQueryOptions unused, string query, string optionName) { // Arrange var message = RequestFactory.Create("Get", "http://localhost/?" + query, setupAction: null); var option = new ODataQueryOptions(_context, message); var expectedMessage = string.Format( "Query option '{0}' is not allowed. " + "To allow it, set the 'AllowedQueryOptions' property on EnableQueryAttribute or QueryValidationSettings.", optionName); var settings = new ODataValidationSettings() { AllowedQueryOptions = AllowedQueryOptions.All & ~AllowedQueryOptions.Supported, }; // Act & Assert Assert.NotEqual(unused, settings.AllowedQueryOptions); ExceptionAssert.Throws <ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void Validate_Throws_ForDisallowedQueryOptions(string queryOptionName, string queryValue, AllowedQueryOptions queryOption) { // Arrange HttpRequestMessage message = new HttpRequestMessage( HttpMethod.Get, new Uri("http://localhost/?$" + queryOptionName + "=" + queryValue) ); ODataQueryOptions option = new ODataQueryOptions(_context, message); ODataValidationSettings settings = new ODataValidationSettings() { AllowedQueryOptions = AllowedQueryOptions.All & ~queryOption }; // Act & Assert var exception = Assert.Throws<ODataException>(() => _validator.Validate(option, settings)); Assert.Equal( "Query option '" + queryOptionName + "' is not allowed. To allow it, set the 'AllowedQueryOptions' property on EnableQueryAttribute or QueryValidationSettings.", exception.Message, StringComparer.OrdinalIgnoreCase); }
/// <inheritdoc /> public virtual string Describe(AllowedQueryOptions queryOption, ODataQueryOptionDescriptionContext context) { if ((queryOption < Filter || queryOption > Supported) || (queryOption != Filter && ((int)queryOption % 2 != 0))) { throw new ArgumentException(SR.MultipleQueryOptionsNotAllowed, nameof(queryOption)); } return(queryOption switch { Filter => DescribeFilter(context), Expand => DescribeExpand(context), Select => DescribeSelect(context), OrderBy => DescribeOrderBy(context), Top => DescribeTop(context), Skip => DescribeSkip(context), Count => DescribeCount(context), #pragma warning disable CA1308 // Normalize strings to uppercase _ => throw new ArgumentException(SR.UnsupportedQueryOption.FormatDefault(queryOption.ToString().ToLowerInvariant()), nameof(queryOption)), #pragma warning restore CA1308 });
/// <inheritdoc /> public virtual string Describe(AllowedQueryOptions queryOption, ODataQueryOptionDescriptionContext context) { Arg.NotNull(context, nameof(context)); if ((queryOption < Filter || queryOption > Supported) || (queryOption != Filter && ((int)queryOption % 2 != 0))) { throw new ArgumentException(SR.MultipleQueryOptionsNotAllowed, nameof(queryOption)); } switch (queryOption) { case Filter: return(DescribeFilter(context)); case Expand: return(DescribeExpand(context)); case Select: return(DescribeSelect(context)); case OrderBy: return(DescribeOrderBy(context)); case Top: return(DescribeTop(context)); case Skip: return(DescribeSkip(context)); case Count: return(DescribeCount(context)); } #pragma warning disable CA1308 // Normalize strings to uppercase throw new ArgumentException(SR.UnsupportedQueryOption.FormatDefault(queryOption.ToString().ToLowerInvariant()), nameof(queryOption)); #pragma warning restore CA1308 }
public void Supported_DoesNotContain_UnsupportedQueryOptions(AllowedQueryOptions queryOption) { Assert.Equal(AllowedQueryOptions.None, AllowedQueryOptions.Supported & queryOption); }
public void Validate_Throws_ForDisallowedQueryOptions(string queryOptionName, string queryValue, AllowedQueryOptions queryOption) { // Arrange HttpRequestMessage message = new HttpRequestMessage( HttpMethod.Get, new Uri("http://localhost/?$" + queryOptionName + "=" + queryValue) ); ODataQueryOptions option = new ODataQueryOptions(_context, message); ODataValidationSettings settings = new ODataValidationSettings() { AllowedQueryOptions = AllowedQueryOptions.All & ~queryOption }; // Act & Assert var exception = Assert.Throws <ODataException>(() => _validator.Validate(option, settings)); Assert.Equal( "Query option '" + queryOptionName + "' is not allowed. To allow it, set the 'AllowedQueryOptions' property on EnableQueryAttribute or QueryValidationSettings.", exception.Message, StringComparer.OrdinalIgnoreCase); }
public void Supported_Contains_SupportedQueryOptions(AllowedQueryOptions queryOption) { Assert.Equal(queryOption, AllowedQueryOptions.Supported & queryOption); }
void Visit <TSetting>( ModelBoundQuerySettings querySettings, ICollection <string> properties, AllowedQueryOptions option, Func <ModelBoundQuerySettings, bool> enabled, IList <string> queryableProperties, Dictionary <string, TSetting> configurations, Func <TSetting, bool> allowed) { Contract.Requires(querySettings != null); Contract.Requires(properties != null); Contract.Requires(enabled != null); Contract.Requires(queryableProperties != null); Contract.Requires(configurations != null); Contract.Requires(allowed != null); if (!enabled(querySettings)) { AllowedQueryOptions &= ~option; queryableProperties.Clear(); return; } AllowedQueryOptions |= option; if (configurations.Count == 0) { // skip property-specific configurations; everything is allowed return; } var comparer = StringComparer.OrdinalIgnoreCase; var allowedProperties = new HashSet <string>(comparer); var disallowedProperties = new HashSet <string>(comparer); foreach (var property in configurations) { var name = property.Key; // note: remember that model bound attributes might be using hardcode attributes. we need // to account for a substituted type on a down-level model where the property does not exist if (!properties.Contains(name)) { continue; } if (allowed(property.Value)) { allowedProperties.Add(name); } else { disallowedProperties.Add(name); } } // if there's no specifically allowed properties, allow them all if (allowedProperties.Count == 0) { foreach (var property in properties) { allowedProperties.Add(property); } } // remove any disallowed properties allowedProperties.ExceptWith(disallowedProperties); // if the final allowed set results in all properties, then clear the // properties to keep message less verbose if (allowedProperties.Count == properties.Count) { queryableProperties.Clear(); return; } foreach (var property in allowedProperties) { queryableProperties.Add(property); } }
public void ApplyTo_Entity_DoesnotApply_IfSetApplied(string queryOption, AllowedQueryOptions allowedQueryOptions) { // Arrange HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost" + queryOption); var builder = new ODataConventionModelBuilder(); builder.EntitySet<Customer>("Customers"); ODataQueryContext context = new ODataQueryContext(builder.GetEdmModel(), typeof(Customer)); ODataQueryOptions options = new ODataQueryOptions(context, request); options.Context.AppliedQueryOptions = allowedQueryOptions; Customer customer = new Customer { CustomerId = 1, Orders = new List<Order> { new Order {OrderId = 1} } }; // Act object result = options.ApplyTo(customer, new ODataQuerySettings()); // Assert Assert.Equal(customer, (result as Customer)); }
public void ApplyTo_DoesnotApply_IfSetApplied(string queryOption, AllowedQueryOptions allowedQueryOptions) { // Arrange HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost" + queryOption); var builder = new ODataConventionModelBuilder(); builder.EntitySet<Customer>("Customers"); ODataQueryContext context = new ODataQueryContext(builder.GetEdmModel(), typeof(Customer)); ODataQueryOptions options = new ODataQueryOptions(context, request); options.Context.AppliedQueryOptions = allowedQueryOptions; IQueryable<Customer> customers = Enumerable.Range(1, 10).Select( i => new Customer { CustomerId = i, Orders = new List<Order> { new Order {OrderId = i} } }) .AsQueryable(); // Act IQueryable result = options.ApplyTo(customers, new ODataQuerySettings()); // Assert Assert.Equal(10, (result as IQueryable<Customer>).Count()); }
public void UnsupportedQueryOptions_ThrowIfGroupNotAllowed(AllowedQueryOptions unused, string query, string optionName) { // Arrange var message = new HttpRequestMessage(HttpMethod.Get, new Uri("http://localhost/?" + query)); var option = new ODataQueryOptions(_context, message); var expectedMessage = string.Format( "Query option '{0}' is not allowed. " + "To allow it, set the 'AllowedQueryOptions' property on EnableQueryAttribute or QueryValidationSettings.", optionName); var settings = new ODataValidationSettings() { AllowedQueryOptions = AllowedQueryOptions.Supported, }; // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }