add message to custom permission

change detail to message and update text
This commit is contained in:
donewell 2015-02-10 17:41:03 +00:00
parent b999db1c46
commit 9ea615af14
3 changed files with 103 additions and 1 deletions

View File

@ -205,6 +205,16 @@ If you need to test if a request is a read operation or a write operation, you s
---
Custom permissions will raise a `PermissionDenied` exception if the test fails. To change the error message associated with the exception, implement a `message` attribute directly on your custom permission. Otherwise the `default_detail` attribute from `PermissionDenied` will be used.
from rest_framework import permissions
class CustomerAccessPermission(permissions.BasePermission):
message = 'Adding customers not allowed.'
def has_permission(self, request, view):
...
## Examples
The following is an example of a permission class that checks the incoming request's IP address against a blacklist, and denies the request if the IP has been blacklisted.

View File

@ -134,12 +134,14 @@ class APIView(View):
"""
raise exceptions.MethodNotAllowed(request.method)
def permission_denied(self, request):
def permission_denied(self, request, message=None):
"""
If request is not permitted, determine what kind of exception to raise.
"""
if not request.successful_authenticator:
raise exceptions.NotAuthenticated()
if message is not None:
raise exceptions.PermissionDenied(message)
raise exceptions.PermissionDenied()
def throttled(self, request, wait):
@ -280,6 +282,8 @@ class APIView(View):
"""
for permission in self.get_permissions():
if not permission.has_permission(request, self):
if hasattr(permission, 'message'):
self.permission_denied(request, permission.message)
self.permission_denied(request)
def check_object_permissions(self, request, obj):
@ -289,6 +293,8 @@ class APIView(View):
"""
for permission in self.get_permissions():
if not permission.has_object_permission(request, self, obj):
if hasattr(permission, 'message'):
self.permission_denied(request, permission.message)
self.permission_denied(request)
def check_throttles(self, request):

View File

@ -310,3 +310,89 @@ class ObjectPermissionsIntegrationTests(TestCase):
response = object_permissions_list_view(request)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertListEqual(response.data, [])
class BasicPerm(permissions.BasePermission):
def has_permission(self, request, view):
return False
class BasicPermWithDetail(permissions.BasePermission):
message = 'Custom: You cannot post to this resource'
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 post to this resource'
def has_object_permission(self, request, view, obj):
return False
class PermissionInstanceView(generics.RetrieveUpdateDestroyAPIView):
queryset = BasicModel.objects.all()
serializer_class = BasicSerializer
class DeniedView(PermissionInstanceView):
permission_classes = (BasicPerm,)
class DeniedViewWithDetail(PermissionInstanceView):
permission_classes = (BasicPermWithDetail,)
class DeniedObjectView(PermissionInstanceView):
permission_classes = (BasicObjectPerm,)
class DeniedObjectViewWithDetail(PermissionInstanceView):
permission_classes = (BasicObjectPermWithDetail,)
denied_view = DeniedView.as_view()
denied_view_with_detail = DeniedViewWithDetail.as_view()
denied_object_view = DeniedObjectView.as_view()
denied_object_view_with_detail = DeniedObjectViewWithDetail.as_view()
class CustomPermissionsTests(TestCase):
def setUp(self):
BasicModel(text='foo').save()
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 post to this resource'
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)
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)
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)
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)