mirror of
https://github.com/graphql-python/graphene.git
synced 2025-07-30 01:39:56 +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
|
import inspect
|
||||||
|
from graphql.error import GraphQLError
|
||||||
from collections import Mapping, OrderedDict
|
from collections import Mapping, OrderedDict
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
|
@ -31,6 +32,7 @@ class Field(MountedType):
|
||||||
required=False,
|
required=False,
|
||||||
_creation_counter=None,
|
_creation_counter=None,
|
||||||
default_value=None,
|
default_value=None,
|
||||||
|
permission_classes=[],
|
||||||
**extra_args
|
**extra_args
|
||||||
):
|
):
|
||||||
super(Field, self).__init__(_creation_counter=_creation_counter)
|
super(Field, self).__init__(_creation_counter=_creation_counter)
|
||||||
|
@ -66,10 +68,39 @@ class Field(MountedType):
|
||||||
self.deprecation_reason = deprecation_reason
|
self.deprecation_reason = deprecation_reason
|
||||||
self.description = description
|
self.description = description
|
||||||
self.default_value = default_value
|
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
|
@property
|
||||||
def type(self):
|
def type(self):
|
||||||
return get_type(self._type)
|
return get_type(self._type)
|
||||||
|
|
||||||
def get_resolver(self, parent_resolver):
|
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