mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-18 04:02:35 +03:00
feat: Add PermissionCacheMixin and cache permission methods results
This commit is contained in:
parent
376a5cbbba
commit
c992532552
|
@ -1,6 +1,8 @@
|
||||||
"""
|
"""
|
||||||
Provides a set of pluggable permission policies.
|
Provides a set of pluggable permission policies.
|
||||||
"""
|
"""
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
|
|
||||||
from rest_framework import exceptions
|
from rest_framework import exceptions
|
||||||
|
@ -8,6 +10,16 @@ from rest_framework import exceptions
|
||||||
SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS')
|
SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS')
|
||||||
|
|
||||||
|
|
||||||
|
class PermissionCacheMixin:
|
||||||
|
@lru_cache
|
||||||
|
def has_permission_value(self, request, view):
|
||||||
|
return self.has_permission(request, view)
|
||||||
|
|
||||||
|
@lru_cache
|
||||||
|
def has_object_permission_value(self, request, view, obj):
|
||||||
|
return self.has_object_permission(request, view, obj)
|
||||||
|
|
||||||
|
|
||||||
class OperationHolderMixin:
|
class OperationHolderMixin:
|
||||||
def __and__(self, other):
|
def __and__(self, other):
|
||||||
return OperandHolder(AND, self, other)
|
return OperandHolder(AND, self, other)
|
||||||
|
@ -55,61 +67,61 @@ class OperandHolder(OperationHolderMixin):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class AND:
|
class AND(PermissionCacheMixin):
|
||||||
def __init__(self, op1, op2):
|
def __init__(self, op1, op2):
|
||||||
self.op1 = op1
|
self.op1 = op1
|
||||||
self.op2 = op2
|
self.op2 = op2
|
||||||
|
|
||||||
def has_permission(self, request, view):
|
def has_permission(self, request, view):
|
||||||
return (
|
return (
|
||||||
self.op1.has_permission(request, view) and
|
self.op1.has_permission_value(request, view) and
|
||||||
self.op2.has_permission(request, view)
|
self.op2.has_permission_value(request, view)
|
||||||
)
|
)
|
||||||
|
|
||||||
def has_object_permission(self, request, view, obj):
|
def has_object_permission(self, request, view, obj):
|
||||||
return (
|
return (
|
||||||
self.op1.has_object_permission(request, view, obj) and
|
self.op1.has_object_permission_value(request, view, obj) and
|
||||||
self.op2.has_object_permission(request, view, obj)
|
self.op2.has_object_permission_value(request, view, obj)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class OR:
|
class OR(PermissionCacheMixin):
|
||||||
def __init__(self, op1, op2):
|
def __init__(self, op1, op2):
|
||||||
self.op1 = op1
|
self.op1 = op1
|
||||||
self.op2 = op2
|
self.op2 = op2
|
||||||
|
|
||||||
def has_permission(self, request, view):
|
def has_permission(self, request, view):
|
||||||
return (
|
return (
|
||||||
self.op1.has_permission(request, view) or
|
self.op1.has_permission_value(request, view) or
|
||||||
self.op2.has_permission(request, view)
|
self.op2.has_permission_value(request, view)
|
||||||
)
|
)
|
||||||
|
|
||||||
def has_object_permission(self, request, view, obj):
|
def has_object_permission(self, request, view, obj):
|
||||||
return (
|
return (
|
||||||
self.op1.has_permission(request, view)
|
self.op1.has_permission_value(request, view)
|
||||||
and self.op1.has_object_permission(request, view, obj)
|
and self.op1.has_object_permission_value(request, view, obj)
|
||||||
) or (
|
) or (
|
||||||
self.op2.has_permission(request, view)
|
self.op2.has_permission_value(request, view)
|
||||||
and self.op2.has_object_permission(request, view, obj)
|
and self.op2.has_object_permission_value(request, view, obj)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class NOT:
|
class NOT(PermissionCacheMixin):
|
||||||
def __init__(self, op1):
|
def __init__(self, op1):
|
||||||
self.op1 = op1
|
self.op1 = op1
|
||||||
|
|
||||||
def has_permission(self, request, view):
|
def has_permission(self, request, view):
|
||||||
return not self.op1.has_permission(request, view)
|
return not self.op1.has_permission_value(request, view)
|
||||||
|
|
||||||
def has_object_permission(self, request, view, obj):
|
def has_object_permission(self, request, view, obj):
|
||||||
return not self.op1.has_object_permission(request, view, obj)
|
return not self.op1.has_object_permission_value(request, view, obj)
|
||||||
|
|
||||||
|
|
||||||
class BasePermissionMetaclass(OperationHolderMixin, type):
|
class BasePermissionMetaclass(OperationHolderMixin, type):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BasePermission(metaclass=BasePermissionMetaclass):
|
class BasePermission(PermissionCacheMixin, metaclass=BasePermissionMetaclass):
|
||||||
"""
|
"""
|
||||||
A base class from which all permission classes should inherit.
|
A base class from which all permission classes should inherit.
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue
Block a user