Skip to content

Commit

Permalink
Admin permission checks are cached on the request instance
Browse files Browse the repository at this point in the history
  • Loading branch information
nnseva committed Nov 21, 2023
1 parent 084cad5 commit 950e86f
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 5 deletions.
2 changes: 1 addition & 1 deletion access/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.1.1b2"
__version__ = "0.1.2b1"
28 changes: 25 additions & 3 deletions access/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,23 +201,23 @@ def has_basic_change_permission(self, request, obj=None):
if manager.check_changeable(self.model, request) is False:
return False
if obj:
return bool(manager.apply_changeable(obj.__class__.objects.filter(id=obj.id), request))
return self._check_request_object_ability(obj, 'changeable', request)
return True

def has_delete_permission(self, request, obj=None):
manager = AccessManager(self.model)
if manager.check_deleteable(self.model, request) is False:
return False
if obj:
return bool(manager.apply_deleteable(obj.__class__.objects.filter(id=obj.id), request))
return self._check_request_object_ability(obj, 'deleteable', request)
return True

def has_view_permission(self, request, obj=None):
manager = AccessManager(self.model)
if manager.check_visible(self.model, request) is False:
return False
if obj:
return bool(manager.apply_visible(obj.__class__.objects.filter(id=obj.id), request))
return self._check_request_object_ability(obj, 'visible', request)
return True

def has_module_permission(self, request):
Expand Down Expand Up @@ -477,6 +477,28 @@ def clean(form):

return super(AccessControlMixin, self).get_formset(request, obj=obj, **kw)

def _get_request_ability_cache(self, request):
"""
Returns the request ability cache to avoid twice requests
for individual model instance ability
"""
if not hasattr(request, '--request-ability-cache'):
setattr(request, '--request-ability-cache', {})
return getattr(request, '--request-ability-cache')

def _check_request_object_ability(self, obj, ability, request):
"""
Checks and caches individual model instance ability
"""
model_name = '%s.%s' % (obj._meta.app_label, obj._meta.model_name)
pk = obj.pk
perm = self._get_request_ability_cache(request).get((model_name, pk, ability), None)
if perm is None:
manager = AccessManager(obj.__class__)
perm = bool(manager.apply_able(ability, obj.__class__.objects.filter(id=obj.id), request).exists())
self._get_request_ability_cache(request)[(model_name, pk, ability)] = perm
return perm


class AccessModelAdmin(AccessControlMixin, ModelAdmin):
pass
Expand Down
1 change: 0 additions & 1 deletion access/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ def check_able(self, ability, model, request):
return ret

def __getattr__(self, name):
method = None
prefix = 'apply_'
if name.startswith(prefix):
ability = name[len(prefix):]
Expand Down

0 comments on commit 950e86f

Please sign in to comment.