def _has_change_permissions_permission(self, request): """ User is able to add/change objects only if he haves can change permission on some page. """ try: get_user_permission_level(request.user) except NoPermissionsException: return False return True
def get_formsets(self, request, obj=None): if obj: for inline in self.inline_instances: if settings.CMS_PERMISSION and isinstance(inline, PagePermissionInlineAdmin): if "recover" in request.path or "history" in request.path: #do not display permissions in recover mode continue if obj and not obj.has_change_permissions_permission(request): continue elif not obj: try: get_user_permission_level(request.user) except NoPermissionsException: continue yield inline.get_formset(request, obj)
def get_formsets(self, request, obj=None): if obj: for inline in self.inline_instances: if settings.CMS_PERMISSION and isinstance( inline, PagePermissionInlineAdmin): if "recover" in request.path or "history" in request.path: #do not display permissions in recover mode continue if obj and not obj.has_change_permissions_permission( request): continue elif not obj: try: get_user_permission_level(request.user) except NoPermissionsException: continue yield inline.get_formset(request, obj)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) user = get_current_user() # current user from threadlocals site = Site.objects.get_current() sub_users = get_subordinate_users(user, site) limit_choices = True use_raw_id = False # Unfortunately, if there are > 500 users in the system, non-superusers # won't see any benefit here because if we ask Django to put all the # user PKs in limit_choices_to in the query string of the popup we're # in danger of causing 414 errors so we fall back to the normal input # widget. if get_cms_setting('RAW_ID_USERS'): if sub_users.count() < 500: # If there aren't too many users, proceed as normal and use a # raw id field with limit_choices_to limit_choices = True use_raw_id = True elif get_user_permission_level(user, site) == ROOT_USER_LEVEL: # If there are enough choices to possibly cause a 414 request # URI too large error, we only proceed with the raw id field if # the user is a superuser & thus can legitimately circumvent # the limit_choices_to condition. limit_choices = False use_raw_id = True # We don't use the fancy custom widget if the admin form wants to use a # raw id field for the user if use_raw_id: from django.contrib.admin.widgets import ForeignKeyRawIdWidget # This check will be False if the number of users in the system # is less than the threshold set by the RAW_ID_USERS setting. if isinstance(self.fields['user'].widget, ForeignKeyRawIdWidget): # We can't set a queryset on a raw id lookup, but we can use # the fact that it respects the limit_choices_to parameter. if limit_choices: self.fields['user'].widget.rel.limit_choices_to = dict( id__in=list(sub_users.values_list('pk', flat=True))) else: self.fields['user'].widget = UserSelectAdminWidget() self.fields['user'].queryset = sub_users self.fields['user'].widget.user = user # assign current user self.fields['group'].queryset = get_subordinate_groups(user, site)
def __init__(self, *args, **kwargs): super(PagePermissionInlineAdminForm, self).__init__(*args, **kwargs) user = get_current_user() # current user from threadlocals site = Site.objects.get_current() sub_users = get_subordinate_users(user, site) limit_choices = True use_raw_id = False # Unfortunately, if there are > 500 users in the system, non-superusers # won't see any benefit here because if we ask Django to put all the # user PKs in limit_choices_to in the query string of the popup we're # in danger of causing 414 errors so we fall back to the normal input # widget. if get_cms_setting('RAW_ID_USERS'): if sub_users.count() < 500: # If there aren't too many users, proceed as normal and use a # raw id field with limit_choices_to limit_choices = True use_raw_id = True elif get_user_permission_level(user, site) == ROOT_USER_LEVEL: # If there are enough choices to possibly cause a 414 request # URI too large error, we only proceed with the raw id field if # the user is a superuser & thus can legitimately circumvent # the limit_choices_to condition. limit_choices = False use_raw_id = True # We don't use the fancy custom widget if the admin form wants to use a # raw id field for the user if use_raw_id: from django.contrib.admin.widgets import ForeignKeyRawIdWidget # This check will be False if the number of users in the system # is less than the threshold set by the RAW_ID_USERS setting. if isinstance(self.fields['user'].widget, ForeignKeyRawIdWidget): # We can't set a queryset on a raw id lookup, but we can use # the fact that it respects the limit_choices_to parameter. if limit_choices: self.fields['user'].widget.rel.limit_choices_to = dict( id__in=list(sub_users.values_list('pk', flat=True)) ) else: self.fields['user'].widget = UserSelectAdminWidget() self.fields['user'].queryset = sub_users self.fields['user'].widget.user = user # assign current user self.fields['group'].queryset = get_subordinate_groups(user, site)
def subordinate_to_user(self, user): """Get all page permission objects on which user/group is lover in hierarchy then given user and given user can change permissions on them. !IMPORTANT, but exclude objects with given user, or any group containing this user - he can't be able to change his own permissions, because if he does, and removes some permissions from himself, he will not be able to add them anymore. Example: A / \ user B,E / \ C,X D,Y Gives permission nodes C,X,D,Y under user, so he can edit permissions if he haves can_change_permission. Example: A,Y / \ user B,E,X / \ C,X D,Y Gives permission nodes C,D under user, so he can edit, but not anymore to X,Y, because this users are on the same level or higher in page hierarchy. (but only if user have can_change_permission) Example: A / \ user B,E / \ \ C,X D,Y user / \ I J,A User permissions can be assigned to multiple page nodes, so merge of all of them is required. In this case user can see permissions for users C,X,D,Y,I,J but not A, because A user in higher in hierarchy. If permission object holds group, this permission object can be visible to user only if all of the group members are lover in hierarchy. If any of members is higher then given user, this entry must stay invisible. If user is superuser, or haves global can_change_permission permissions, show him everything. Result of this is used in admin for page permissions inline. """ from cms.models import GlobalPagePermission, Page if user.is_superuser or \ GlobalPagePermission.objects.with_can_change_permissions(user): # everything for those guys return self.all() # get user level from cms.utils.permissions import get_user_permission_level try: user_level = get_user_permission_level(user) except NoPermissionsException: return self.none() # get current site site = Site.objects.get_current() # get all permissions page_id_allow_list = Page.permissions.get_change_permissions_id_list( user, site) # get permission set, but without objects targeting user, or any group # in which he can be qs = self.filter( page__id__in=page_id_allow_list, page__level__gte=user_level, ) qs = qs.exclude(user=user).exclude(group__user=user) return qs
def subordinate_to_user(self, user): """Get all page permission objects on which user/group is lover in hierarchy then given user and given user can change permissions on them. !IMPORTANT, but exclude objects with given user, or any group containing this user - he can't be able to change his own permissions, because if he does, and removes some permissions from himself, he will not be able to add them anymore. Example: A / \ user B,E / \ C,X D,Y Gives permission nodes C,X,D,Y under user, so he can edit permissions if he haves can_change_permission. Example: A,Y / \ user B,E,X / \ C,X D,Y Gives permission nodes C,D under user, so he can edit, but not anymore to X,Y, because this users are on the same level or higher in page hierarchy. (but only if user have can_change_permission) Example: A / \ user B,E / \ \ C,X D,Y user / \ I J,A User permissions can be assigned to multiple page nodes, so merge of all of them is required. In this case user can see permissions for users C,X,D,Y,I,J but not A, because A user in higher in hierarchy. If permission object holds group, this permission object can be visible to user only if all of the group members are lover in hierarchy. If any of members is higher then given user, this entry must stay invisible. If user is superuser, or haves global can_change_permission permissions, show him everything. Result of this is used in admin for page permissions inline. """ from cms.models import GlobalPagePermission, Page if user.is_superuser or \ GlobalPagePermission.objects.with_can_change_permissions(user): # everything for those guys return self.all() # get user level from cms.utils.permissions import get_user_permission_level try: user_level = get_user_permission_level(user) except NoPermissionsException: return self.none() # get current site site = Site.objects.get_current() # get all permissions page_id_allow_list = Page.permissions.get_change_permissions_id_list(user, site) # get permission set, but without objects targeting user, or any group # in which he can be qs = self.filter( page__id__in=page_id_allow_list, page__level__gte=user_level, ) qs = qs.exclude(user=user).exclude(group__user=user) return qs