Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Protecting Mutation or Queries #3

Closed
CBinyenya opened this issue Jan 27, 2018 · 11 comments
Closed

Protecting Mutation or Queries #3

CBinyenya opened this issue Jan 27, 2018 · 11 comments

Comments

@CBinyenya
Copy link

This is a helpful project, I just have one question, is there a way to protect mutations and queries from unauthorized uses?

@mongkok
Copy link
Member

mongkok commented Jan 27, 2018

Thanks for the feedback!

Of course, you can protect your queries and mutations verifying the info.context.user variable:

from django.contrib.auth import get_user_model

import graphene


class Query(graphene.ObjectType):
    me = graphene.Field(UserType)
    users = graphene.List(UserType)

    def resolve_me(self, info, **kwargs):
        user = info.context.user
        if user.is_anonymous:
            raise Exception('Authentication credentials were not provided')
        return user

    def resolve_users(self, info, **kwargs):
        user = info.context.user
        if not user.is_active or not user.is_staff:
            raise Exception('You do not have permission to perform this action')
        return get_user_model().objects.all()

As a shortcut, you can implement a @login_required and @staff_member_required decorators:

from functools import wraps


def context(f):
    def _context(func):
        def wrapper(*args, **kwargs):
            info = args[f.__code__.co_varnames.index('info')]
            return func(info.context, *args, **kwargs)
        return wrapper
    return _context


def login_required(f):
    @wraps(f)
    @context(f)
    def wrapper(context, *args, **kwargs):
        if context.user.is_anonymous:
            raise Exception('Authentication credentials were not provided')
        return f(*args, **kwargs)
    return wrapper


def staff_member_required(f):
    @wraps(f)
    @context(f)
    def wrapper(context, *args, **kwargs):
        user = context.user
        if user.is_active and user.is_staff:
            return f(*args, **kwargs)
        raise Exception('You do not have permission to perform this action')
    return wrapper

Using decorators...

from django.contrib.auth import get_user_model

import graphene


class Query(graphene.ObjectType):
    me = graphene.Field(UserType)
    users = graphene.List(UserType)

    @login_required
    def resolve_me(self, info, **kwargs):
        return info.context.user

    @staff_member_required
    def resolve_users(self, info, **kwargs):
        return get_user_model().objects.all()

The same for mutations.

@mongkok
Copy link
Member

mongkok commented Feb 7, 2018

Hi @CBinyenya,
do you have any question?,
can I close the ticket?

@mongkok mongkok closed this as completed Feb 9, 2018
@felipemfp
Copy link

@mongkok, maybe is a good idea include this decorators in the package

@mongkok
Copy link
Member

mongkok commented Feb 25, 2018

Hi @felipemfp,
decorators authenticate using any backend included in the AUTHENTICATION_BACKENDS settings, I think it could be added in the Graphene Django framework, there is a related issue.

@tutturen
Copy link

tutturen commented Mar 2, 2018

This issue contains helpful documentation, can I suggest that you add it to the main readme? ✍️ 😬

@mongkok
Copy link
Member

mongkok commented Mar 5, 2018

Yes, you are quite right, I should include it in the README :)

@tutturen @felipemfp, in case it can help you, I developed a package with these decorators.
https://github.com/flavors/django-graphql-extensions

@maarcingebala
Copy link

@mongkok Shouldn't these decorators be a part of this package? I guess most people who use this package will need them anyway. Also, in the README there is a reference to login_requried, but it doesn't say to which one - Django's or a custom one. My intuition was to look for these decorators inside this package.
Aside from that, thanks for a very useful piece of code, it does exactly what I was looking for.

@mongkok
Copy link
Member

mongkok commented Mar 16, 2018

Thanks @elwoodxblues,
there is a link to the [wiki] at the beginning, it might not be seen.

In my opinion, auth decorators are for general use, it can also be used for any backend included in the AUTHENTICATION_BACKENDS, that's why I think it should be included in the graphene-django framework.

On the other hand I have my doubts, to include the decorators in this library would be of great help for all of us.

At the moment I reopen the issue.

@mongkok mongkok reopened this Mar 16, 2018
mongkok pushed a commit that referenced this issue Mar 25, 2018
@mongkok
Copy link
Member

mongkok commented Mar 26, 2018

I've included the auth decorators, you can find a full list of them and examples on the documentation.

Thanks for all your comments.

@mongkok mongkok closed this as completed Mar 26, 2018
@IdemenB
Copy link

IdemenB commented Dec 5, 2020

Hi @mongkok, thanks a lot for making so many people's lives easier with your effort.

I'd like to have creation/verification/refreshing of tokens unprotected and all others that can be reached through the global schema protected. Can I ask what is the proper way of protecting the whole schema with the JWT using the lib? What I mean is, something not repeated rather than defininq @login_required for each Query and Mutation separately.

@abdulhafeez1724
Copy link

This is a helpful project, I just have one question, is there a way to protect mutations and queries from unauthorized uses?

Hi can you help me how to put token in header ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants