mirror of
https://github.com/graphql-python/graphene-django.git
synced 2025-04-26 12:03:47 +03:00
Add PermissionField
This commit is contained in:
parent
f76f38ef30
commit
5f17d6e025
|
@ -1,5 +1,6 @@
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
|
|
||||||
from promise import Promise
|
from promise import Promise
|
||||||
|
@ -9,7 +10,7 @@ from graphene.relay import ConnectionField, PageInfo
|
||||||
from graphql_relay.connection.arrayconnection import connection_from_list_slice
|
from graphql_relay.connection.arrayconnection import connection_from_list_slice
|
||||||
|
|
||||||
from .settings import graphene_settings
|
from .settings import graphene_settings
|
||||||
from .utils import maybe_queryset
|
from .utils import maybe_queryset, has_permissions, resolve_bound_resolver
|
||||||
|
|
||||||
|
|
||||||
class DjangoListField(Field):
|
class DjangoListField(Field):
|
||||||
|
@ -151,3 +152,37 @@ class DjangoConnectionField(ConnectionField):
|
||||||
self.max_limit,
|
self.max_limit,
|
||||||
self.enforce_first_or_last,
|
self.enforce_first_or_last,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DjangoPermissionField(Field):
|
||||||
|
"""Class to manage permission for fields"""
|
||||||
|
|
||||||
|
def __init__(self, type, permissions, *args, **kwargs):
|
||||||
|
"""Get permissions to access a field"""
|
||||||
|
super(DjangoPermissionField, self).__init__(type, *args, **kwargs)
|
||||||
|
self.permissions = permissions
|
||||||
|
|
||||||
|
def permission_resolver(self, parent_resolver, raise_exception, root, info, **args):
|
||||||
|
"""
|
||||||
|
Middleware resolver to check viewer's permissions
|
||||||
|
:param parent_resolver: Field resolver
|
||||||
|
:param raise_exception: If True a PermissionDenied is raised
|
||||||
|
:param root: Schema root
|
||||||
|
:param info: Schema info
|
||||||
|
:param args: Schema args
|
||||||
|
:return: Resolved field. None if the viewer does not have permission to access the field.
|
||||||
|
"""
|
||||||
|
# Get viewer from context
|
||||||
|
user = info.context.user
|
||||||
|
if has_permissions(user, self.permissions):
|
||||||
|
if parent_resolver:
|
||||||
|
# A resolver is provided in the class
|
||||||
|
return resolve_bound_resolver(parent_resolver, root, info, **args)
|
||||||
|
# Get default resolver
|
||||||
|
elif raise_exception:
|
||||||
|
raise PermissionDenied()
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_resolver(self, parent_resolver):
|
||||||
|
"""Intercept resolver to analyse permissions"""
|
||||||
|
return partial(self.permission_resolver, parent_resolver, True)
|
||||||
|
|
|
@ -5,6 +5,8 @@ from django.db.models.manager import Manager
|
||||||
|
|
||||||
|
|
||||||
# from graphene.utils import LazyList
|
# from graphene.utils import LazyList
|
||||||
|
from graphene.types.resolver import get_default_resolver
|
||||||
|
from graphene.utils.get_unbound_function import get_unbound_function
|
||||||
|
|
||||||
|
|
||||||
class LazyList(object):
|
class LazyList(object):
|
||||||
|
@ -81,3 +83,28 @@ def import_single_dispatch():
|
||||||
)
|
)
|
||||||
|
|
||||||
return singledispatch
|
return singledispatch
|
||||||
|
|
||||||
|
|
||||||
|
def has_permissions(viewer, permissions):
|
||||||
|
"""
|
||||||
|
Verify that at least one permission is accomplished
|
||||||
|
:param viewer: Field's viewer
|
||||||
|
:param permissions: Field permissions
|
||||||
|
:return: True if viewer has permission. False otherwise.
|
||||||
|
"""
|
||||||
|
if not permissions:
|
||||||
|
return True
|
||||||
|
return any([viewer.has_perm(perm) for perm in permissions])
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_bound_resolver(resolver, root, info, **args):
|
||||||
|
"""
|
||||||
|
Resolve provided resolver
|
||||||
|
:param resolver: Explicit field resolver
|
||||||
|
:param root: Schema root
|
||||||
|
:param info: Schema info
|
||||||
|
:param args: Schema args
|
||||||
|
:return: Resolved field
|
||||||
|
"""
|
||||||
|
resolver = get_unbound_function(resolver)
|
||||||
|
return resolver(root, info, **args)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user