diff --git a/rest_framework/permissions.py b/rest_framework/permissions.py index 3a8c580646..0d1b658cd7 100644 --- a/rest_framework/permissions.py +++ b/rest_framework/permissions.py @@ -77,10 +77,10 @@ def has_permission(self, request, view): ) def has_object_permission(self, request, view, obj): - return ( - self.op1.has_object_permission(request, view, obj) or - self.op2.has_object_permission(request, view, obj) - ) + op1 = self.op1.has_permission(request, view) and self.op1.has_object_permission(request, view, obj) + if op1: + return op1 + return self.op2.has_permission(request, view) and self.op2.has_object_permission(request, view, obj) class NOT: diff --git a/tests/test_permissions.py b/tests/test_permissions.py index 232c72dd26..6049e94f1e 100644 --- a/tests/test_permissions.py +++ b/tests/test_permissions.py @@ -311,6 +311,7 @@ class ObjectPermissionsIntegrationTests(TestCase): """ Integration tests for the object level permissions API. """ + def setUp(self): from guardian.shortcuts import assign_perm @@ -605,6 +606,15 @@ def test_several_levels_and_precedence(self): ) assert composed_perm().has_permission(request, None) is True + def test_has_object_permissions_not_short_circuited(self): + request = factory.get('/1', format='json') + request.user = self.user + composed_perm = ( + permissions.IsAdminUser | + BasicObjectPerm + ) + assert composed_perm().has_object_permission(request, None, None) is False + def test_or_lazyness(self): request = factory.get('/1', format='json') request.user = AnonymousUser() @@ -638,7 +648,7 @@ def test_object_or_lazyness(self): mock_deny.assert_not_called() with mock.patch.object(permissions.AllowAny, 'has_object_permission', return_value=True) as mock_allow: - with mock.patch.object(permissions.IsAuthenticated, 'has_object_permission', return_value=False) as mock_deny: + with mock.patch.object(permissions.IsAuthenticated, 'has_permission', return_value=False) as mock_deny: composed_perm = (permissions.IsAuthenticated | permissions.AllowAny) hasperm = composed_perm().has_object_permission(request, None, None) assert hasperm is True