Is there a way to know on which field definition shield is deciding to use global fallbackRule. When I have set it to fallbackRule: deny I am seeing it always throwing the fallbackError. I am using createCollection mutation, and I have tried setting createCollection: allow and Collection: allow too, and it doesn't make any difference vs setting rules on all of their fields individually as I have in my permissions system.
My options object (I am getting no debug info too, it's all the way fallback):
{
debug: true, //process.env.NODE_ENV !== "production",
// to see errors thrown inside resolvers
allowExternalErrors: true, // process.env.NODE_ENV !== "production",
fallbackError: new Error(
"You are not authorised to access these resources!"
),
fallbackRule: deny // FIXME: fallback error is thrown on deny
}
Error logged is:
{"message":"You are not authorised to access these resources!","locations":[{"line":14,"column":5}],"path":["updateCollection","collection"],"extensions":{"code":"INTERNAL_SERVER_ERROR","exception":{"stacktrace":["Error: You are not authorised to access these resources!"," at Object.<anonymous> (G:\\apollo\\prod\\apollo-server\\src\\auth\\permissions.ts:252:20)"," at
Module._compile (module.js:652:30)"," at Module.m._compile (G:\\apollo\\prod\\apollo-server\\node_modules\\ts-node\\src\\index.ts:439:23)"," at Module._extensions..js (module.js:663:10)"," at Object.require.extensions.(anonymous function) [as .ts] (G:\\apollo\\prod\\apollo-server\\node_modules\\ts-node\\src\\index.ts:442:12)"," at Module.load (module.js:565:32)"," at
tryModuleLoad (module.js:505:12)"," at Function.Module._load (module.js:497:3)"," at Module.require (module.js:596:17)","
at require (internal/module.js:11:18)"," at Object.<anonymous> (G:\\apollo\\prod\\apollo-server\\src\\makeExecutableSchema.ts:14:1)"," at Module._compile (module.js:652:30)"," at Module.m._compile (G:\\apollo\\prod\\apollo-server\\node_modules\\ts-node\\src\\index.ts:439:23)"," at Module._extensions..js (module.js:663:10)"," at Object.require.extensions.(anonymous function) [as .ts] (G:\\apollo\\prod\\apollo-server\\node_modules\\ts-node\\src\\index.ts:442:12)"," at Module.load (module.js:565:32)"]}}}
I should be reproducing this, but since my whole night is lost to this, I am assuming it's something silly that I am doing.
@devautor could you provide your schema, permissions and a sample query as well?
Hello @maticzav Morning :) I am trying to set up a reproducible sandbox, but am finding it heavy (due to type relations) to decide on what part of code could be put in public, and how best to do it.
So, I am posting actual snippets here to give you a sense of direction for the reported issue, and maybe it could be enough for you :)
My permissions object is:
export const permissions = shield(
{
Query: {
customer: isUserCustomer
},
Mutation: {
_blank: allow,
createCustomerCartItem: isUserCustomer
},
CustomerCartItem: isUserCustomer,
Customer: {
id: isUserCustomer,
emailId: isUserCustomer,
mobileNumber: isUserCustomer,
name: allow,
cartItems: isUserCustomer,
createdAt: isUserCustomer,
updatedAt: isUserCustomer
},
Product: {
vendor: or(isUserSeller, isUserStoreManager)
},
},
{
debug: true, //process.env.NODE_ENV !== "production",
// to see errors thrown inside resolvers
allowExternalErrors: true, // process.env.NODE_ENV !== "production",
fallbackError: new Error(
"You are not authorised to access these resources!"
),
fallbackRule: allow // FIXME: fallback error is thrown on deny
}
);
export default permissions;
Error is thrown on mutation createCustomerCartItem.
Hello @maticzav Hello from yet another genius here is the reproduction repo, successfully reproducing this issue: https://github.com/devautor/shield-fallback-deny
Update: fallbackError is thrown, still, but even with fallbackRule: allow (bith global). Steps to reproduced are documented in the repo itself.
Edit: Kindly note that my codebase throws fallbackError only with deny, while this reproduction will throw it with both allow or deny. (Verified against different mutations)
Thank you :)
Hey @devautor 馃憢,
Thanks for the reproduction. I believe you are experiencing the problem because createCustomerCartItem returns CreateCustomerCartItemMutationResponse which is, as defined by fallbackRule, denied by default.
There's an open issue about the auto-guessed types and their rules, but as mentioned there, it is not possible to have a system which would meaningfully guess the provisions of the return types because a particular type can be returned by multiple fields with different restraints.
@maticzav This current design definitely makes sense. I had let my mind totally slip setting permissions on these mutation responses types. So much of my time wasted not following simple rules. Thanks maticzav, strucking out genius title against myself :(
I will try this and let this thread know!
Hey @maticzav Does it make sense to write permissions on mutation payload types? I mean, if the user is not authorized to submit a request, it is denied these payloads by auth errors anyway.
Also, since my mutation payloads are all extending an interface, would it be possible for me (with shield) to write allow permission on this interface (i.e. those three interface fields specifically) only once, since payload has otherwise schema type to return which have their individual roles.
Did I just make a stupid feature request!?
Hey @devautor 馃憢,
Thank you for being so patient with this issue. I believe GraphQL Shield won't support interface types soon because you can easily use TS and JS features to extend standard rules to more than one object.
Regarding the mutation payloads; it depends on the context. In some cases, it certainly makes sense to define them on PayloadTypes (e.g. having Admin user receive more information about the change than a regular user), however, as you mentioned it might add unnecessary complexity to your permission system. I prefer to enclose my schema entirely in rules as it feels like I am having more control; however, something entirely different might suit your needs.
Since the thread changed its direction away from the original question, I'll close the issue. Feel free to ask further questions regarding the original problem, or open another issue to discuss the difficulties you face. 馃檪
Most helpful comment
@maticzav This current design definitely makes sense. I had let my mind totally slip setting permissions on these mutation responses types. So much of my time wasted not following simple rules. Thanks maticzav, strucking out genius title against myself :(
I will try this and let this thread know!