Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
dj-kaos / governance / backends.py
Size: Mime:
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