Repository URL to install this package:
Version:
0.2.0a11 ▾
|
from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.models import Permission
from .utils import get_action_name, extract_permission_codename, get_permission_descriptor
class ObjectPermissionsBackend(BaseBackend):
@staticmethod
def _init_cache(user) -> dict[tuple, set]:
perm_cache_name = '_object_perm_cache'
if not hasattr(user, perm_cache_name):
setattr(user, perm_cache_name, {})
return getattr(user, perm_cache_name)
@staticmethod
def _get_cache_key(obj):
opts = obj._meta
return opts.app_label, opts.model_name, obj.pk
def get_obj_permissions(self, user, obj=None):
if not obj or not user.is_active:
return set()
perm_cache = self._init_cache(user)
cache_key = self._get_cache_key(obj)
perm_cache.setdefault(cache_key, set())
opts = obj._meta
perms = Permission.objects.select_related('content_type').filter(
content_type__app_label=opts.app_label,
content_type__model=opts.model_name
)
if not user.is_superuser: # superusers get all perms, others get a filtered subset.
if has_object_perm := getattr(obj, 'has_object_perm', None):
perms = (
perm for perm in perms
if
get_permission_descriptor(opts, codename=perm.codename) in perm_cache[cache_key]
or has_object_perm(user, get_action_name(opts, perm.codename))
)
else:
perms = ()
perm_cache[cache_key] = {get_permission_descriptor(opts, codename=perm.codename) for perm in perms}
return perm_cache[cache_key]
def get_all_permissions(self, user_obj, obj=None):
return self.get_obj_permissions(user_obj, obj)
def has_perm(self, user_obj, perm, obj=None):
if not obj or not user_obj.is_active:
return False
perm_cache = self._init_cache(user_obj)
cache_key = self._get_cache_key(obj)
perm_cache.setdefault(cache_key, set())
if perm in perm_cache[cache_key]:
return True
opts = obj._meta
codename = extract_permission_codename(perm)
has_object_perm = getattr(obj, 'has_object_perm', None)
if user_obj.is_superuser or (has_object_perm and has_object_perm(user_obj, get_action_name(opts, codename))):
perm_cache[cache_key].add(perm)
return True
return False