Permalink
Browse files

working on fixing global page permissions for issue #1120

Introduces a new manager, to keep the Q objects in one place.
  • Loading branch information...
kezabelle committed Dec 22, 2011
1 parent b5b90a9 commit ee44d34c66261a1d9f5133f88d656196666d0b25
Showing with 48 additions and 28 deletions.
  1. +2 −5 cms/menu.py
  2. +26 −5 cms/models/managers.py
  3. +3 −6 cms/models/pagemodel.py
  4. +3 −2 cms/models/permissionmodels.py
  5. +3 −2 cms/utils/admin.py
  6. +11 −8 cms/utils/permissions.py
View
@@ -42,11 +42,8 @@ def get_visible_pages(request, pages, site=None):
site = current_site(request)
if request.user.is_authenticated():
- #return self.filter(Q(user=user) | Q(group__user=user))
- global_page_perm_q = Q(
- Q(user=request.user) | Q(group__user=request.user)
- ) & Q(can_view=True) & Q(Q(sites__in=[site.pk]) | Q(sites__isnull=True))
- global_view_perms = GlobalPagePermission.objects.filter(global_page_perm_q).exists()
+ global_view_perms = GlobalPagePermission.objects.user_has_view_permission(
+ request.user, site.pk).exists()
def has_global_perm():
if has_global_perm.cache < 0:
View
@@ -237,7 +237,8 @@ def set_or_create(self, request, page, form, language):
class BasicPagePermissionManager(models.Manager):
"""Global page permission manager accessible under objects.
- !IMPORTANT: take care, PagePermissionManager extends this manager
+ !IMPORTANT: take care, PagePermissionManager and GlobalPagePermissionManager both
+ inherit from this manager
"""
def with_user(self, user):
"""Get all objects for given user, also takes look if user is in some
@@ -251,6 +252,28 @@ def with_can_change_permissions(self, user):
permissions use page.permissions manager.
"""
return self.with_user(user).filter(can_change_permissions=True)
+
+class GlobalPagePermissionManager(BasicPagePermissionManager):
+
+ def user_has_permission(self, user, site_id, perm):
+ ''' Provide a single point of entry for deciding whether any given global
+ permission exists.
+ '''
+ # if the user has add rights to this site explicitly
+ this_site = Q(**{perm: True, 'sites__in':[site_id]})
+ # if the user can add to all sites
+ all_sites = Q(**{perm: True, 'sites__isnull': True})
+ return self.with_user(user).filter(this_site | all_sites)
+
+ def user_has_add_permission(self, user, site_id):
+ return self.user_has_permission(user, site_id, 'can_add')
+
+ def user_has_change_permission(self, user, site_id):
+ return self.user_has_permission(user, site_id, 'can_change')
+
+ def user_has_view_permission(self, user, site_id):
+ return self.user_has_permission(user, site_id, 'can_view')
+
class PagePermissionManager(BasicPagePermissionManager):
"""Page permission manager accessible under objects.
@@ -460,10 +483,8 @@ def __get_id_list(self, user, site, attr):
if cached is not None:
return cached
# check global permissions
- global_permissions = GlobalPagePermission.objects.with_user(user)
- if global_permissions.filter(**{
- attr: True, 'sites__in':[site]
- }).exists():
+ global_perm = GlobalPagePermission.objects.user_has_permission(user, site, attr).exists()
+ if global_perm:
# user or his group are allowed to do `attr` action
# !IMPORTANT: page permissions must not override global permissions
return PagePermissionsPermissionManager.GRANT_ALL
View
@@ -692,12 +692,9 @@ def has_view_permission(self, request):
is_restricted = PagePermission.objects.for_page(self).filter(can_view=True).exists()
if request.user.is_authenticated():
- site = current_site(request)
- global_perms_q = Q(can_view=True) & Q(
- Q(sites__in=[site]) | Q(sites__isnull=True)
- )
- global_view_perms = GlobalPagePermission.objects.with_user(
- request.user).filter(global_perms_q).exists()
+
+ global_view_perms = GlobalPagePermission.objects.user_has_view_permission(
+ request.user, current_site(request)).exists()
# a global permission was given to the request's user
if global_view_perms:
return True
@@ -6,7 +6,8 @@
from django.contrib.sites.models import Site
from cms.models import Page, ACCESS_CHOICES, ACCESS_PAGE_AND_DESCENDANTS
-from cms.models.managers import BasicPagePermissionManager, PagePermissionManager
+from cms.models.managers import (BasicPagePermissionManager, PagePermissionManager,
+ GlobalPagePermissionManager)
from cms.utils.helpers import reversion_register
class AbstractPagePermission(models.Model):
@@ -51,7 +52,7 @@ class GlobalPagePermission(AbstractPagePermission):
can_recover_page = models.BooleanField(_("can recover pages"), default=True, help_text=_("can recover any deleted page"))
sites = models.ManyToManyField(Site, null=True, blank=True, help_text=_('If none selected, user haves granted permissions to all sites.'), verbose_name=_('sites'))
- objects = BasicPagePermissionManager()
+ objects = GlobalPagePermissionManager()
class Meta:
verbose_name = _('Page global permission')
View
@@ -42,8 +42,9 @@ def get_admin_menu_item_context(request, page, filtered=False):
has_add_on_same_level_permission = False
opts = Page._meta
if settings.CMS_PERMISSION:
- if (request.user.has_perm(opts.app_label + '.' + opts.get_add_permission()) and
- GlobalPagePermission.objects.with_user(request.user).filter(can_add=True, sites__in=[page.site_id])):
+ global_add_perm = GlobalPagePermission.objects.user_has_add_permission(
+ request.user, page.site_id).exists()
+ if request.user.has_perm(opts.app_label + '.' + opts.get_add_permission()) and global_add_perm:
has_add_on_same_level_permission = True
if not has_add_on_same_level_permission and page.parent_id:
View
@@ -55,8 +55,8 @@ def has_page_add_permission(request):
page = Page.objects.get(pk=target)
except Page.DoesNotExist:
return False
- if (request.user.has_perm(opts.app_label + '.' + opts.get_add_permission()) and
- GlobalPagePermission.objects.with_user(request.user).filter(can_add=True, sites__in=[page.site_id])):
+ global_add_perm = GlobalPagePermission.objects.user_has_add_permission(request.user, page.site_id).exists()
+ if request.user.has_perm(opts.app_label + '.' + opts.get_add_permission()) and global_add_perm:
return True
if position in ("first-child", "last-child"):
return page.has_add_permission(request)
@@ -67,8 +67,8 @@ def has_page_add_permission(request):
else:
from cms.utils.plugins import current_site
site = current_site(request)
- if (request.user.has_perm(opts.app_label + '.' + opts.get_add_permission()) and
- GlobalPagePermission.objects.with_user(request.user).filter(can_add=True, sites__in=[site])):
+ global_add_perm = GlobalPagePermission.objects.user_has_add_permission(request.user, site).exists()
+ if request.user.has_perm(opts.app_label + '.' + opts.get_add_permission()) and global_add_perm:
return True
return False
@@ -89,11 +89,13 @@ def has_page_change_permission(request):
"""
from cms.utils.plugins import current_site
opts = Page._meta
+
+ site = current_site(request)
+ global_change_perm = GlobalPagePermission.objects.user_has_change_permission(request.user, site).exists()
+
if request.user.is_superuser or (
- request.user.has_perm(opts.app_label + '.' + opts.get_change_permission()) and (
- GlobalPagePermission.objects.with_user(request.user).filter(
- can_change=True, sites__in=[current_site(request)]
- ).exists()) or has_any_page_change_permissions(request)):
+ request.user.has_perm(opts.app_label + '.' + opts.get_change_permission())
+ and global_change_perm or has_any_page_change_permissions(request)):
return True
return False
@@ -231,6 +233,7 @@ def has_global_change_permissions_permission(user):
def has_generic_permission(page_id, user, attr, site):
"""
Permission getter for single page with given id.
+ Internally, this calls a method on PagePermissionsPermissionManager
"""
func = getattr(Page.permissions, "get_%s_id_list" % attr)
permission = func(user, site)

0 comments on commit ee44d34

Please sign in to comment.