Skip to content

Commit

Permalink
Fix composable permissions
Browse files Browse the repository at this point in the history
In some cases we end with an operation between two `OperandHolder`.
This didn't work as it didn't knew how to deal with | or &
This fixes by adding those operations.
  • Loading branch information
xordoquy committed Nov 27, 2018
1 parent 0f5dfe8 commit 7457421
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 13 deletions.
30 changes: 17 additions & 13 deletions rest_framework/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,21 @@
SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS')


class OperandHolder:
class OperationHolderMixin:
def __and__(self, other):
return OperandHolder(AND, self, other)

def __or__(self, other):
return OperandHolder(OR, self, other)

def __rand__(self, other):
return OperandHolder(AND, other, self)

def __ror__(self, other):
return OperandHolder(OR, other, self)


class OperandHolder(OperationHolderMixin):
def __init__(self, operator_class, op1_class, op2_class):
self.operator_class = operator_class
self.op1_class = op1_class
Expand Down Expand Up @@ -59,18 +73,8 @@ def has_object_permission(self, request, view, obj):
)


class BasePermissionMetaclass(type):
def __and__(cls, other):
return OperandHolder(AND, cls, other)

def __or__(cls, other):
return OperandHolder(OR, cls, other)

def __rand__(cls, other):
return OperandHolder(AND, other, cls)

def __ror__(cls, other):
return OperandHolder(OR, other, cls)
class BasePermissionMetaclass(OperationHolderMixin, type):
pass


@six.add_metaclass(BasePermissionMetaclass)
Expand Down
11 changes: 11 additions & 0 deletions tests/test_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -589,3 +589,14 @@ def test_several_levels(self):
permissions.IsAuthenticated
)
assert composed_perm().has_permission(request, None) is True

def test_several_levels_and_precedence(self):
request = factory.get('/1', format='json')
request.user = self.user
composed_perm = (
permissions.IsAuthenticated &
permissions.IsAuthenticated |
permissions.IsAuthenticated &
permissions.IsAuthenticated
)
assert composed_perm().has_permission(request, None) is True

0 comments on commit 7457421

Please sign in to comment.