Skip to content
This repository has been archived by the owner on Jul 8, 2023. It is now read-only.

Permission Directives when deploying scema through GraphQLHTTPConsumer #138

Open
m4riok opened this issue Oct 31, 2022 · 2 comments
Open
Labels
enhancement New feature or request

Comments

@m4riok
Copy link

m4riok commented Oct 31, 2022

Hi there. Thanks for all the work you are putting into keeping GraphQL alive for django.
I have run into the following issue. In order to be able to use subscription with Django and Channels I am currently deploying my schema like so:

gql_http_consumer = TokenAuthMiddlewareStack(GraphQLHTTPConsumer.as_asgi(schema=schema))
gql_ws_consumer = GraphQLWSConsumer.as_asgi(schema=schema)

application = ProtocolTypeRouter({
    "http": URLRouter(
        [
            re_path('^graphql', gql_http_consumer),
            re_path('^',django_asgi_app),
        ]

    ),
    "websocket": TokenAuthMiddlewareStack(
        URLRouter([
            re_path(r'graphql' , gql_ws_consumer),
            #path('chat/', ChatConsumer.as_asgi()),
        ])
    ),
})

My TokenAuthMiddlewareStack retrieves the user and injects it into the scope so it is accessible in resolvers through info.context.request.scope['user']. When attempting to use permission directives in a query like gql.django.field(directives=[IsAuthenticated()]) the following exception is thrown:

Traceback (most recent call last):
File "/home/mariok/webappz/pydev/venvs/myfees/lib/python3.10/site-packages/graphql/execution/execute.py", line 521, in execute_field
result = resolve_fn(source, info, **args)
File "/home/mariok/webappz/pydev/venvs/myfees/lib/python3.10/site-packages/strawberry_django_plus/directives.py", line 119, in resolve
return _next(root, info, *args, **kwargs)
File "/home/mariok/webappz/pydev/venvs/myfees/lib/python3.10/site-packages/strawberry_django_plus/permissions.py", line 254, in resolve
user = cast(UserType, context.request.user)
AttributeError: 'GraphQLHTTPConsumer' object has no attribute 'user'

I am guessing you are expecting a request object there that would be available if the schema was exposed through a view. Is there some other way making a request object available that I am missing here ? Are there plans to support this sort of setup? I saw that @bellini666 is using subscriptions together with this package so I am guessing there is either another way to make subscriptions available or something is missing in my current setup.

@bellini666
Copy link
Member

Hey @m4riok . When I wrote the permissions directives the websockets support was not done yet in strawberry.

This should be easily solved by checking the type of the context (or the request itself) with isinstance and, if it is a django context then we know we can retrieve the user with context.request.user, but if it is a channels context then we need to do context.request.scope["user"].

Would you like to try to make that change and open a PR for it? Otherwise I'll take a look at this on next week

@bellini666 bellini666 added the enhancement New feature or request label Nov 1, 2022
@m4riok
Copy link
Author

m4riok commented Nov 3, 2022

Thanks for the quick reply.

For now I had to fall back to exposing my graphql API through an Async view cause I needed to use strawberry_django_jwt which heavily relies on the presence of a request object.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants