Can not apply filters for related entities

In documentation in the section about GraphQL i see follow example

query ($USER: String!) { 
            queryPost(filter: { author : { id: { eq: $USER } } } ) { 
                id 
            }

but in real database with schema

type User {
  id: ID!
  name: String!
  login: String! @id
  sources: [Source] @hasInverse(field: owner)
}

type Source {
  id: ID!
  title: String!
  owner: User! @hasInverse(field: sources)
}

I can not run query

query {
  querySource(filter: { owner: {id: { eq: "some_id" }} }) {
    id
  }
}

that why i can not implement ACL with auth directive

Can you point to this exact example in the docs? This should not be in the docs as it is not supported.

Update: I found it here: https://dgraph.io/docs/graphql/authorization/directive/#implementing-types

you can do:

type User {
  id: ID
  name: String!
  login: String! @id
  sources: [Source] @hasInverse(field: "owner")
}

type Source @auth(query: { rule: """
  query ($USER: ID!) {
    querySource {
      owner(filter: { id: [$USER] }) {
        id
      }
    }
  }
"""}) {
  id: ID!
  title: String!
  owner: User! @hasInverse(field: "sources")
}

The auth rules internally use a form of the cascade directive to only return true if the innermost fields are returned. In this case, the rule only returns true for Source nodes where the owner edge returns an id using the filter applied on the edge for a specific user.

Here are a few sidepoints

  • Depending on your Dgraph version the syntax eq: "some_id" might throw and error because it should be wrapped in a list.
  • The example you referenced defines $USER: String! in the variable definition, if used with your schema, it should actually be $USER: ID! or else the query will throw a GraphQL error for the wrong type expected.

To better write query rules, Write the rule in the API Explorer in Slash (or in another GraphQL playground client if not using Slash) and put @cascade in the root of the query. This will show you where the errors are in your auth rule and might help to see what is being returned vs what you think should be returned. Here is how I would test the query rule above:

{
  query ($USER: ID!) {
    querySource @cascade {
      id # these nodes would be allowed with this rule
      owner(filter: { id: [$USER] }) {
        id
      }
    }
  }
}

Can you point to this exact example in the docs? This should not be in the docs as it is not supported.
https://dgraph.io/docs/graphql/authorization/directive/#authorization-rules

1 Like

PR written to update the docs. Thank you for brining this to attention.


type Todo @auth(
   query: { rule: """
      query ($USER: String!) { 
           queryTodo(filter: { owner: { eq: $USER } } ) { 
               id 
           } 
       }"""
   }
){
   id: ID!
   text: String! @search(by: [term])
   owner: String! @search(by: [hash])
}

^ Notice that this is valid because owner is not an edge to a USER but instead is a predicate holding a string value.