Auth Rule checks if value exists in array

I’m trying to write something like this:

type User @auth(
    delete: { rule:  "{$ROLE: { eq: \"ADMIN\" } }"}
) { 
    username: String! @id
    todos: [Todo]
}

Although I’m returning “roles” from Auth0 and my roles variable is an array of roles. So, For example…

["Admin", "Creator", "Reviewer"]

What’s the correct way to match this? Like… to say only allow add if they have the “Creator” role in the array.

Hi @tommo, Role matching with array is not possible at this moment. You can find some helpful posts here:

In short, role matching right now is basic string match. So you have to convert your role array into single string values.

Thanks. I’ll alter the rule on auth0 to issue them out individually. HOWEVER… That is a very common practice to have an array of entitlements. It would be very useful for Dgraph to be able to match in an array. Similary to matching a term in a query filter.

So… just fo future users who want to do what I just did and use auth0 or something similar. Here’s the final solution (and works great).

First… follow the Auth0 docs for turning on RBAC and adding RBAC roles to the JWT Custom claims.
Second… follow the Dgraph docs for using Auth0 w/ Dgraph.

Third: Create rule to generate any think you want to query on in your Dgraph rules: Here’s what I ended up with.

function (user, context, callback) {
  const namespace = "https://dgraph.io/jwt/claims";
  const assignedRoles = (context.authorization || {}).roles;
  context.idToken[namespace] =
    {
      'USER': user.email,
    	'isAuthenticated': 'true',  // This is the rule I created to differentiate between public and private data
    };
 assignedRoles.forEach((role) => {
  	context.idToken[namespace][role] = 'true';  // This loops through the array of roles, adds them to the object and sets them to true.
 });
  
  return callback(null, user, context);
}

Last… in my schema, I’ve set the rules to look like this:

type Blog @auth(
    add: { rule:  "{$ContentCreator: { eq: \"true\" } }" },
    update: { rule:  "{$ContentCreator: { eq: \"true\" } }" },
    delete: { or: [
            { rule:  "{$ContentCreator: { eq: \"true\" } }" },
            { rule:  "{$Admin: { eq: \"true\" } }" },
    ]},
    query: { or: [
            { rule: "{$isAuthenticated: { eq: \"true\" } }" },
            { rule: """query {
                    queryBlog(filter: {isPublic: true}) {
                        id
                    }
                }
                """}
    ]}
)

Hopefully that’ll help future people who may need to do something similar.

-Tom

Hi! This just shot me in the foot. I wish there was a filter for this, both in rules and filters in general.

Maybe something like this?

{ haystackArray: { contains: $needle } }
2 Likes