-
Notifications
You must be signed in to change notification settings - Fork 12
Description
- Take array of enums instead of string as argument in
@hasRole.
(Please also keep in mind that roles (permission subsets) can be non-overlapping.)
Current implementation:
directive @hasRole(role: String) on FIELD | FIELD_DEFINITION
type User
name: String
banned: Boolean @hasRole(role: "admin")
canPost: Boolean @hasRole(role: "reviewer, admin")
}Proposed implementation:
directive @hasRole(roles: [Role] = [UNKNOWN]) on FIELD | FIELD_DEFINITION
enum Role {
ADMIN
REVIEWER
USER
UNKNOWN
}
type User
name: String
banned: Boolean @hasRole(roles: [ADMIN])
canPost: Boolean @hasRole(roles: [REVIEWER, ADMIN])
}It seems that an array of strings would be more flexible than an array of enums (because you don't need to update enum in the GraphQL SDL to add a new role), but it less type-safe (you don't get a list of possible values e.g. for autocomplete).
- Add support of other directive locations besides
FIELD_DEFINITIONto apply the directive to e.g. mutations and fields in the input types used in these mutations for more granular permissions.
Did I understand correctly that @hasRole directive can only be applied to FIELD_DEFINITION, while there are many places where directives (in general) can be applied (see the full list here: https://github.com/graphql/graphql-js/blob/master/src/language/directiveLocation.js)?
Example use case:
Everyone can query, create and update users (except canPost and banned fields), but only users with role ADMIN can delete users.
Only users with role REVIEWER or ADMIN can have access (query, create and update) canPost field.
Only users with role ADMIN can have access (query, create and update) banned field.
Only users with role MANAGER can update verified field.
Proposed implementation:
type User @hasRole(roles: [USER]) {
name: String
canPost: Boolean @hasRole(roles: [REVIEWER, ADMIN])
banned: Boolean @hasRole(roles: [ADMIN])
...
}
...
type Mutation {
createUser(data: UserCreateInput!): User!
updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User!
deleteUser(where: UserWhereUniqueInput!): User @hasRole(roles: [ADMIN])
...
}
...
input UserUpdateInput {
phone: String
verified: Boolean! @hasRole(roles: [MANAGER]) @default(value: false)
...
}- Add support of logical operations
Currently, @hasRole(role: "user, admin") checks if user has some (at least one any) of specified roles. What about all, none and other more complex cases? (Please also keep in mind that roles (permission subsets) can be non-overlapping.)
What about adding support of logic operations for nest rules (similar to https://github.com/maticzav/graphql-shield#and-or-not)? Something like (the syntax is subject to discussion):
@hasRole(roles: "or(ADMIN, and(OWNER, not(EDITOR)))")