Skip to content

Commit c3e8cad

Browse files
committed
Use APIView.permission_denied to handle 401 and 403 http errors
1 parent 2b49fa1 commit c3e8cad

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

rules/contrib/rest_framework.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,4 @@ def initial(self, *args, **kwargs):
7272
# Finally, check permission
7373
perm = self.get_queryset().model.get_perm(perm_type)
7474
if not self.request.user.has_perm(perm, obj):
75-
raise PermissionDenied
75+
self.permission_denied(self.request)

tests/testsuite/contrib/test_rest_framework.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
from __future__ import absolute_import
22

3-
from django.contrib.auth.models import AnonymousUser
3+
from django.contrib.auth.models import AnonymousUser, User
44
from django.core.exceptions import ImproperlyConfigured
55
from django.test import TestCase
66

7+
from rest_framework.authentication import BasicAuthentication
78
from rest_framework.decorators import action
89
from rest_framework.response import Response
910
from rest_framework.serializers import ModelSerializer
10-
from rest_framework.test import APIRequestFactory
11+
from rest_framework.test import APIRequestFactory, force_authenticate
1112
from rest_framework.viewsets import ModelViewSet
1213

1314
import rules # noqa
@@ -26,6 +27,7 @@ class Meta:
2627
class TestViewSet(AutoPermissionViewSetMixin, ModelViewSet):
2728
queryset = TestModel.objects.all()
2829
serializer_class = TestModelSerializer
30+
authentication_classes = [BasicAuthentication]
2931
permission_type_map = AutoPermissionViewSetMixin.permission_type_map.copy()
3032
permission_type_map["custom_detail"] = "add"
3133
permission_type_map["custom_nodetail"] = "add"
@@ -58,7 +60,14 @@ def test_predefined_action(self):
5860
self.assertEqual(
5961
self.vs.as_view({"get": "retrieve"})(self.req, pk=1).status_code, 200
6062
)
61-
# Destroy should be forbidden due to missing delete permission
63+
# Unauthenticated destroy should be return 401 due to missing credentials
64+
self.assertEqual(
65+
self.vs.as_view({"get": "destroy"})(self.req, pk=1).status_code, 401
66+
)
67+
# Authenticated with unauthorized destroy should be forbidden due to missing
68+
# delete permission
69+
user = User.objects.create_user(username='user', password='pass')
70+
force_authenticate(self.req, user=user)
6271
self.assertEqual(
6372
self.vs.as_view({"get": "destroy"})(self.req, pk=1).status_code, 403
6473
)

0 commit comments

Comments
 (0)