mirror of
https://github.com/graphql-python/graphene.git
synced 2025-07-27 08:19:45 +03:00
Add initial implementation for permission_classes on field
Co-authored-by: Carlos Martinez <carlosmart626@gmail.com>
This commit is contained in:
parent
705cad76b2
commit
74e96ab98e
|
@ -1,4 +1,5 @@
|
|||
import inspect
|
||||
from graphql.error import GraphQLError
|
||||
from collections import Mapping, OrderedDict
|
||||
from functools import partial
|
||||
|
||||
|
@ -31,6 +32,7 @@ class Field(MountedType):
|
|||
required=False,
|
||||
_creation_counter=None,
|
||||
default_value=None,
|
||||
permission_classes=[],
|
||||
**extra_args
|
||||
):
|
||||
super(Field, self).__init__(_creation_counter=_creation_counter)
|
||||
|
@ -66,10 +68,39 @@ class Field(MountedType):
|
|||
self.deprecation_reason = deprecation_reason
|
||||
self.description = description
|
||||
self.default_value = default_value
|
||||
self.permission_classes = permission_classes
|
||||
|
||||
def get_permissions(self):
|
||||
"""
|
||||
Instantiates and returns the list of permissions that this field requires.
|
||||
"""
|
||||
return [permission() for permission in self.permission_classes]
|
||||
|
||||
def check_permissions(self, info):
|
||||
for permission in self.get_permissions():
|
||||
if not permission.has_permission(info, self):
|
||||
self.permission_denied(
|
||||
info, message=getattr(permission, 'message', None)
|
||||
)
|
||||
|
||||
def permission_denied(self, info, message=None):
|
||||
raise GraphQLError(message)
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return get_type(self._type)
|
||||
|
||||
def get_resolver(self, parent_resolver):
|
||||
return self.resolver or parent_resolver
|
||||
_resolver = self.resolver or parent_resolver
|
||||
|
||||
if not _resolver:
|
||||
return None
|
||||
|
||||
def resolver(root, info, *args, **kwargs):
|
||||
|
||||
# TODO: pass root?
|
||||
self.check_permissions(info)
|
||||
|
||||
return _resolver(root, info, *args, **kwargs)
|
||||
|
||||
return resolver
|
||||
|
|
44
graphene/types/tests/test_field_permissions.py
Normal file
44
graphene/types/tests/test_field_permissions.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
from functools import partial
|
||||
|
||||
import pytest
|
||||
from graphql.error import GraphQLError
|
||||
|
||||
from ..argument import Argument
|
||||
from ..field import Field
|
||||
from ..scalars import String
|
||||
from ..structures import NonNull
|
||||
from .utils import MyLazyType
|
||||
|
||||
|
||||
class MyInstance(object):
|
||||
value = "value"
|
||||
value_func = staticmethod(lambda: "value_func")
|
||||
|
||||
def value_method(self):
|
||||
return "value_method"
|
||||
|
||||
|
||||
class AlwaysFalsePermission(object):
|
||||
def has_permission(self, info, field):
|
||||
return False
|
||||
|
||||
class AlwaysTruePermission(object):
|
||||
def has_permission(self, info, field):
|
||||
return True
|
||||
|
||||
|
||||
def test_raises_error():
|
||||
MyType = object()
|
||||
field = Field(MyType, source="value", permission_classes=[AlwaysFalsePermission])
|
||||
|
||||
with pytest.raises(GraphQLError):
|
||||
|
||||
field.get_resolver(None)(MyInstance(), None)
|
||||
|
||||
# TODO: test error message
|
||||
|
||||
def test_does_not_raise_error():
|
||||
MyType = object()
|
||||
field = Field(MyType, source="value", permission_classes=[AlwaysTruePermission])
|
||||
|
||||
field.get_resolver(None)(MyInstance(), None)
|
Loading…
Reference in New Issue
Block a user