Pull-Request: Fix checkpwd and val in eq func in custom dql

Hi!

I’m trying to create a custom dql query in graphql, but it seems checkpwd is not supported. The dql query works in Ratel and if I remove checkpwd it also works in graphql as custom dql query. This leads me to the conclusion that checkpwd is not supported in custom dql. Is that correct?

type Query {
    authenticate(username: String, email: String, password: String!): [User] @custom(dql: """
	query q($username: string, $email: string, $password: string) {
        var(func: type(User)) @filter(eq(User.username, $username) OR eq(User.email, $email)) {
            check as checkpwd(User.password, $password)
        }
            
        authenticate(func: eq(val(check), 1)) {
            uid
            User.username
            User.email
        }
    }
    """
    )
}

The error:

"errors": [
    {
      "message": "resolving authenticate failed because Dgraph query failed because Dgraph execution failed because while lexing query {\n  var(func: type(User)) @filter((eq(User.username, \"Alice\") OR eq(User.email, \"\"))) {\n    check as password)\n  }\n  authenticate(func: eq(check, \"1\")) {\n    uid\n    User.username\n    User.email\n  }\n} at line 3 column 21: Unrecognized character in lexText: U+0029 ')'",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ]
    }
1 Like

Can you test without the symbols? remove all variables and write the password and so on directly to the query params.

Unfortunately same result.


type Query {
    authenticate: [User] @custom(dql: """
	query {
        var(func: type(User)) @filter(eq(User.username, "Alice") OR eq(User.email, "")) {
            check as checkpwd(User.password, "password")
        }
            
        authenticate(func: eq(val(check), 1)) {
            uid
            User.username
            User.email
        }
    }
    """
    )
}

Error:

"errors": [
    {
      "message": "resolving authenticate failed because Dgraph query failed because Dgraph execution failed because while lexing query {\n  var(func: type(User)) @filter((eq(User.username, \"Alice\") OR eq(User.email, \"\"))) {\n    check as User.password)\n  }\n  authenticate(func: eq(check, \"1\")) {\n    uid\n    User.username\n    User.email\n  }\n} at line 3 column 26: Unrecognized character in lexText: U+0029 ')'",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ]
    }
  ],

Are you sure this isn’t a typo? I see two ((

Yes the resulting query has some issues with brackets according to the error.

But my original dql query should be fine, so I think there must be something wrong when rewriting the query.

I don’t think the error is where you are pointing at, since the brackets are closed later. When rewriting it seems additional brackets around the expression are added by the system. But there is another issue with the rewritten checkpwd result:

In the custom dql

check as checkpwd(User.password, "password")

Is rewritten to

check as User.password)

I don’t know what this is supposed to look like, but the bracket is for sure wrong.

Sorry for mistakes, I’m writing this from my phone.

I’ve done some playing around. I’m currently using the master branch to build a docker image. It does not work on master, but using the docker image from v21.03.2, this works.
So there must have been some change that breaks this feature in master.

UPDATE:
I think I found the culprit. In the commit
feat(GraphQL): Support auth with custom DQL (#7775)

Have been made some changes, that lead to the checkpwd function not working correctly in custom dql queries.
I will try to figure out the reason.

I’ve found a few issues with custom dql queries and I think it’s important to make these limitations clear within the docs as well.

  • checkpwd is currently not working
    The auth support does a lot of manual rewriting and I guess the teams forgot to add checkpwd. I was able to add it on my local branch. But then I found another issue:
  • // Only uid(0x123, 0x124), type(…) and eq(Type.Predicate, …) functions are supported at root.
    This means that in the above dql query the authenticate query part does not work, because it uses the val(…) function inside of eq(…). In my tests the rewritten authenticate query looks like this:
authenticate(func: eq(check, "1")) {
    id : uid
    username : User.username
    email : User.email
}

I will create a pull request for the checkpwd issue and might extend the functionality of the query root in due time.

I have a question though. Is it really necessary to rewrite all of the dql queries? This seems like a lot of manual work atm and in the end the query looks exactly the same as it was before rewriting, except that variables are replaced with their literal values. A simple string replace should be sufficient for that.
I thought auth is just doing additional queries, so there should be no meddling with the actual dql queries right?
I’m sorry if I see things too simple and I do not want to discredit any work! I am still veery unknowledgable about the dgraph code and its workings.

I have created a pull request for both issues. It would be nice if this could make it into the next release as it is a minor change.

https://github.com/dgraph-io/dgraph/pull/8103

while we are at it, I would like to hint at this pull-request. As firebase user this would help a lot and is also a minor change :upside_down_face:

2 Likes