How to write more complex permission query?


#1

Hello!

Could you please point me how to write more complex query for READ permission?
Let’s me explain on simple example (not real).
Schema:

type User @model {
  id: ID! @isUnique
  posts: [Post!]! @relation(name: "UserPosts")
  email: String @isUnique
}

type Post @model {
  id: ID! @isUnique
  description: String!
  targetEmail: String!
  author: User! @relation(name: "UserPosts")
}

I need to write READ permission query to allow quering posts only for a user which User.email == Post.targetEmail.
I have unsuccessfully tried with different approaches:
1.Use resolver function in permission query.
2.Pass $user param to permission query.
3.Write query within filter (like SQL):

query ReadPost ($user_id: ID!, $node_id: ID!) {
  SomePostExists(filter: {
    id: $node_id,
    targetEmail: (query User(id: $node_id){email})
  })
}

Thanks in advance.


#2
query ReadPost ($user_id: ID!, $node_targetEmail: String) {
  SomeUserExists(filter: {
    id: $user_id,
    email: $node_targetEmail
  })
}

#3

Thanks @agartha for response.
I have oversimplified real case. Let’s consider we have targetEmail field not directly in Post type but one layer nested Post.Detail.targetEmail.
I want to know whether these are any other approaches to write the query except SomeTypeExists.


#4

Relation fields are not available in permissions queries, so that wouldn’t be so straightforward to do.


#5

I am ready to hear all non-straightforward solutions. :slight_smile:


#6

You could make a resolver function. In that function, you first query the user by the nodeId from event.context.auth to get the email address, then you get the Detail node for the Post from the PostId you pass in to the resolver. Compare email addresses, and if they match, return all fields from Post.

The only issue with this is that you cannot return nested Types, model Types, or relations from resolver functions yet.

The alternative would be to use an API Gateway in front of your GraphQL endpoint where you put that logic. Then you can return the actual Post node, so you can query all of its fields and relations from your client.


#7

Hey, I am right understand that resolver could be used in permission query. Could you please write some example.
What I would like to avoid that some “bad” users in SPA could query all data which are not related to them.
E.g. using Apollo Chrome extension I could simply query any data:


#8

Hey, I have the same question! Did you find the answer?

I’d like to prevent that everyone can read the user data and the users just read their own information. I’ve been having problems with permissions, it’s so hard to understand.


#9

Hi Cezar,
I have added more strict permissions (e.g. only owner of data could read them).
And for cases where are required to share data for someone else, I have created resolvers. Query which is invoked in the resolver ignores defined permissions.