Skip to content

Commit

Permalink
Updated GraphQL Nested Filter integration tests and GraphQL filter pr…
Browse files Browse the repository at this point in the history
…ocessing (#1407)

## Why make this change?

- Closes #998 which enhances the test suite tests for nested filters in
GraphQL.

## What is this change?

- Updated processing of nested graphql filters such that the target
entity is included in the `@relationship` directive metadata in addition
to a reference to the graphql object name.
- Updated Nested filtering tests to add validation to role, entity, and
field evaluation.
- Updated the authorization resolver to return fewer exceptions and
return "false" when certain permissions aren't met.
- Runtime config entities with the suffix NF represent "nested filter"
entities. These entities are exclusively for nested filter tests so that
the anonymous role can be left out. (allowing only authenticated roles,
allowing us to demonstrate authorization rule processing for graphql.)
these entities have the same backing database object as the entities
without the NF suffix.

## How was this tested?

- [X] Integration Tests
- [ ] Unit Tests
  • Loading branch information
seantleonard authored Apr 5, 2023
1 parent 9643195 commit 893f503
Show file tree
Hide file tree
Showing 20 changed files with 893 additions and 212 deletions.
45 changes: 41 additions & 4 deletions config-generators/mssql-commands.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
init --config "dab-config.MsSql.json" --database-type mssql --set-session-context true --connection-string "Server=tcp:127.0.0.1,1433;Persist Security Info=False;User ID=sa;Password=REPLACEME;MultipleActiveResultSets=False;Connection Timeout=5;" --host-mode Development --cors-origin "http://localhost:5000"
add Publisher --config "dab-config.MsSql.json" --source publishers --permissions "anonymous:read"
add Stock --config "dab-config.MsSql.json" --source stocks --permissions "anonymous:create,read,update"
add Stock --config "dab-config.MsSql.json" --source stocks --permissions "anonymous:create,read,update,delete"
add Book --config "dab-config.MsSql.json" --source books --permissions "anonymous:create,read,update,delete" --graphql "book:books"
add BookWebsitePlacement --config "dab-config.MsSql.json" --source book_website_placements --permissions "anonymous:read"
add Author --config "dab-config.MsSql.json" --source authors --permissions "anonymous:read"
Expand All @@ -10,7 +10,9 @@ add Comic --config "dab-config.MsSql.json" --source comics --permissions "anonym
add Broker --config "dab-config.MsSql.json" --source brokers --permissions "anonymous:read"
add WebsiteUser --config "dab-config.MsSql.json" --source website_users --permissions "anonymous:create,read,delete,update"
add SupportedType --config "dab-config.MsSql.json" --source type_table --permissions "anonymous:create,read,delete,update"
add stocks_price --config "dab-config.MsSql.json" --source stocks_price --permissions "anonymous:read"
add stocks_price --config "dab-config.MsSql.json" --source stocks_price --permissions "authenticated:create,read,update,delete"
update stocks_price --config "dab-config.MsSql.json" --permissions "TestNestedFilterFieldIsNull_ColumnForbidden:read" --fields.exclude "price"
update stocks_price --config "dab-config.MsSql.json" --permissions "TestNestedFilterFieldIsNull_EntityReadForbidden:create"
add Tree --config "dab-config.MsSql.json" --source trees --permissions "anonymous:create,read,update,delete"
add Shrub --config "dab-config.MsSql.json" --source trees --permissions "anonymous:create,read,update,delete" --rest plants
add Fungus --config "dab-config.MsSql.json" --source fungi --permissions "anonymous:create,read,update,delete" --graphql "fungus:fungi"
Expand Down Expand Up @@ -57,7 +59,8 @@ update Publisher --config "dab-config.MsSql.json" --permissions "policy_tester_0
update Publisher --config "dab-config.MsSql.json" --permissions "database_policy_tester:read" --policy-database "@item.id ne 1234 or @item.id gt 1940"
update Publisher --config "dab-config.MsSql.json" --permissions "database_policy_tester:update" --policy-database "@item.id ne 1234"
update Publisher --config "dab-config.MsSql.json" --permissions "database_policy_tester:create" --policy-database "@item.name ne 'New publisher'"
update Stock --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete" --rest commodities --graphql true --relationship stocks_price --target.entity stocks_price --cardinality one
update Stock --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete"
update Stock --config "dab-config.MsSql.json" --rest commodities --graphql true --relationship stocks_price --target.entity stocks_price --cardinality one
update Book --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete"
update Book --config "dab-config.MsSql.json" --relationship publishers --target.entity Publisher --cardinality one
update Book --config "dab-config.MsSql.json" --relationship websiteplacement --target.entity BookWebsitePlacement --cardinality one
Expand Down Expand Up @@ -97,7 +100,6 @@ update BookWebsitePlacement --config "dab-config.MsSql.json" --permissions "auth
update Author --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete" --rest true --graphql true
update WebsiteUser --config "dab-config.MsSql.json" --permissions "authenticated:create,read,delete,update" --rest false --graphql "websiteUser:websiteUsers"
update Revenue --config "dab-config.MsSql.json" --permissions "database_policy_tester:create" --policy-database "@item.revenue gt 1000"
update stocks_price --config "dab-config.MsSql.json" --permissions "authenticated:create,read,delete,update" --rest false
update Comic --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete" --rest true --graphql true --relationship myseries --target.entity series --cardinality one
update series --config "dab-config.MsSql.json" --relationship comics --target.entity Comic --cardinality many
update Broker --config "dab-config.MsSql.json" --permissions "authenticated:create,update,read,delete" --graphql false
Expand Down Expand Up @@ -134,3 +136,38 @@ update GetAuthorsHistoryByFirstName --config "dab-config.MsSql.json" --permissio
update InsertAndDisplayAllBooksUnderGivenPublisher --config "dab-config.MsSql.json" --permissions "authenticated:execute"
update Bookmarks --config "dab-config.MsSql.json" --permissions "authenticated:*"
update MappedBookmarks --config "dab-config.MsSql.json" --permissions "authenticated:*" --map "id:bkid,bkname:name"
add PublisherNF --config "dab-config.MsSql.json" --source publishers --permissions "authenticated:create,read,update,delete" --rest true --graphql true
add BookNF --config "dab-config.MsSql.json" --source books --permissions "authenticated:create,read,update,delete" --rest true --graphql "bookNF:booksNF"
add AuthorNF --config "dab-config.MsSql.json" --source authors --permissions "authenticated:read" --rest true --graphql true
update PublisherNF --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete"
update PublisherNF --config "dab-config.MsSql.json" --relationship books --target.entity BookNF --cardinality many
update PublisherNF --config "dab-config.MsSql.json" --permissions "TestNestedFilter_EntityReadForbidden:read"
update PublisherNF --config "dab-config.MsSql.json" --permissions "TestNestedFilter_ColumnForbidden:read"
update PublisherNF --config "dab-config.MsSql.json" --permissions "TestNestedFilterChained_EntityReadForbidden:create"
update PublisherNF --config "dab-config.MsSql.json" --permissions "TestNestedFilterChained_ColumnForbidden:read" --fields.exclude "name"
update AuthorNF --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete" --rest true --graphql true
update AuthorNF --config "dab-config.MsSql.json" --relationship books --target.entity BookNF --cardinality many --linking.object book_author_link
update AuthorNF --config "dab-config.MsSql.json" --permissions "TestNestedFilter_EntityReadForbidden:create" --fields.exclude "name"
update AuthorNF --config "dab-config.MsSql.json" --permissions "TestNestedFilter_ColumnForbidden:read" --fields.exclude "name"
update AuthorNF --config "dab-config.MsSql.json" --permissions "TestNestedFilterChained_EntityReadForbidden:read"
update AuthorNF --config "dab-config.MsSql.json" --permissions "TestNestedFilterChained_ColumnForbidden:read"
update BookNF --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete"
update BookNF --config "dab-config.MsSql.json" --permissions "TestNestedFilter_EntityReadForbidden:read"
update BookNF --config "dab-config.MsSql.json" --permissions "TestNestedFilter_ColumnForbidden:read"
update BookNF --config "dab-config.MsSql.json" --permissions "TestNestedFilterChained_EntityReadForbidden:read"
update BookNF --config "dab-config.MsSql.json" --permissions "TestNestedFilterChained_ColumnForbidden:read"
update BookNF --config "dab-config.MsSql.json" --relationship publishers --target.entity PublisherNF --cardinality one
update BookNF --config "dab-config.MsSql.json" --relationship websiteplacement --target.entity BookWebsitePlacement --cardinality one
update BookNF --config "dab-config.MsSql.json" --relationship reviews --target.entity Review --cardinality many
update BookNF --config "dab-config.MsSql.json" --relationship authors --target.entity AuthorNF --cardinality many --linking.object book_author_link --linking.source.fields "book_id" --linking.target.fields "author_id"
update BookNF --config "dab-config.MsSql.json" --map "id:id,title:title"
update Comic --config "dab-config.MsSql.json" --permissions "TestNestedFilterManyOne_ColumnForbidden:read"
update Comic --config "dab-config.MsSql.json" --permissions "TestNestedFilterManyOne_EntityReadForbidden:read"
update Comic --config "dab-config.MsSql.json" --permissions "TestNestedFilterOneMany_ColumnForbidden:read" --fields.exclude "categoryName"
update Comic --config "dab-config.MsSql.json" --permissions "TestNestedFilterOneMany_EntityReadForbidden:create,update,delete"
update Stock --config "dab-config.MsSql.json" --permissions "TestNestedFilterFieldIsNull_ColumnForbidden:read"
update Stock --config "dab-config.MsSql.json" --permissions "TestNestedFilterFieldIsNull_EntityReadForbidden:read"
update series --config "dab-config.MsSql.json" --permissions "TestNestedFilterManyOne_ColumnForbidden:read" --fields.exclude "name"
update series --config "dab-config.MsSql.json" --permissions "TestNestedFilterManyOne_EntityReadForbidden:create,update,delete"
update series --config "dab-config.MsSql.json" --permissions "TestNestedFilterOneMany_ColumnForbidden:read"
update series --config "dab-config.MsSql.json" --permissions "TestNestedFilterOneMany_EntityReadForbidden:read"
42 changes: 39 additions & 3 deletions config-generators/postgresql-commands.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
init --config "dab-config.PostgreSql.json" --database-type postgresql --connection-string "Host=localhost;Database=datagatewaytest;username=REPLACEME;password=REPLACEME" --host-mode Development --cors-origin "http://localhost:5000"
add Publisher --config "dab-config.PostgreSql.json" --source publishers --permissions "anonymous:read"
add Stock --config "dab-config.PostgreSql.json" --source stocks --permissions "anonymous:create,read,update"
add Stock --config "dab-config.PostgreSql.json" --source stocks --permissions "anonymous:create,read,update,delete"
add Book --config "dab-config.PostgreSql.json" --source books --permissions "anonymous:create,read,update,delete" --graphql "book:books"
add BookWebsitePlacement --config "dab-config.PostgreSql.json" --source book_website_placements --permissions "anonymous:read"
add Author --config "dab-config.PostgreSql.json" --source authors --permissions "anonymous:read"
Expand All @@ -9,7 +9,9 @@ add Comic --config "dab-config.PostgreSql.json" --source comics --permissions "a
add Broker --config "dab-config.PostgreSql.json" --source brokers --permissions "anonymous:read"
add WebsiteUser --config "dab-config.PostgreSql.json" --source website_users --permissions "anonymous:create,read,delete,update"
add SupportedType --config "dab-config.PostgreSql.json" --source type_table --permissions "anonymous:create,read,delete,update"
add stocks_price --config "dab-config.PostgreSql.json" --source stocks_price --permissions "anonymous:read"
add stocks_price --config "dab-config.PostgreSql.json" --source stocks_price --permissions "authenticated:create,read,update,delete"
update stocks_price --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterFieldIsNull_ColumnForbidden:read" --fields.exclude "price"
update stocks_price --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterFieldIsNull_EntityReadForbidden:create"
add Tree --config "dab-config.PostgreSql.json" --source trees --permissions "anonymous:create,read,update,delete"
add Shrub --config "dab-config.PostgreSql.json" --source trees --permissions "anonymous:create,read,update,delete" --rest plants
add Fungus --config "dab-config.PostgreSql.json" --source fungi --permissions "anonymous:create,read,update,delete" --graphql "fungus:fungi"
Expand Down Expand Up @@ -87,7 +89,6 @@ update BookWebsitePlacement --config "dab-config.PostgreSql.json" --permissions
update BookWebsitePlacement --config "dab-config.PostgreSql.json" --permissions "authenticated:delete" --fields.include "*" --policy-database "@claims.userId eq @item.id"
update Author --config "dab-config.PostgreSql.json" --permissions "authenticated:create,read,update,delete" --rest true --graphql true
update WebsiteUser --config "dab-config.PostgreSql.json" --permissions "authenticated:create,read,delete,update" --rest false --graphql "websiteUser:websiteUsers"
update stocks_price --config "dab-config.PostgreSql.json" --permissions "authenticated:create,read,delete,update" --rest false
update Comic --config "dab-config.PostgreSql.json" --permissions "authenticated:create,read,update,delete" --rest true --graphql true --relationship myseries --target.entity series --cardinality one
update series --config "dab-config.PostgreSql.json" --relationship comics --target.entity Comic --cardinality many
update Broker --config "dab-config.PostgreSql.json" --permissions "authenticated:create,update,read,delete" --graphql false
Expand All @@ -111,3 +112,38 @@ update ArtOfWar --config "dab-config.PostgreSql.json" --permissions "authenticat
update Sales --config "dab-config.PostgreSql.json" --permissions "authenticated:*"
update Bookmarks --config "dab-config.PostgreSql.json" --permissions "authenticated:*"
update MappedBookmarks --config "dab-config.PostgreSql.json" --permissions "authenticated:*" --map "id:bkid,bkname:name"
add PublisherNF --config "dab-config.PostgreSql.json" --source publishers --permissions "authenticated:create,read,update,delete" --rest true --graphql true
add BookNF --config "dab-config.PostgreSql.json" --source books --permissions "authenticated:create,read,update,delete" --rest true --graphql "bookNF:booksNF"
add AuthorNF --config "dab-config.PostgreSql.json" --source authors --permissions "authenticated:read" --rest true --graphql true
update PublisherNF --config "dab-config.PostgreSql.json" --permissions "authenticated:create,read,update,delete"
update PublisherNF --config "dab-config.PostgreSql.json" --relationship books --target.entity BookNF --cardinality many
update PublisherNF --config "dab-config.PostgreSql.json" --permissions "TestNestedFilter_EntityReadForbidden:read"
update PublisherNF --config "dab-config.PostgreSql.json" --permissions "TestNestedFilter_ColumnForbidden:read"
update PublisherNF --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterChained_EntityReadForbidden:create"
update PublisherNF --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterChained_ColumnForbidden:read" --fields.exclude "name"
update AuthorNF --config "dab-config.PostgreSql.json" --permissions "authenticated:create,read,update,delete" --rest true --graphql true
update AuthorNF --config "dab-config.PostgreSql.json" --relationship books --target.entity BookNF --cardinality many --linking.object book_author_link
update AuthorNF --config "dab-config.PostgreSql.json" --permissions "TestNestedFilter_EntityReadForbidden:create" --fields.exclude "name"
update AuthorNF --config "dab-config.PostgreSql.json" --permissions "TestNestedFilter_ColumnForbidden:read" --fields.exclude "name"
update AuthorNF --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterChained_EntityReadForbidden:read"
update AuthorNF --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterChained_ColumnForbidden:read"
update BookNF --config "dab-config.PostgreSql.json" --permissions "authenticated:create,read,update,delete"
update BookNF --config "dab-config.PostgreSql.json" --permissions "TestNestedFilter_EntityReadForbidden:read"
update BookNF --config "dab-config.PostgreSql.json" --permissions "TestNestedFilter_ColumnForbidden:read"
update BookNF --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterChained_EntityReadForbidden:read"
update BookNF --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterChained_ColumnForbidden:read"
update BookNF --config "dab-config.PostgreSql.json" --relationship publishers --target.entity PublisherNF --cardinality one
update BookNF --config "dab-config.PostgreSql.json" --relationship websiteplacement --target.entity BookWebsitePlacement --cardinality one
update BookNF --config "dab-config.PostgreSql.json" --relationship reviews --target.entity Review --cardinality many
update BookNF --config "dab-config.PostgreSql.json" --relationship authors --target.entity AuthorNF --cardinality many --linking.object book_author_link --linking.source.fields "book_id" --linking.target.fields "author_id"
update BookNF --config "dab-config.PostgreSql.json" --map "id:id,title:title"
update Comic --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterManyOne_ColumnForbidden:read"
update Comic --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterManyOne_EntityReadForbidden:read"
update Comic --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterOneMany_ColumnForbidden:read" --fields.exclude "categoryName"
update Comic --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterOneMany_EntityReadForbidden:create,update,delete"
update Stock --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterFieldIsNull_ColumnForbidden:read"
update Stock --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterFieldIsNull_EntityReadForbidden:read"
update series --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterManyOne_ColumnForbidden:read" --fields.exclude "name"
update series --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterManyOne_EntityReadForbidden:create,update,delete"
update series --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterOneMany_ColumnForbidden:read"
update series --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterOneMany_EntityReadForbidden:read"
3 changes: 2 additions & 1 deletion src/Auth/IAuthorizationResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ public interface IAuthorizationResolver
/// <param name="entityName">EntityName whose operationMetadata will be searched.</param>
/// <param name="field">Field to lookup operation permissions</param>
/// <param name="operation">Specific operation to get collection of roles</param>
/// <returns>Collection of role names allowed to perform operation on Entity's field.</returns>
/// <returns>Collection of role names allowed to perform operation on Entity's field. Empty list when zero roles
/// have permission to perform the {operation} on the provided field.</returns>
public IEnumerable<string> GetRolesForField(string entityName, string field, Operation operation);

/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions src/Config/DataApiBuilderException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ namespace Azure.DataApiBuilder.Service.Exceptions
public class DataApiBuilderException : Exception
{
public const string CONNECTION_STRING_ERROR_MESSAGE = "A valid Connection String should be provided.";
public const string GRAPHQL_FILTER_ENTITY_AUTHZ_FAILURE = "Access forbidden to the target entity described in the filter.";
public const string GRAPHQL_FILTER_FIELD_AUTHZ_FAILURE = "Access forbidden to a field referenced in the filter.";

public enum SubStatusCodes
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ protected override void Configure(IDirectiveTypeDescriptor descriptor)

descriptor.Argument("target")
.Type<StringType>()
.Description("The name of the entity the relationship targets");
.Description("The name of the GraphQL type the relationship targets");

descriptor.Argument("cardinality")
.Type<StringType>()
Expand Down Expand Up @@ -51,7 +51,7 @@ public static string Target(FieldDefinitionNode field)
/// </summary>
/// <param name="infield">The input field that is expected to have a relationship directive defined on it.</param>
/// <returns>The name of the target object if the relationship is found, null otherwise.</returns>
public static string? GetTarget(InputField infield)
public static string? GetTarget(IInputField infield)
{
Directive? directive = (Directive?)infield.Directives.FirstOrDefault(d => d.Name.Value == DirectiveName);
DirectiveNode? directiveNode = directive?.ToNode();
Expand Down
Loading

0 comments on commit 893f503

Please sign in to comment.