Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
75fa1d5
Updated FieldToRolesMap definitions and comment descriptions
seantleonard Jul 8, 2022
75414f5
Populate FieldToRolesMap during permissions configuration processing …
seantleonard Jul 8, 2022
cd1bf6a
Add @authorize directive for field level READ operations in GraphQL
seantleonard Jul 8, 2022
e45b067
Basic test to check AuthZ Field for authorize Directive on objectType…
seantleonard Jul 9, 2022
4ed517a
Remove whitespace.
seantleonard Jul 10, 2022
5465955
add using
seantleonard Jul 10, 2022
a50e6d4
`AutoGeneratedFieldHasAuthorizeDirective()` test method comment and e…
seantleonard Jul 12, 2022
15c0983
Fixed typo.
seantleonard Jul 12, 2022
fc914db
Remove default null parameter in SchemaConverter.FromTableDefinition(…
seantleonard Jul 12, 2022
0df8d3f
Add anonymous check when adding fields. and check role count in order…
seantleonard Jul 12, 2022
46c165e
Remove anonymous default role since this results in authorize directi…
seantleonard Jul 12, 2022
7a7df69
Add method comment which did not originally have one. Adding since I …
seantleonard Jul 12, 2022
d0513c9
Change param of `rolesAllowedForEntity` to not be nullable, since it …
seantleonard Jul 13, 2022
51006d8
Merge branch 'main' into dev/seleonar/graphQL_Field_AuthZ
seantleonard Jul 14, 2022
5f950a2
Fixed typo'd directive in irrelevant test. Add test for anonymous rol…
seantleonard Jul 14, 2022
29704b0
fixed typo
seantleonard Jul 14, 2022
b41d5fb
Added datarow tests for checking presence of authorize directive.
seantleonard Jul 14, 2022
4717e7d
Merge branch 'main' into dev/seleonar/graphQL_Field_AuthZ
seantleonard Jul 14, 2022
ad56828
consistency with attribute and spacing
seantleonard Jul 14, 2022
b8879e4
Merge branch 'dev/seleonar/graphQL_Field_AuthZ' of https://github.com…
seantleonard Jul 14, 2022
24cd581
Extra space
seantleonard Jul 14, 2022
e2e1f1d
Merge branch 'main' into dev/seleonar/graphQL_Field_AuthZ
seantleonard Jul 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DataGateway.Auth/AuthorizationMetadataHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class EntityMetadata
/// Key(field): id -> Value(collection): permitted in {Role1, Role2, ..., RoleN}
/// Key(field): title -> Value(collection): permitted in {Role1}
/// </summary>
public Dictionary<string, Dictionary<string, IEnumerable<string>>> FieldToRolesMap { get; set; } = new();
public Dictionary<string, Dictionary<string, List<string>>> FieldToRolesMap { get; set; } = new();

/// <summary>
/// Given the key (actionName) returns a collection of roles
Expand Down
8 changes: 4 additions & 4 deletions DataGateway.Auth/IAuthorizationResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ public interface IAuthorizationResolver
/// Applicable to GraphQL field directive @authorize on ObjectType fields.
/// </summary>
/// <param name="entityName">EntityName whose actionMetadata will be searched.</param>
/// <param name="actionName">ActionName to lookup field permissions</param>
/// <param name="field">Specific field to get collection of roles</param>
/// <returns>Collection of role names allowed to perform actionType on Entity's field.</returns>
public IEnumerable<string> GetRolesForField(string entityName, string actionName, string field);
/// <param name="field">Field to lookup action permissions</param>
/// <param name="actionName">Specific action to get collection of roles</param>
/// <returns>Collection of role names allowed to perform actionName on Entity's field.</returns>
public IEnumerable<string> GetRolesForField(string entityName, string field, string actionName);

/// <summary>
/// Returns a list of roles which define permissions for the provided action.
Expand Down
1 change: 1 addition & 0 deletions DataGateway.Service.GraphQLBuilder/GraphQLUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public static class GraphQLUtils
public const string AUTHORIZE_DIRECTIVE_ARGUMENT_ROLES = "roles";
public const string OBJECT_TYPE_MUTATION = "mutation";
public const string OBJECT_TYPE_QUERY = "query";
public const string SYSTEM_ROLE_ANONYMOUS = "anonymous";

public static bool IsModelType(ObjectTypeDefinitionNode objectTypeDefinitionNode)
{
Expand Down
45 changes: 33 additions & 12 deletions DataGateway.Service.GraphQLBuilder/Sql/SchemaConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,18 @@ public static class SchemaConverter
/// <param name="entityName">Name of the entity in the runtime config to generate the GraphQL object type for.</param>
/// <param name="tableDefinition">SQL table definition information.</param>
/// <param name="configEntity">Runtime config information for the table.</param>
/// <param name="entities">Key/Value Collection mapping entity name to the entity object,
/// currently used to lookup relationship metadata.</param>
/// <param name="rolesAllowedForEntity">Roles to add to authorize directive at the object level (applies to query/read ops).</param>
/// <param name="rolesAllowedForFields">Roles to add to authorize directive at the field level (applies to mutations).</param>
/// <returns>A GraphQL object type to be provided to a Hot Chocolate GraphQL document.</returns>
public static ObjectTypeDefinitionNode FromTableDefinition(
string entityName,
TableDefinition tableDefinition,
[NotNull] Entity configEntity,
Dictionary<string, Entity> entities,
IEnumerable<string>? rolesAllowedForEntity = null)
IEnumerable<string> rolesAllowedForEntity,
IDictionary<string, IEnumerable<string>> rolesAllowedForFields)
{
Dictionary<string, FieldDefinitionNode> fields = new();
List<DirectiveNode> objectTypeDirectives = new();
Expand Down Expand Up @@ -70,16 +75,32 @@ public static ObjectTypeDefinitionNode FromTableDefinition(
directives.Add(new DirectiveNode(DefaultValueDirectiveType.DirectiveName, new ArgumentNode("value", arg)));
}

NamedTypeNode fieldType = new(GetGraphQLTypeForColumnType(column.SystemType));
FieldDefinitionNode field = new(
location: null,
new(FormatNameForField(columnName)),
description: null,
new List<InputValueDefinitionNode>(),
column.IsNullable ? fieldType : new NonNullTypeNode(fieldType),
directives);

fields.Add(columnName, field);
// If no roles are allowed for the field, we should not include it in the schema.
// Consequently, the field is only added to schema if this conditional evaluates to TRUE.
if (rolesAllowedForFields.TryGetValue(key: columnName, out IEnumerable<string>? roles))
{
// Roles will not be null here if TryGetValue evaluates to true, so here we check if there are any roles to process.
if (roles.Count() > 0)
{
// Add field to object definition but do not add @authorize directive
// if anonymous is defined for field since authentication is not required.
if (!roles.Contains(GraphQLUtils.SYSTEM_ROLE_ANONYMOUS))
Comment thread
Aniruddh25 marked this conversation as resolved.
{
directives.Add(GraphQLUtils.CreateAuthorizationDirective(roles));
}

NamedTypeNode fieldType = new(GetGraphQLTypeForColumnType(column.SystemType));
FieldDefinitionNode field = new(
location: null,
new(FormatNameForField(columnName)),
description: null,
new List<InputValueDefinitionNode>(),
column.IsNullable ? fieldType : new NonNullTypeNode(fieldType),
directives);

fields.Add(columnName, field);
}
}
}

if (configEntity.Relationships is not null)
Expand Down Expand Up @@ -125,7 +146,7 @@ public static ObjectTypeDefinitionNode FromTableDefinition(

// Any roles passed in will be added to the authorize directive for this ObjectType
// taking the form: @authorize(roles: [“role1”, ..., “roleN”])
if (rolesAllowedForEntity is not null)
if (rolesAllowedForEntity.Count() >= 1)
{
objectTypeDirectives.Add(GraphQLUtils.CreateAuthorizationDirective(rolesAllowedForEntity));
}
Expand Down
Loading