Modify AND operand to have the ability to use custom messages

This commit is contained in:
Basil Dubyk 2019-03-08 10:31:24 +02:00 committed by Serhii Tereshchenko
parent 28d0261afc
commit e5162e1f48
2 changed files with 110 additions and 15 deletions

View File

@ -62,18 +62,29 @@ class AND:
def __init__(self, op1, op2):
self.op1 = op1
self.op2 = op2
self.message = None
def has_permission(self, request, view):
return (
self.op1.has_permission(request, view) and
self.op2.has_permission(request, view)
)
if not self.op1.has_permission(request, view):
self.message = getattr(self.op1, 'message', None)
return False
if not self.op2.has_permission(request, view):
self.message = getattr(self.op2, 'message', None)
return False
return True
def has_object_permission(self, request, view, obj):
return (
self.op1.has_object_permission(request, view, obj) and
self.op2.has_object_permission(request, view, obj)
)
if not self.op1.has_object_permission(request, view, obj):
self.message = getattr(self.op1, 'message', None)
return False
if not self.op2.has_object_permission(request, view, obj):
self.message = getattr(self.op2, 'message', None)
return False
return True
class OR:

View File

@ -18,6 +18,9 @@ from tests.models import BasicModel
factory = APIRequestFactory()
CUSTOM_MESSAGE_1 = 'Custom: You cannot access this resource'
CUSTOM_MESSAGE_2 = 'Custom: You do not have permission to view this resource'
class BasicSerializer(serializers.ModelSerializer):
class Meta:
@ -454,26 +457,40 @@ class BasicPerm(permissions.BasePermission):
class BasicPermWithDetail(permissions.BasePermission):
message = 'Custom: You cannot access this resource'
message = CUSTOM_MESSAGE_1
code = 'permission_denied_custom'
def has_permission(self, request, view):
return False
class AnotherBasicPermWithDetail(permissions.BasePermission):
message = CUSTOM_MESSAGE_2
def has_permission(self, request, view):
return False
class BasicObjectPerm(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
return False
class BasicObjectPermWithDetail(permissions.BasePermission):
message = 'Custom: You cannot access this resource'
message = CUSTOM_MESSAGE_1
code = 'permission_denied_custom'
def has_object_permission(self, request, view, obj):
return False
class AnotherBasicObjectPermWithDetail(permissions.BasePermission):
message = CUSTOM_MESSAGE_2
def has_object_permission(self, request, view, obj):
return False
class PermissionInstanceView(generics.RetrieveUpdateDestroyAPIView):
queryset = BasicModel.objects.all()
serializer_class = BasicSerializer
@ -487,6 +504,18 @@ class DeniedViewWithDetail(PermissionInstanceView):
permission_classes = (BasicPermWithDetail,)
class DeniedViewWithDetailAND1(PermissionInstanceView):
permission_classes = (BasicPermWithDetail & permissions.AllowAny,)
class DeniedViewWithDetailAND2(PermissionInstanceView):
permission_classes = (permissions.AllowAny & AnotherBasicPermWithDetail,)
class DeniedViewWithDetailAND3(PermissionInstanceView):
permission_classes = (BasicPermWithDetail & AnotherBasicPermWithDetail,)
class DeniedObjectView(PermissionInstanceView):
permission_classes = (BasicObjectPerm,)
@ -495,14 +524,34 @@ class DeniedObjectViewWithDetail(PermissionInstanceView):
permission_classes = (BasicObjectPermWithDetail,)
class DeniedObjectViewWithDetailAND1(PermissionInstanceView):
permission_classes = (BasicObjectPermWithDetail & permissions.AllowAny,)
class DeniedObjectViewWithDetailAND2(PermissionInstanceView):
permission_classes = (permissions.AllowAny & AnotherBasicObjectPermWithDetail,)
class DeniedObjectViewWithDetailAND3(PermissionInstanceView):
permission_classes = (AnotherBasicObjectPermWithDetail & BasicObjectPermWithDetail,)
denied_view = DeniedView.as_view()
denied_view_with_detail = DeniedViewWithDetail.as_view()
denied_view_with_detail_and_1 = DeniedViewWithDetailAND1.as_view()
denied_view_with_detail_and_2 = DeniedViewWithDetailAND2.as_view()
denied_view_with_detail_and_3 = DeniedViewWithDetailAND3.as_view()
denied_object_view = DeniedObjectView.as_view()
denied_object_view_with_detail = DeniedObjectViewWithDetail.as_view()
denied_object_view_with_detail_and_1 = DeniedObjectViewWithDetailAND1.as_view()
denied_object_view_with_detail_and_2 = DeniedObjectViewWithDetailAND2.as_view()
denied_object_view_with_detail_and_3 = DeniedObjectViewWithDetailAND3.as_view()
class CustomPermissionsTests(TestCase):
def setUp(self):
@ -510,37 +559,72 @@ class CustomPermissionsTests(TestCase):
User.objects.create_user('username', 'username@example.com', 'password')
credentials = basic_auth_header('username', 'password')
self.request = factory.get('/1', format='json', HTTP_AUTHORIZATION=credentials)
self.custom_message = 'Custom: You cannot access this resource'
self.custom_code = 'permission_denied_custom'
def test_permission_denied(self):
response = denied_view(self.request, pk=1)
detail = response.data.get('detail')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertNotEqual(detail, self.custom_message)
self.assertNotEqual(detail, CUSTOM_MESSAGE_1)
self.assertNotEqual(detail.code, self.custom_code)
def test_permission_denied_with_custom_detail(self):
response = denied_view_with_detail(self.request, pk=1)
detail = response.data.get('detail')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(detail, self.custom_message)
self.assertEqual(detail, CUSTOM_MESSAGE_1)
self.assertEqual(detail.code, self.custom_code)
def test_permission_denied_with_custom_detail_and_1(self):
response = denied_view_with_detail_and_1(self.request, pk=1)
detail = response.data.get('detail')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(detail, CUSTOM_MESSAGE_1)
def test_permission_denied_with_custom_detail_and_2(self):
response = denied_view_with_detail_and_2(self.request, pk=1)
detail = response.data.get('detail')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(detail, CUSTOM_MESSAGE_2)
def test_permission_denied_with_custom_detail_and_3(self):
response = denied_view_with_detail_and_3(self.request, pk=1)
detail = response.data.get('detail')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(detail, CUSTOM_MESSAGE_1)
def test_permission_denied_for_object(self):
response = denied_object_view(self.request, pk=1)
detail = response.data.get('detail')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertNotEqual(detail, self.custom_message)
self.assertNotEqual(detail, CUSTOM_MESSAGE_1)
self.assertNotEqual(detail.code, self.custom_code)
def test_permission_denied_for_object_with_custom_detail(self):
response = denied_object_view_with_detail(self.request, pk=1)
detail = response.data.get('detail')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(detail, self.custom_message)
self.assertEqual(detail, CUSTOM_MESSAGE_1)
self.assertEqual(detail.code, self.custom_code)
def test_permission_denied_for_object_with_custom_detail_and_1(self):
response = denied_object_view_with_detail_and_1(self.request, pk=1)
detail = response.data.get('detail')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(detail, CUSTOM_MESSAGE_1)
def test_permission_denied_for_object_with_custom_detail_and_2(self):
response = denied_object_view_with_detail_and_2(self.request, pk=1)
detail = response.data.get('detail')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(detail, CUSTOM_MESSAGE_2)
def test_permission_denied_for_object_with_custom_detail_and_3(self):
response = denied_object_view_with_detail_and_3(self.request, pk=1)
detail = response.data.get('detail')
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(detail, CUSTOM_MESSAGE_2)
class PermissionsCompositionTests(TestCase):