From 5f17d6e025b88b1bc623af25fda6e1c776981cf0 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Fri, 4 Jan 2019 14:24:15 -0500 Subject: [PATCH 01/17] Add PermissionField --- graphene_django/fields.py | 37 ++++++++++++++++++++++++++++++++++++- graphene_django/utils.py | 27 +++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/graphene_django/fields.py b/graphene_django/fields.py index 1ecce45..7c3cdfa 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -1,5 +1,6 @@ from functools import partial +from django.core.exceptions import PermissionDenied from django.db.models.query import QuerySet 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 .settings import graphene_settings -from .utils import maybe_queryset +from .utils import maybe_queryset, has_permissions, resolve_bound_resolver class DjangoListField(Field): @@ -151,3 +152,37 @@ class DjangoConnectionField(ConnectionField): self.max_limit, 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) diff --git a/graphene_django/utils.py b/graphene_django/utils.py index 560f604..5adf427 100644 --- a/graphene_django/utils.py +++ b/graphene_django/utils.py @@ -5,6 +5,8 @@ from django.db.models.manager import Manager # 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): @@ -81,3 +83,28 @@ def import_single_dispatch(): ) 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) From 72b849363268f4c68458f512b4ff86dc48b74092 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Fri, 4 Jan 2019 14:24:44 -0500 Subject: [PATCH 02/17] Remove import --- graphene_django/utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/graphene_django/utils.py b/graphene_django/utils.py index 5adf427..3318e1a 100644 --- a/graphene_django/utils.py +++ b/graphene_django/utils.py @@ -5,7 +5,6 @@ from django.db.models.manager import Manager # from graphene.utils import LazyList -from graphene.types.resolver import get_default_resolver from graphene.utils.get_unbound_function import get_unbound_function From d773e4232a748ee2a7c6c51e011d7d408005e391 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Fri, 4 Jan 2019 14:24:55 -0500 Subject: [PATCH 03/17] Add tests to DjangoPermissionField --- graphene_django/tests/test_fields.py | 46 ++++++++++++++++++++++++++++ graphene_django/tests/test_utils.py | 22 ++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 graphene_django/tests/test_fields.py diff --git a/graphene_django/tests/test_fields.py b/graphene_django/tests/test_fields.py new file mode 100644 index 0000000..83f3b9c --- /dev/null +++ b/graphene_django/tests/test_fields.py @@ -0,0 +1,46 @@ +from unittest import TestCase +from django.core.exceptions import PermissionDenied +from graphene_django.fields import DjangoPermissionField + + +class MyInstance(object): + value = "value" + + def resolver(self): + return "resolver method" + + +class PermissionFieldTests(TestCase): + + def test_permission_field(self): + MyType = object() + field = DjangoPermissionField(MyType, permissions=['perm1', 'perm2'], source='resolver') + resolver = field.get_resolver(field.resolver) + + class Viewer(object): + def has_perm(self, perm): + return perm == 'perm2' + + class Info(object): + class Context(object): + user = Viewer() + context = Context() + + self.assertEqual(resolver(MyInstance(), Info()), MyInstance().resolver()) + + def test_permission_field_without_permission(self): + MyType = object() + field = DjangoPermissionField(MyType, permissions=['perm1', 'perm2'], source='resolver') + resolver = field.get_resolver(field.resolver) + + class Viewer(object): + def has_perm(self, perm): + return False + + class Info(object): + class Context(object): + user = Viewer() + context = Context() + + with self.assertRaises(PermissionDenied): + resolver(MyInstance(), Info()) diff --git a/graphene_django/tests/test_utils.py b/graphene_django/tests/test_utils.py index becd031..e1068c1 100644 --- a/graphene_django/tests/test_utils.py +++ b/graphene_django/tests/test_utils.py @@ -1,4 +1,4 @@ -from ..utils import get_model_fields +from ..utils import get_model_fields, has_permissions from .models import Film, Reporter @@ -10,3 +10,23 @@ def test_get_model_fields_no_duplication(): film_fields = get_model_fields(Film) film_name_set = set([field[0] for field in film_fields]) assert len(film_fields) == len(film_name_set) + + +def test_has_permissions(): + class Viewer(object): + @staticmethod + def has_perm(permission): + return permission + + viewer_as_perm = has_permissions(Viewer(), [False, True, False]) + assert viewer_as_perm + + +def test_viewer_without_permissions(): + class Viewer(object): + @staticmethod + def has_perm(permission): + return permission + + viewer_as_perm = has_permissions(Viewer(), [False, False, False]) + assert not viewer_as_perm From a314511ea44e59cbe9170bccfc140230aeb82d5a Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Fri, 4 Jan 2019 14:25:08 -0500 Subject: [PATCH 04/17] Change PermissionField to DjangoPermissionField --- graphene_django/tests/test_fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphene_django/tests/test_fields.py b/graphene_django/tests/test_fields.py index 83f3b9c..8f61298 100644 --- a/graphene_django/tests/test_fields.py +++ b/graphene_django/tests/test_fields.py @@ -10,7 +10,7 @@ class MyInstance(object): return "resolver method" -class PermissionFieldTests(TestCase): +class DjangoPermissionFieldTests(TestCase): def test_permission_field(self): MyType = object() From 4c6e7209c37a44d043c253d6fc0d7b5af0f94472 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Fri, 4 Jan 2019 15:02:50 -0500 Subject: [PATCH 05/17] Add viewer management --- graphene_django/fields.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/graphene_django/fields.py b/graphene_django/fields.py index 7c3cdfa..1926f8a 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -162,6 +162,10 @@ class DjangoPermissionField(Field): super(DjangoPermissionField, self).__init__(type, *args, **kwargs) self.permissions = permissions + def get_viewer(self, root, info, **args): + """Get viewer to verify permissions""" + return info.context.user + def permission_resolver(self, parent_resolver, raise_exception, root, info, **args): """ Middleware resolver to check viewer's permissions @@ -173,7 +177,7 @@ class DjangoPermissionField(Field): :return: Resolved field. None if the viewer does not have permission to access the field. """ # Get viewer from context - user = info.context.user + user = self.get_viewer(root, info, **args) if has_permissions(user, self.permissions): if parent_resolver: # A resolver is provided in the class From beba1306577f35176522f09c8b394e4efc77228d Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Mon, 7 Jan 2019 07:44:20 -0500 Subject: [PATCH 06/17] Refactoring permission field --- graphene_django/fields.py | 29 ++--------------------------- graphene_django/utils.py | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/graphene_django/fields.py b/graphene_django/fields.py index 1926f8a..41132e2 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -10,7 +10,7 @@ from graphene.relay import ConnectionField, PageInfo from graphql_relay.connection.arrayconnection import connection_from_list_slice from .settings import graphene_settings -from .utils import maybe_queryset, has_permissions, resolve_bound_resolver +from .utils import maybe_queryset, auth_resolver class DjangoListField(Field): @@ -162,31 +162,6 @@ class DjangoPermissionField(Field): super(DjangoPermissionField, self).__init__(type, *args, **kwargs) self.permissions = permissions - def get_viewer(self, root, info, **args): - """Get viewer to verify permissions""" - return info.context.user - - 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 = self.get_viewer(root, info, **args) - 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) + return partial(auth_resolver, self.resolver or parent_resolver, self.permissions, True) diff --git a/graphene_django/utils.py b/graphene_django/utils.py index 3318e1a..55581c4 100644 --- a/graphene_django/utils.py +++ b/graphene_django/utils.py @@ -1,5 +1,6 @@ import inspect +from django.core.exceptions import PermissionDenied from django.db import models from django.db.models.manager import Manager @@ -107,3 +108,25 @@ def resolve_bound_resolver(resolver, root, info, **args): """ resolver = get_unbound_function(resolver) return resolver(root, info, **args) + + +def auth_resolver(parent_resolver, permissions, raise_exception, root, info, **args): + """ + Middleware resolver to check viewer's permissions + :param parent_resolver: Field resolver + :param permissions: Field permissions + :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, permissions): + if parent_resolver: + # A resolver is provided in the class + return resolve_bound_resolver(parent_resolver, root, info, **args) + elif raise_exception: + raise PermissionDenied() + return None From b8eef4731aae3bc16296bb05dfaecf0255391914 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Fri, 15 Feb 2019 15:19:04 -0500 Subject: [PATCH 07/17] Set default resolver --- graphene_django/fields.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/graphene_django/fields.py b/graphene_django/fields.py index 41132e2..f598bf9 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -156,6 +156,7 @@ class DjangoConnectionField(ConnectionField): class DjangoPermissionField(Field): """Class to manage permission for fields""" + AUTH_RESOLVER = auth_resolver def __init__(self, type, permissions, *args, **kwargs): """Get permissions to access a field""" @@ -164,4 +165,4 @@ class DjangoPermissionField(Field): def get_resolver(self, parent_resolver): """Intercept resolver to analyse permissions""" - return partial(auth_resolver, self.resolver or parent_resolver, self.permissions, True) + return partial(self.AUTH_RESOLVER, self.resolver or parent_resolver, self.permissions, True) From 813b31e965979ffc7b2f34968ea3c29fa2fb44f0 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Fri, 15 Feb 2019 16:19:15 -0500 Subject: [PATCH 08/17] Get unbound function to resolver --- graphene_django/fields.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/graphene_django/fields.py b/graphene_django/fields.py index f598bf9..384a6b6 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -2,6 +2,7 @@ from functools import partial from django.core.exceptions import PermissionDenied from django.db.models.query import QuerySet +from graphene.utils.get_unbound_function import get_unbound_function from promise import Promise @@ -165,4 +166,5 @@ class DjangoPermissionField(Field): def get_resolver(self, parent_resolver): """Intercept resolver to analyse permissions""" - return partial(self.AUTH_RESOLVER, self.resolver or parent_resolver, self.permissions, True) + return partial(get_unbound_function(self.AUTH_RESOLVER), self.resolver or parent_resolver, self.permissions, + True) From 7d643f3b717d8326b35821be8d856f8dabe7dd88 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Mon, 18 Feb 2019 15:15:13 -0500 Subject: [PATCH 09/17] Get bound --- graphene_django/fields.py | 3 +-- graphene_django/tests/test_fields.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/graphene_django/fields.py b/graphene_django/fields.py index 384a6b6..ddffd07 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -1,8 +1,7 @@ from functools import partial -from django.core.exceptions import PermissionDenied from django.db.models.query import QuerySet -from graphene.utils.get_unbound_function import get_unbound_function +from django.utils.six import get_unbound_function from promise import Promise diff --git a/graphene_django/tests/test_fields.py b/graphene_django/tests/test_fields.py index 8f61298..bf2bbd7 100644 --- a/graphene_django/tests/test_fields.py +++ b/graphene_django/tests/test_fields.py @@ -15,7 +15,7 @@ class DjangoPermissionFieldTests(TestCase): def test_permission_field(self): MyType = object() field = DjangoPermissionField(MyType, permissions=['perm1', 'perm2'], source='resolver') - resolver = field.get_resolver(field.resolver) + resolver = field.get_resolver(None) class Viewer(object): def has_perm(self, perm): From ad7497de1030b5a2356d980da11159ce7a2f6064 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Thu, 28 Feb 2019 14:58:20 -0500 Subject: [PATCH 10/17] Refactor PermissionField --- graphene_django/fields.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/graphene_django/fields.py b/graphene_django/fields.py index 384a6b6..0f1733d 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -1,8 +1,7 @@ from functools import partial -from django.core.exceptions import PermissionDenied from django.db.models.query import QuerySet -from graphene.utils.get_unbound_function import get_unbound_function +from django.utils.six import get_unbound_function from promise import Promise @@ -155,16 +154,16 @@ class DjangoConnectionField(ConnectionField): ) -class DjangoPermissionField(Field): +class DjangoField(Field): """Class to manage permission for fields""" - AUTH_RESOLVER = auth_resolver - def __init__(self, type, permissions, *args, **kwargs): + def __init__(self, type, permissions, permission_resolver=auth_resolver, *args, **kwargs): """Get permissions to access a field""" - super(DjangoPermissionField, self).__init__(type, *args, **kwargs) + super(DjangoField, self).__init__(type, *args, **kwargs) self.permissions = permissions + self.permissions_resolver = permission_resolver def get_resolver(self, parent_resolver): """Intercept resolver to analyse permissions""" - return partial(get_unbound_function(self.AUTH_RESOLVER), self.resolver or parent_resolver, self.permissions, - True) + return partial(get_unbound_function(self.permission_resolver), self.resolver or parent_resolver, + self.permissions, raise_exception=True) From d14af48866e2384d0a9c2db38da5042173db20bd Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Thu, 28 Feb 2019 15:05:39 -0500 Subject: [PATCH 11/17] Change naming --- graphene_django/fields.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/graphene_django/fields.py b/graphene_django/fields.py index 0f1733d..1131544 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -157,13 +157,13 @@ class DjangoConnectionField(ConnectionField): class DjangoField(Field): """Class to manage permission for fields""" - def __init__(self, type, permissions, permission_resolver=auth_resolver, *args, **kwargs): + def __init__(self, type, permissions, permissions_resolver=auth_resolver, *args, **kwargs): """Get permissions to access a field""" super(DjangoField, self).__init__(type, *args, **kwargs) self.permissions = permissions - self.permissions_resolver = permission_resolver + self.permissions_resolver = permissions_resolver def get_resolver(self, parent_resolver): """Intercept resolver to analyse permissions""" - return partial(get_unbound_function(self.permission_resolver), self.resolver or parent_resolver, + return partial(get_unbound_function(self.permissions_resolver), self.resolver or parent_resolver, self.permissions, raise_exception=True) From eca43192b0f070186ed3bad534bb425c26077f1c Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Thu, 28 Feb 2019 15:10:22 -0500 Subject: [PATCH 12/17] Change get_unbound_function importation --- graphene_django/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphene_django/fields.py b/graphene_django/fields.py index 1131544..ec3438e 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -1,12 +1,12 @@ from functools import partial from django.db.models.query import QuerySet -from django.utils.six import get_unbound_function from promise import Promise from graphene.types import Field, List from graphene.relay import ConnectionField, PageInfo +from graphene.utils.get_unbound_function import get_unbound_function from graphql_relay.connection.arrayconnection import connection_from_list_slice from .settings import graphene_settings From c518ddbf4bf8a8921fd3e69bee66eb7b8536a347 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Thu, 28 Feb 2019 15:15:46 -0500 Subject: [PATCH 13/17] Set raise_exception as arg --- graphene_django/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphene_django/fields.py b/graphene_django/fields.py index ec3438e..1bfd33a 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -166,4 +166,4 @@ class DjangoField(Field): def get_resolver(self, parent_resolver): """Intercept resolver to analyse permissions""" return partial(get_unbound_function(self.permissions_resolver), self.resolver or parent_resolver, - self.permissions, raise_exception=True) + self.permissions, True) From 063cced5853aaeacfa7b7acf0b8ded3d0d0fdb95 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Fri, 1 Mar 2019 09:28:14 -0500 Subject: [PATCH 14/17] Update tests --- graphene_django/tests/test_fields.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/graphene_django/tests/test_fields.py b/graphene_django/tests/test_fields.py index bf2bbd7..95ccb64 100644 --- a/graphene_django/tests/test_fields.py +++ b/graphene_django/tests/test_fields.py @@ -1,6 +1,6 @@ from unittest import TestCase from django.core.exceptions import PermissionDenied -from graphene_django.fields import DjangoPermissionField +from graphene_django.fields import DjangoField class MyInstance(object): @@ -14,7 +14,7 @@ class DjangoPermissionFieldTests(TestCase): def test_permission_field(self): MyType = object() - field = DjangoPermissionField(MyType, permissions=['perm1', 'perm2'], source='resolver') + field = DjangoField(MyType, permissions=['perm1', 'perm2'], source='resolver') resolver = field.get_resolver(None) class Viewer(object): @@ -30,7 +30,7 @@ class DjangoPermissionFieldTests(TestCase): def test_permission_field_without_permission(self): MyType = object() - field = DjangoPermissionField(MyType, permissions=['perm1', 'perm2'], source='resolver') + field = DjangoField(MyType, permissions=['perm1', 'perm2'], source='resolver') resolver = field.get_resolver(field.resolver) class Viewer(object): From ad2342a08b680aef6154e09ed8307fab647dd459 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Fri, 1 Mar 2019 12:40:54 -0500 Subject: [PATCH 15/17] Verify there is a viewer on context --- graphene_django/utils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/graphene_django/utils.py b/graphene_django/utils.py index 55581c4..f4800eb 100644 --- a/graphene_django/utils.py +++ b/graphene_django/utils.py @@ -122,7 +122,10 @@ def auth_resolver(parent_resolver, permissions, raise_exception, root, info, **a :return: Resolved field. None if the viewer does not have permission to access the field. """ # Get viewer from context + if not hasattr(info.context, 'user'): + raise PermissionDenied() user = info.context.user + if has_permissions(user, permissions): if parent_resolver: # A resolver is provided in the class From 76cbad1fb21530ad081c73f7a64c0b95dcc935e1 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Fri, 1 Mar 2019 12:42:29 -0500 Subject: [PATCH 16/17] Change DjangoField to PermissionField --- graphene_django/fields.py | 4 ++-- graphene_django/tests/test_fields.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/graphene_django/fields.py b/graphene_django/fields.py index 1bfd33a..25eb419 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -154,12 +154,12 @@ class DjangoConnectionField(ConnectionField): ) -class DjangoField(Field): +class PermissionField(Field): """Class to manage permission for fields""" def __init__(self, type, permissions, permissions_resolver=auth_resolver, *args, **kwargs): """Get permissions to access a field""" - super(DjangoField, self).__init__(type, *args, **kwargs) + super(PermissionField, self).__init__(type, *args, **kwargs) self.permissions = permissions self.permissions_resolver = permissions_resolver diff --git a/graphene_django/tests/test_fields.py b/graphene_django/tests/test_fields.py index 95ccb64..23cce7f 100644 --- a/graphene_django/tests/test_fields.py +++ b/graphene_django/tests/test_fields.py @@ -1,6 +1,6 @@ from unittest import TestCase from django.core.exceptions import PermissionDenied -from graphene_django.fields import DjangoField +from graphene_django.fields import PermissionField class MyInstance(object): @@ -10,11 +10,11 @@ class MyInstance(object): return "resolver method" -class DjangoPermissionFieldTests(TestCase): +class PermissionFieldTests(TestCase): def test_permission_field(self): MyType = object() - field = DjangoField(MyType, permissions=['perm1', 'perm2'], source='resolver') + field = PermissionField(MyType, permissions=['perm1', 'perm2'], source='resolver') resolver = field.get_resolver(None) class Viewer(object): @@ -30,7 +30,7 @@ class DjangoPermissionFieldTests(TestCase): def test_permission_field_without_permission(self): MyType = object() - field = DjangoField(MyType, permissions=['perm1', 'perm2'], source='resolver') + field = PermissionField(MyType, permissions=['perm1', 'perm2'], source='resolver') resolver = field.get_resolver(field.resolver) class Viewer(object): From 8912175cc5393be4619513b78be9cc8458813da3 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Fri, 1 Mar 2019 12:44:52 -0500 Subject: [PATCH 17/17] Set permissions as optional --- graphene_django/fields.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/graphene_django/fields.py b/graphene_django/fields.py index 25eb419..bbf1940 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -157,7 +157,7 @@ class DjangoConnectionField(ConnectionField): class PermissionField(Field): """Class to manage permission for fields""" - def __init__(self, type, permissions, permissions_resolver=auth_resolver, *args, **kwargs): + def __init__(self, type, permissions=(), permissions_resolver=auth_resolver, *args, **kwargs): """Get permissions to access a field""" super(PermissionField, self).__init__(type, *args, **kwargs) self.permissions = permissions @@ -165,5 +165,7 @@ class PermissionField(Field): def get_resolver(self, parent_resolver): """Intercept resolver to analyse permissions""" - return partial(get_unbound_function(self.permissions_resolver), self.resolver or parent_resolver, - self.permissions, True) + parent_resolver = super(PermissionField, self).get_resolver(parent_resolver) + if self.permissions: + return partial(get_unbound_function(self.permissions_resolver), parent_resolver, self.permissions, True) + return parent_resolver