mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-10-26 05:31:07 +03:00 
			
		
		
		
	Pass custom code to PermissionDenied if permission class had one set (#7306)
This commit is contained in:
		
							parent
							
								
									4349ce1a54
								
							
						
					
					
						commit
						d7777ea10f
					
				|  | @ -231,7 +231,7 @@ 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. | 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. Similarly, to change the code identifier associated with the exception, implement a `code` attribute directly on your custom permission - otherwise the `default_code` attribute from `PermissionDenied` will be used. | ||||||
| 
 | 
 | ||||||
|     from rest_framework import permissions |     from rest_framework import permissions | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -166,13 +166,13 @@ class APIView(View): | ||||||
|         """ |         """ | ||||||
|         raise exceptions.MethodNotAllowed(request.method) |         raise exceptions.MethodNotAllowed(request.method) | ||||||
| 
 | 
 | ||||||
|     def permission_denied(self, request, message=None): |     def permission_denied(self, request, message=None, code=None): | ||||||
|         """ |         """ | ||||||
|         If request is not permitted, determine what kind of exception to raise. |         If request is not permitted, determine what kind of exception to raise. | ||||||
|         """ |         """ | ||||||
|         if request.authenticators and not request.successful_authenticator: |         if request.authenticators and not request.successful_authenticator: | ||||||
|             raise exceptions.NotAuthenticated() |             raise exceptions.NotAuthenticated() | ||||||
|         raise exceptions.PermissionDenied(detail=message) |         raise exceptions.PermissionDenied(detail=message, code=code) | ||||||
| 
 | 
 | ||||||
|     def throttled(self, request, wait): |     def throttled(self, request, wait): | ||||||
|         """ |         """ | ||||||
|  | @ -331,7 +331,9 @@ class APIView(View): | ||||||
|         for permission in self.get_permissions(): |         for permission in self.get_permissions(): | ||||||
|             if not permission.has_permission(request, self): |             if not permission.has_permission(request, self): | ||||||
|                 self.permission_denied( |                 self.permission_denied( | ||||||
|                     request, message=getattr(permission, 'message', None) |                     request, | ||||||
|  |                     message=getattr(permission, 'message', None), | ||||||
|  |                     code=getattr(permission, 'code', None) | ||||||
|                 ) |                 ) | ||||||
| 
 | 
 | ||||||
|     def check_object_permissions(self, request, obj): |     def check_object_permissions(self, request, obj): | ||||||
|  | @ -342,7 +344,9 @@ class APIView(View): | ||||||
|         for permission in self.get_permissions(): |         for permission in self.get_permissions(): | ||||||
|             if not permission.has_object_permission(request, self, obj): |             if not permission.has_object_permission(request, self, obj): | ||||||
|                 self.permission_denied( |                 self.permission_denied( | ||||||
|                     request, message=getattr(permission, 'message', None) |                     request, | ||||||
|  |                     message=getattr(permission, 'message', None), | ||||||
|  |                     code=getattr(permission, 'code', None) | ||||||
|                 ) |                 ) | ||||||
| 
 | 
 | ||||||
|     def check_throttles(self, request): |     def check_throttles(self, request): | ||||||
|  |  | ||||||
|  | @ -438,6 +438,7 @@ class BasicPerm(permissions.BasePermission): | ||||||
| 
 | 
 | ||||||
| class BasicPermWithDetail(permissions.BasePermission): | class BasicPermWithDetail(permissions.BasePermission): | ||||||
|     message = 'Custom: You cannot access this resource' |     message = 'Custom: You cannot access this resource' | ||||||
|  |     code = 'permission_denied_custom' | ||||||
| 
 | 
 | ||||||
|     def has_permission(self, request, view): |     def has_permission(self, request, view): | ||||||
|         return False |         return False | ||||||
|  | @ -450,6 +451,7 @@ class BasicObjectPerm(permissions.BasePermission): | ||||||
| 
 | 
 | ||||||
| class BasicObjectPermWithDetail(permissions.BasePermission): | class BasicObjectPermWithDetail(permissions.BasePermission): | ||||||
|     message = 'Custom: You cannot access this resource' |     message = 'Custom: You cannot access this resource' | ||||||
|  |     code = 'permission_denied_custom' | ||||||
| 
 | 
 | ||||||
|     def has_object_permission(self, request, view, obj): |     def has_object_permission(self, request, view, obj): | ||||||
|         return False |         return False | ||||||
|  | @ -492,30 +494,35 @@ class CustomPermissionsTests(TestCase): | ||||||
|         credentials = basic_auth_header('username', 'password') |         credentials = basic_auth_header('username', 'password') | ||||||
|         self.request = factory.get('/1', format='json', HTTP_AUTHORIZATION=credentials) |         self.request = factory.get('/1', format='json', HTTP_AUTHORIZATION=credentials) | ||||||
|         self.custom_message = 'Custom: You cannot access this resource' |         self.custom_message = 'Custom: You cannot access this resource' | ||||||
|  |         self.custom_code = 'permission_denied_custom' | ||||||
| 
 | 
 | ||||||
|     def test_permission_denied(self): |     def test_permission_denied(self): | ||||||
|         response = denied_view(self.request, pk=1) |         response = denied_view(self.request, pk=1) | ||||||
|         detail = response.data.get('detail') |         detail = response.data.get('detail') | ||||||
|         self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) |         self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | ||||||
|         self.assertNotEqual(detail, self.custom_message) |         self.assertNotEqual(detail, self.custom_message) | ||||||
|  |         self.assertNotEqual(detail.code, self.custom_code) | ||||||
| 
 | 
 | ||||||
|     def test_permission_denied_with_custom_detail(self): |     def test_permission_denied_with_custom_detail(self): | ||||||
|         response = denied_view_with_detail(self.request, pk=1) |         response = denied_view_with_detail(self.request, pk=1) | ||||||
|         detail = response.data.get('detail') |         detail = response.data.get('detail') | ||||||
|         self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) |         self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | ||||||
|         self.assertEqual(detail, self.custom_message) |         self.assertEqual(detail, self.custom_message) | ||||||
|  |         self.assertEqual(detail.code, self.custom_code) | ||||||
| 
 | 
 | ||||||
|     def test_permission_denied_for_object(self): |     def test_permission_denied_for_object(self): | ||||||
|         response = denied_object_view(self.request, pk=1) |         response = denied_object_view(self.request, pk=1) | ||||||
|         detail = response.data.get('detail') |         detail = response.data.get('detail') | ||||||
|         self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) |         self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | ||||||
|         self.assertNotEqual(detail, self.custom_message) |         self.assertNotEqual(detail, self.custom_message) | ||||||
|  |         self.assertNotEqual(detail.code, self.custom_code) | ||||||
| 
 | 
 | ||||||
|     def test_permission_denied_for_object_with_custom_detail(self): |     def test_permission_denied_for_object_with_custom_detail(self): | ||||||
|         response = denied_object_view_with_detail(self.request, pk=1) |         response = denied_object_view_with_detail(self.request, pk=1) | ||||||
|         detail = response.data.get('detail') |         detail = response.data.get('detail') | ||||||
|         self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) |         self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | ||||||
|         self.assertEqual(detail, self.custom_message) |         self.assertEqual(detail, self.custom_message) | ||||||
|  |         self.assertEqual(detail.code, self.custom_code) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class PermissionsCompositionTests(TestCase): | class PermissionsCompositionTests(TestCase): | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user