I have the following schema in my graphene-django
application:
import graphene
from django.contrib.auth import get_user_model
from graphene_django import DjangoObjectType
class UserType(DjangoObjectType):
class Meta:
model = get_user_model()
fields = ("id", "username", "email")
class Query(object):
user = graphene.Field(UserType, user_id=graphene.Int())
def resolve_user(self, info, user_id):
user = get_user_model().objects.get(pk=user_id)
if info.context.user.id != user_id:
# If the query didn't access email field -> query is ok
# If the query tried to access email field -> raise an error
else:
# Logged in as the user we're querying -> let the query access all the fields
I want to be able to query the schema in the following way:
# Logged in as user 1 => no errors, because we're allowed to see all fields
query {
user (userId: 1) {
id
username
email
}
}
# Not logged in as user 1 => no errors, because not trying to see email
query {
user (userId: 1) {
id
username
}
}
# Not logged in as user 1 => return error because accessing email
query {
user (userId: 1) {
id
username
email
}
}
How can I make it so that only a logged in user can see the email
field of their own profile and no one else can see the emails of others?
I ended up just doing it like this, where the actual value of email
is returned when querying one's own info, and None
is returned for others:
import graphene
from django.contrib.auth import get_user_model
from graphene_django import DjangoObjectType
class UserType(DjangoObjectType):
class Meta:
model = get_user_model()
fields = ("id", "username", "email")
def resolve_email(self, info):
if info.context.user.is_authenticated and self.pk == info.context.user.pk:
return self.email
else:
return None
class Query(graphene.ObjectType):
user = graphene.Field(UserType, user_id=graphene.Int())
def resolve_user(self, info, user_id):
return get_user_model().objects.get(pk=user_id)