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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -166,13 +166,13 @@ class APIView(View): | |||
|         """ | ||||
|         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.authenticators and not request.successful_authenticator: | ||||
|             raise exceptions.NotAuthenticated() | ||||
|         raise exceptions.PermissionDenied(detail=message) | ||||
|         raise exceptions.PermissionDenied(detail=message, code=code) | ||||
| 
 | ||||
|     def throttled(self, request, wait): | ||||
|         """ | ||||
|  | @ -331,7 +331,9 @@ class APIView(View): | |||
|         for permission in self.get_permissions(): | ||||
|             if not permission.has_permission(request, self): | ||||
|                 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): | ||||
|  | @ -342,7 +344,9 @@ class APIView(View): | |||
|         for permission in self.get_permissions(): | ||||
|             if not permission.has_object_permission(request, self, obj): | ||||
|                 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): | ||||
|  |  | |||
|  | @ -438,6 +438,7 @@ class BasicPerm(permissions.BasePermission): | |||
| 
 | ||||
| class BasicPermWithDetail(permissions.BasePermission): | ||||
|     message = 'Custom: You cannot access this resource' | ||||
|     code = 'permission_denied_custom' | ||||
| 
 | ||||
|     def has_permission(self, request, view): | ||||
|         return False | ||||
|  | @ -450,6 +451,7 @@ class BasicObjectPerm(permissions.BasePermission): | |||
| 
 | ||||
| class BasicObjectPermWithDetail(permissions.BasePermission): | ||||
|     message = 'Custom: You cannot access this resource' | ||||
|     code = 'permission_denied_custom' | ||||
| 
 | ||||
|     def has_object_permission(self, request, view, obj): | ||||
|         return False | ||||
|  | @ -492,30 +494,35 @@ class CustomPermissionsTests(TestCase): | |||
|         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.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.code, self.custom_code) | ||||
| 
 | ||||
|     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.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.code, self.custom_code) | ||||
| 
 | ||||
| 
 | ||||
| class PermissionsCompositionTests(TestCase): | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user