0003-django_rbac-add-auth_level-arg-to-permission-methods.patch
| src/django_rbac/backends.py | ||
|---|---|---|
|
- `'<app_label>'`: contains a boolean, it indicates that the user own at least on
|
||
|
permision on a model of this application.
|
||
|
'''
|
||
|
if not hasattr(user_obj, '_rbac_perms_cache'):
|
||
|
perms_cache = {}
|
||
|
auth_level = getattr(user_obj, '_auth_level', None)
|
||
|
cache_suffix = '_auth_level' if auth_level else ''
|
||
|
perms_cache = getattr(user_obj, '_rbac_perms_cache' + cache_suffix, {})
|
||
|
if not perms_cache:
|
||
|
Permission = utils.get_permission_model()
|
||
|
qs = Permission.objects.for_user(user_obj)
|
||
|
qs = Permission.objects.for_user(user_obj, max_auth_level=auth_level)
|
||
|
ct_ct = ContentType.objects.get_for_model(ContentType)
|
||
|
qs = qs.select_related('operation')
|
||
|
for permission in qs:
|
||
| ... | ... | |
|
permissions.update(perms)
|
||
|
# optimization for has_module_perms
|
||
|
perms_cache[app_label] = True
|
||
|
user_obj._rbac_perms_cache = perms_cache
|
||
|
return user_obj._rbac_perms_cache
|
||
|
setattr(user_obj, '_rbac_perms_cache' + cache_suffix, perms_cache)
|
||
|
return perms_cache
|
||
|
def get_all_permissions(self, user_obj, obj=None):
|
||
|
if user_obj.is_anonymous():
|
||
| src/django_rbac/exceptions.py | ||
|---|---|---|
|
class InsufficientAuthLevel(Exception):
|
||
|
pass
|
||
| src/django_rbac/managers.py | ||
|---|---|---|
|
'''Filter permission whose target matches target'''
|
||
|
return self.by_target_ct(target).filter(target_id=target.pk)
|
||
|
def for_user(self, user):
|
||
|
def for_user(self, user, max_auth_level=None):
|
||
|
'''Retrieve all permissions hold by an user through its role and
|
||
|
inherited roles.
|
||
|
'''
|
||
|
Role = utils.get_role_model()
|
||
|
roles = Role.objects.for_user(user=user)
|
||
|
roles = Role.objects.for_user(user=user, max_auth_level=max_auth_level)
|
||
|
return self.filter(roles__in=roles)
|
||
|
def cleanup(self):
|
||
| src/django_rbac/models.py | ||
|---|---|---|
|
from django.core.validators import MinValueValidator
|
||
|
from . import utils, constants, managers, backends
|
||
|
from .exceptions import InsufficientAuthLevel
|
||
|
@six.python_2_unicode_compatible
|
||
| ... | ... | |
|
def get_all_permissions(self, obj=None):
|
||
|
return _user_get_all_permissions(self, obj)
|
||
|
def _check_auth_level(perm_func):
|
||
|
"""Add authentication level check to a permission control function.
|
||
|
perm_func can be passed a new keyword argument 'auth_level'. If
|
||
|
present, expect perm_func to be ran two times, once with the user
|
||
|
object annotated with an '_auth_level' attribute, and once without. If
|
||
|
the return values do not match, ie some permissions are not granted
|
||
|
when the user authentication level is taken into account, the decorator
|
||
|
will take care of raising an InsufficientAuthLevel exception.
|
||
|
"""
|
||
|
def wrapped_perm_func(self, *args, **kwargs):
|
||
|
auth_level = kwargs.pop('auth_level', None)
|
||
|
auth_level_result = None
|
||
|
if auth_level:
|
||
|
self._auth_level = auth_level
|
||
|
auth_level_result = perm_func(self, *args, **kwargs)
|
||
|
self._auth_level = None
|
||
|
if auth_level_result is True:
|
||
|
# Performance trick: if the function returns True, assume
|
||
|
# that we can return right away.
|
||
|
return True
|
||
|
new_result = perm_func(self, *args, **kwargs)
|
||
|
if auth_level and auth_level_result != new_result:
|
||
|
# Let the application know that permission could be granted
|
||
|
# with higher authentication level.
|
||
|
raise InsufficientAuthLevel
|
||
|
return new_result
|
||
|
return wrapped_perm_func
|
||
|
@_check_auth_level
|
||
|
def has_perm(self, perm, obj=None):
|
||
|
"""
|
||
|
Returns True if the user has the specified permission. This method
|
||
| ... | ... | |
|
# Otherwise we need to check the backends.
|
||
|
return _user_has_perm(self, perm, obj)
|
||
|
def has_perms(self, perm_list, obj=None):
|
||
|
def has_perms(self, perm_list, obj=None, auth_level=None):
|
||
|
"""
|
||
|
Returns True if the user has each of the specified permissions. If
|
||
|
object is passed, it checks if the user has all required perms for this
|
||
| ... | ... | |
|
return True
|
||
|
for perm in perm_list:
|
||
|
if not self.has_perm(perm, obj):
|
||
|
if not self.has_perm(perm, obj, auth_level=auth_level):
|
||
|
return False
|
||
|
return True
|
||
|
@_check_auth_level
|
||
|
def has_module_perms(self, app_label):
|
||
|
"""
|
||
|
Returns True if the user has any permissions in the given app label.
|
||
| ... | ... | |
|
return _user_has_module_perms(self, app_label)
|
||
|
@_check_auth_level
|
||
|
def filter_by_perm(self, perm_or_perms, qs):
|
||
|
results = []
|
||
|
for backend in auth.get_backends():
|
||
| ... | ... | |
|
else:
|
||
|
return qs
|
||
|
@_check_auth_level
|
||
|
def has_perm_any(self, perm_or_perms):
|
||
|
# Active superusers have all permissions.
|
||
|
if self.is_active and self.is_superuser:
|
||
| ... | ... | |
|
return True
|
||
|
return False
|
||
|
@_check_auth_level
|
||
|
def has_ou_perm(self, perm, ou):
|
||
|
# Active superusers have all permissions.
|
||
|
if self.is_active and self.is_superuser:
|
||
| ... | ... | |
|
return True
|
||
|
return False
|
||
|
@_check_auth_level
|
||
|
def ous_with_perm(self, perm, queryset=None):
|
||
|
return backends.DjangoRBACBackend().ous_with_perm(self, perm, queryset=queryset)
|
||