Limit field permissions on Graphene Django

100 views Asked by At

Lets say I got a user Type

class UserType(DjangoObjectType):
    class Meta:
        model = User
        fields = [
            "fieldA",
            "fieldB",
            "relationshipA",
            "relationshipB"
        ]

And I want fieldB and relationshipB to be visible only to the owner (user).
What is the best strategy to do this?
Initially Ive created a PublicUserType excluding private fields, but quickly I realized that it might not be scalable because not only I'll have to create private representation for UserType I'll might also create private representation for any relationship (relationshipA etc), and proper resolvers, and duplicate fragments etc.
Is there a best practice here?

1

There are 1 answers

0
ItayAmza On BEST ANSWER

My solution is:
Create decorators.py file

from functools import wraps
from graphql import GraphQLError
from api.utils import snake_to_camel_case

def private_field(func):
    @wraps(func)
    def wrapper(self, info):
        user = info.context.user

        if user.id != self.id:
            field_name = func.__name__.replace('resolve_', '')
            field_name_camel_cased = snake_to_camel_case(field_name)
            raise GraphQLError(f'You do not have permissions to access {field_name}')
        
        return func(self, info)
    return wrapper

snake_to_camel_case func:

def snake_to_camel_case(string):
    components = string.split('_')
    return components[0] + ''.join(x.title() for x in components[1:])

and finally on my schema file resolver:

@private_field
    def resolve_private_field(self, info):
        return self.private_field

Response should look something like that:

{
    "errors": [
        {
            "message": "You do not have permissions to access privateField",
...

Now obviously this solution is super specific for my needs atm but it should be easy enough to make it more generic and scalable for any scenario.