mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-05 04:50:12 +03:00
Merge 2d762fe3f4
into 003c304115
This commit is contained in:
commit
c6fbc4e107
|
@ -4,6 +4,7 @@ Provides a set of pluggable permission policies.
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
|
from django.utils import six
|
||||||
|
|
||||||
from rest_framework import exceptions
|
from rest_framework import exceptions
|
||||||
from rest_framework.compat import is_authenticated
|
from rest_framework.compat import is_authenticated
|
||||||
|
@ -11,6 +12,49 @@ from rest_framework.compat import is_authenticated
|
||||||
SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS')
|
SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS')
|
||||||
|
|
||||||
|
|
||||||
|
class BasePermissionMetaClass(type):
|
||||||
|
"""
|
||||||
|
Metaclass for the base permission class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(cls, name, bases, dct):
|
||||||
|
super(BasePermissionMetaClass, cls).__init__(name, bases, dct)
|
||||||
|
|
||||||
|
def __or__(klass, perm_class):
|
||||||
|
"""
|
||||||
|
Returns a new permission class performing a logical OR between two
|
||||||
|
different permission classes.
|
||||||
|
"""
|
||||||
|
assert issubclass(perm_class, BasePermission), (
|
||||||
|
"%s is not a subclass of BasePermission" % perm_class
|
||||||
|
)
|
||||||
|
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
perm = klass.has_permission(self, request, view)
|
||||||
|
otherwise = perm_class().has_permission(request, view)
|
||||||
|
|
||||||
|
return perm or otherwise
|
||||||
|
|
||||||
|
def has_object_permission(self, request, view, obj):
|
||||||
|
perm = klass.has_object_permission(self, request, view, obj)
|
||||||
|
otherwise = perm_class().has_object_permission(request, view, obj)
|
||||||
|
|
||||||
|
return perm or otherwise
|
||||||
|
|
||||||
|
t = type(
|
||||||
|
str('{0}Or{1}').format(klass.__name__, perm_class.__name__),
|
||||||
|
(klass,),
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
|
||||||
|
t.has_permission = has_permission
|
||||||
|
t.has_object_permission = has_object_permission
|
||||||
|
|
||||||
|
return t
|
||||||
|
|
||||||
|
|
||||||
|
# Needed for performing logical operations between permission classes.
|
||||||
|
@six.add_metaclass(BasePermissionMetaClass)
|
||||||
class BasePermission(object):
|
class BasePermission(object):
|
||||||
"""
|
"""
|
||||||
A base class from which all permission classes should inherit.
|
A base class from which all permission classes should inherit.
|
||||||
|
|
|
@ -483,3 +483,36 @@ class CustomPermissionsTests(TestCase):
|
||||||
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)
|
||||||
|
|
||||||
|
|
||||||
|
class AllowPermission(permissions.BasePermission):
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def has_object_permission(self, request, view, obj):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class DenyPermission(permissions.BasePermission):
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def has_object_permission(self, request, view, obj):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class PermissionOperatorTests(TestCase):
|
||||||
|
def test_permission_logical_or(self):
|
||||||
|
# We evaluate all possible combinations.
|
||||||
|
|
||||||
|
# We pass None to the has_permission function, request and view aren't
|
||||||
|
# relevant to these classes.
|
||||||
|
self.assertFalse((DenyPermission | DenyPermission)().has_permission(None, None))
|
||||||
|
self.assertTrue((AllowPermission | DenyPermission)().has_permission(None, None))
|
||||||
|
self.assertTrue((DenyPermission | AllowPermission)().has_permission(None, None))
|
||||||
|
self.assertTrue((AllowPermission | AllowPermission)().has_permission(None, None))
|
||||||
|
|
||||||
|
self.assertFalse((DenyPermission | DenyPermission)().has_object_permission(None, None, None))
|
||||||
|
self.assertTrue((AllowPermission | DenyPermission)().has_object_permission(None, None, None))
|
||||||
|
self.assertTrue((DenyPermission | AllowPermission)().has_object_permission(None, None, None))
|
||||||
|
self.assertTrue((AllowPermission | AllowPermission)().has_object_permission(None, None, None))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user