@auth rule with (inner) OR condition fails if an empty list is given as variable

Have you tried reproducing the issue with the latest release?

yes on dgraph dgraph v21.12.0 , and on dgraph cloud.

Steps to reproduce the issue

Schema

type Delta @auth(
  query: {rule: """query ($NAMES: [String]) {
    				queryDelta(filter: {mode: {eq: Public}, or:{name: {in: $NAMES}}}) { id }	
}""" }
){
  id: ID!
  name: String! @search(by: [hash])
  mode: DeltaMode! @search
}
  
enum DeltaMode {
  Public
  Private
}

# Dgraph.Authorization {"VerificationKey":"powned","Header":"X-My-App-Auth","Namespace":"yolo","Algo":"HS256"}

Add an object

mutation  {
  addDelta(input: {name: "hey", mode: Public})
}

set the following token and try to query the data

{ "yolo":"{\"NAMES\": [] }"}

token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ5b2xvIjoie1wiTkFNRVNcIjogW10gfSJ9.Z0ZfzcQoKaJ1nyWc4lUgYs-Ftsv-PPEDfGBlBsv5GaA

try agin with the following token:

{ "yolo":"{}"}

token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ5b2xvIjoie30ifQ.IPV1jlul6mkpf29bCj_ZJEkSZUhNEBhmu_Ggybn-bCU

Expected behaviour and actual result.

With the first case (empty list), dgraph returns no data but the following error

 "errors": [
    {
      "message": "Dgraph query failed because Dgraph execution failed because : eq expects atleast 1 argument.",
      "path": [
        "queryDelta"
      ]
    }
  ]

And the second case (empty claims), dgraph returns no data and no errors.

In both cases, as the variable Names is given as not mandatory, I believe it should return the object as it satisfies the first condition of the @auth rule.

Current workaround

Set the list with an empty string [""] in case where the claims is empty in the Business Logic Layer.

Have you tried running the GraphQL query outside of auth? Meaning remove the auth rules and just try running that query by itself.

I don’t think it is a problem with the auth rule, but a possible bug in the query itself to look in a list that is potentially nil itself.

Hi @amaster507,

I’ve just tested, and indeed, when the NAMES variable is an empty list, the same error is thrown ( eq expects atleast 1 argument, but, interestingly, when the variable is not provided at all, this time an error is thrown, not like the case with the @auth rule.

Here is the error :

  "errors": [
    {
      "message": "Dgraph query failed because Dgraph execution failed because Invalid filter statement",
      "path": [
        "queryDelta"
      ]
    }
  ]

hmm, this leads me to the realization of a bug. But fixing this bug is problematic.

Ideally the fix would be to make the input require an array, but this cannot be forced through the schema or else it would require you to always use the in filter when you might want to instead use the eq filter. This should be fixed on Dgraph side to silently ignore this filter when the object is nil.

Here is another thing to try in the meantime.

type Delta @auth(
  query: {rule: """query ($NAMES: [String]!) {
    				queryDelta(filter: {mode: {eq: Public}, or:{name: {in: $NAMES}}}) { id }	
}""" }
){
  id: ID!
  name: String! @search(by: [hash])
  mode: DeltaMode! @search
}

Notice the ! after [String] this might silent the query when the rule is not met, but this might also stop the whole auth query from running, if so then this may also work:

type Delta @auth(
  query: { or:[
    { rule: "query { queryDelta(filter: {mode: {eq: Public}}) { id }}" },
    { rule: "query ($NAMES: [String]!) { queryDelta(filter: {name: {in: $NAMES}}) { id }}" }
  ]}
){
  id: ID!
  name: String! @search(by: [hash])
  mode: DeltaMode! @search
}

Which hopefully in theory would silently error on the second rule, but still process the first rule.

Note: There is no way to logically say in an input that there has to be at least one value in a list. The [String!]! signifies that there has to be a list and the items in the list cannot be nil, but the list itself could be empty.

Yes, I had tested those possibilities before, and requiring the array doesn’t seem to change the situation.

  • Still an error when the list exists but is empty.
  • this time (with [String]!) the error is different when the list is nil (“cannot be null”, or “must be defined’”), that’s ok.
  • still fail silently with @auth and the an empty list, which is problematic in the case of a OR like my exemple. Yet I agree that making the OR outside the filter will be a workaround like you proposed. That is why I added the term (inner) in the issue title ;).
1 Like