question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow overriding the request role via a GraphQL directive

See original GitHub issue

As mentioned on Discord, it isn’t possible to change the role used by an existing websocket connection, since X-Hasura-Role is sent as a header when opening the connection. @0x777 suggests allowing a special @hasura(role:) directive on a GraphQL operation definition, like this:

subscription s @hasura(role: "new-role") {
  vote_count {
    article_id
    count
  }
}

This would override the role that would otherwise be used for that particular request.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:1
  • Comments:6 (5 by maintainers)

github_iconTop GitHub Comments

5reactions
0x777commented, Dec 19, 2019

A user can have multiple roles and each role could have different permissions on different tables, in such cases, you would want to make a query by specifying the appropriate role (since we don’t support multiple roles). On http, you can set x-hasura-role to the appropriate role and make the request but this feature is lacking on the ws transport as the role gets set when the connection is initialized.

3reactions
GavinRay97commented, Apr 8, 2020

The last bit you posted is great, because the function/data structure is recursive. So we can generate it like this:

const makeRoleLink = (role) =>
  new WebSocketLink({
    uri: 'ws://localhost:8080/v1/graphql',
    options: {
      reconnect: true,
      connectionParams: {
        headers: { 'x-hasura-role': role },
      },
    },
  })

const composeRoleLinks = (head, ...tail) => {
  const [newHead, ...newTail] = [...tail].flat()

  return ApolloLink.split(
    (operation) => operation.getContext().role === head,
    /* ? */ makeRoleLink(head),
    /* : */ newTail.length > 0
      ? composeRoleLinks(newHead, newTail)
      : makeRoleLink(newHead)
  )
}

// Or, more likely coming from `X-Hasura-Allowed-Roles`
const roleLinks = composeRoleLinks('first', 'second', 'third', 'etc.')

const client = new ApolloClient({
  link: roleLinks,
  cache: new InMemoryCache(),
})
Read more comments on GitHub >

github_iconTop Results From Across the Web

Creating schema directives - Apollo GraphQL Docs
In your subclass, you override the visitor method for each location your directive can appear in. You can see each location's corresponding ...
Read more >
Authorization with GraphQL and custom directives
We define a directive with the name auth which can be used on single fields. The directive expects a parameter requires of type...
Read more >
Authorization In GraphQL Using Custom Schema Directives
To do this we override the getDirectiveDeclaration method in IsAuthenticatedDirective In our directive declaration we specify the name of the ...
Read more >
Spring for GraphQL request validation using directives.
The default arguments of a directive can be overridden if needed. In the example above the @Pattern overrides one argument. The message of ......
Read more >
GraphQL Directive - Techdozo
Implementing @auth Directive · The authDataFetcher first checks if the user has the required role by getting the role from the GraphQlContext as ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Hashnode Post

No results found