How to use rules on input types and arguments for authorization?
See original GitHub issueAccording to https://github.com/maticzav/graphql-shield#rules-on-input-types-or-arguments, itās possible to use rules to validate argument value.
-
How to apply rules to input types (and specific fields of input types)? In the https://github.com/maticzav/graphql-shield#rules-on-input-types-or-arguments example the rule is in fact applied to the argument, not the input type, and validates the argument as a nested object, instead of applying rules to the fields of the input type.
-
How to apply rules to arguments and input types (and specific fields of input types) for authorization (permission validation), not value validation?
Suppose there is the following schema:
type Mutation {
createUser(name: String, email: String, age: Int, verified: Boolean): User!
updateUser(id: ID!, name: String, email: String, age: Int, verified: Boolean): User!
deleteUser(id: ID!): User
...
}
Itās possible to restrict the whole mutation, e.g.:
const permissions = shield({
Mutation: {
updateUser: isAdmin,
}
})
But what if I want to restrict only updating of the verified
field (but allow updating the rest fileds) in the updateUser
mutation, not the whole mutation (by applying the rule to the argument)?
Is it possible to do something like the following?
const permissions = shield({
Mutation: {
updateUser(
verified: isAdmin
)
}
})
The mutation arguments may be extracted to separate input types (hello, Prisma! š). In this case the rules should be applied to input type fields. Something like:
type Mutation {
updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User!
...
}
...
input UserUpdateInput {
name: String
email: String
age: Int
verified: Boolean
}
const permissions = shield({
UserUpdateInput: {
email: or(isOwner, isAdmin)
verified: isAdmin
}
})
Is it possible?
Expected behavior
The partial response is one of the basic principles of GraphQL: a response may contain both a partial data
as well as encountered errors
in the case that a field error occurred on a field which was replaced with null
.
If a fieldās resolve function throws an error, the error will be inserted into the responseās errors
key and the field will resolve to null
.
If the null value returns in a resolver for a non-null field, the null result bubbles up to the nearest nullable parent.
This is what concerns data querying (reading). But what about data mutating (writing)?
Suppose there is a mutation that has 3 arguments, and we add validations to all these arguments.
Current behavior: if at least one of the mutation arguments fails validation, the entire mutation will not be executed. Right?
But what if this argument (which failed validation) is not non-null (optional / not required)? In this case the mutation could be executed with two rest arguments.
Is it possible to just remove this argument from mutation if it fails validation?
The argument can be input type (nested object) i.e. contains other input types with its own fields that can also be input types, and so on.
If the field from depth (deep nested input type) fails (permission or value) validation and this field is not non-null (optional / not required), this field should just be removed.
If the field from depth (deep nested input type) fails (permission or value) validation and this field is non-null (required), the null should bubbles up to the nearest nullable parent.
In the case of field (optional or required) was removed, the response should contain both a mutation response as well as encountered errors
in the case that a field error occurred on a input field which was removed.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:5
- Comments:8
Hey š,
Excuse my absence, I had final examinations at school, back at programming now. My point with nesting input types etc., stemmed from the idea that you can also reuse rules across your rule tree. Therefore, I donāt see benefit in having rules applicable to input types if we could make them more declarative by applying the same rule in multiple places.
Perhaps I havenāt thought this through completely, is the problem here that you cannot nest input rules when inputs take āobjectsā as parameters?
@maticzav PTAL at the implementation by @uxname:
https://github.com/uxname/uxbackend/blob/master/src/helper/InputSheldFilter.js
Could you please integrate it (or something similar) into
graphql-shield
?