maticzav / graphql-shield

๐Ÿ›ก A GraphQL tool to ease the creation of permission layer.

Home Page:https://graphql-shield.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support for an override, preflight, super rule

jure opened this issue ยท comments

Feature request

Is your feature request related to a problem? Please describe

I have a large number of queries and mutations that the users can do in the application. I have a fallbackRule specified, in this specific case or(isAdmin, isEditor). The fallbackRule is only applied when no other rule exists which means I have to add an or(isAdmin, isEditor) to every rule I write. I would like to instead specify a rule that applies before all other rules instead, i.e. a preflight, override or super rule, which would apply to all queries, mutations or types.

Describe the solution you'd like

I'd like to specify a rule that runs before all other rules, i.e. a override: isAdmin rule.

Describe alternatives you've considered

  1. Specifying or(isAdmin, isEditor) for each written rule
  2. Modifying the permission object before it's passed to shield() to automatically apply the or(isAdmin, isEditor) rule to each key in the permission object. Seems a bit clunky.

I'd be happy to provide a MR if the feature is deemed useful!

Hey @jure ๐Ÿ‘‹,

Thank you for opening an issue. We will get back to you as soon as we can. Also, check out our Open Collective and consider contributing financially.

https://opencollective.com/graphql-shield

PS.: We offer priority support for all financial contributors. Don't forget to add priority label once you start contributing ๐Ÿ˜„

In the mean time, I've solved it by modifying the permission object using loops going two levels down (recursion works but is not needed):

const addOverrideRule = permissions => {
  const adaptedPermissions = {}
  Object.keys(permissions).forEach(key1 => {
    const value = permissions[key1]
    if (value.constructor.name !== 'Object') {
      adaptedPermissions[key1] = or(fallbackRule, value)
    } else {
      adaptedPermissions[key1] = value
      Object.keys(value).forEach(key2 => {
        adaptedPermissions[key1][key2] = or(fallbackRule, value[key2])
      })
    }
  })
  return adaptedPermissions
}

Hey ๐Ÿ‘‹ ,

Thank you for being so patient with my response. I had a very similar idea. What I thought would be cool was if we extended and, or, and the like, so that they would accept objects and let you "subcompose" rules.

I think there might be a thread about it in one of the issues. I am not sure I have the resources and energy to do it by myself right now but would love to merge a PR or pair code over the weekend.