Skip to content

Commit

Permalink
Merge f10b9d4 into f8201c9
Browse files Browse the repository at this point in the history
  • Loading branch information
czpython committed Jan 13, 2016
2 parents f8201c9 + f10b9d4 commit 181db67
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 105 deletions.
2 changes: 1 addition & 1 deletion cms/admin/pageadmin.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ def has_add_permission(self, request):
Return true if the current user has permission to add a new page.
"""
if get_cms_setting('PERMISSION'):
return permissions.has_page_add_permission(request)
return permissions.has_page_add_permission_from_request(request)
return super(PageAdmin, self).has_add_permission(request)

def has_change_permission(self, request, obj=None):
Expand Down
49 changes: 3 additions & 46 deletions cms/cms_wizards.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# -*- coding: utf-8 -*-

from django.utils.translation import ugettext_lazy as _
from django.contrib.auth import get_permission_codename
from django.contrib.sites.models import Site

from cms.models import Page, GlobalPagePermission
from cms.models import Page
from cms.utils import permissions

from .wizards.wizard_pool import wizard_pool
Expand All @@ -13,56 +12,14 @@
from .forms.wizards import CreateCMSPageForm, CreateCMSSubPageForm


def user_has_page_add_permission(user, target, position=None, site=None):
"""
Verify that «user» has permission to add a new page relative to «target».
:param user: a User object
:param target: a Page object
:param position: a String "first-child", "last-child", "left", or "right"
:param site: only used if target is None, a Site object
:return:
"""
if not user:
return False
if user.is_superuser:
return True
opts = Page._meta

if site is None:
if target:
site = target.site
if site is None:
site = Site.objects.get_current()
global_add_perm = GlobalPagePermission.objects.user_has_add_permission(
user, site).exists()

perm_str = opts.app_label + '.' + get_permission_codename('add', opts)

if target:
if not Page.objects.filter(pk=target.pk).exists():
return False
if user.has_perm(perm_str) and global_add_perm:
return True
if position in ("first-child", "last-child"):
return permissions.has_generic_permission(
target.pk, user, "add", target.site_id)
elif position in ("left", "right") and target.parent_id:
return permissions.has_generic_permission(
target.parent_id, user, "add", target.site_id)
else:
if user.has_perm(perm_str) and global_add_perm:
return True
return False


class CMSPageWizard(Wizard):

def user_has_add_permission(self, user, page=None, **kwargs):
if not page or not page.site_id:
site = Site.objects.get_current()
else:
site = Site.objects.get(pk=page.site_id)
return user_has_page_add_permission(
return permissions.has_page_add_permission(
user, page, position="right", site=site)


Expand All @@ -77,7 +34,7 @@ def user_has_add_permission(self, user, page=None, **kwargs):
site = Site.objects.get_current()
else:
site = Site.objects.get(pk=page.site_id)
return user_has_page_add_permission(
return permissions.has_page_add_permission(
user, page, position="last-child", site=site)


Expand Down
6 changes: 3 additions & 3 deletions cms/forms/wizards.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def clean_slug(self):

def save(self, **kwargs):
from cms.api import create_page, add_plugin
from cms.cms_wizards import user_has_page_add_permission
from cms.utils.permissions import has_page_add_permission

# Check to see if this user has permissions to make this page. We've
# already checked this when producing a list of wizard entries, but this
Expand All @@ -220,9 +220,9 @@ def save(self, **kwargs):

# Before we do this, verify this user has perms to do so.
if not (self.user.is_superuser or
user_has_page_add_permission(self.user, self.page,
has_page_add_permission(self.user, self.page,
position=position,
site=self.page.site_id)):
site=self.page.site)):
raise NoPermissionsException(
_(u"User does not have permission to add page."))

Expand Down
30 changes: 16 additions & 14 deletions cms/tests/test_permmod.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from cms.test_utils.util.fuzzy_int import FuzzyInt
from cms.utils.i18n import force_language
from cms.utils.page_resolver import get_page_from_path
from cms.utils.permissions import (has_page_add_permission,
from cms.utils.permissions import (has_page_add_permission_from_request,
has_page_change_permission,
has_generic_permission)

Expand Down Expand Up @@ -1123,11 +1123,13 @@ def test_emulate_admin_index(self):
is_superuser=True)
superuser.set_password("super")
superuser.save()

site_1 = Site.objects.get(pk=1)
site_2 = Site.objects.create(domain='example2.com', name='example2.com')

SITES = [site_1, site_2]

# create 2 staff users
SITES = [
Site.objects.get(pk=1),
Site.objects.create(domain='example2.com', name='example2.com'),
]
USERS = [
self._create_user("staff", is_staff=True, is_active=True),
self._create_user("staff_2", is_staff=True, is_active=True),
Expand Down Expand Up @@ -1161,20 +1163,20 @@ def test_emulate_admin_index(self):

with self.settings(CMS_PERMISSION=True):
# for all users, they should have access to site 1
request = RequestFactory().get(path='/', data={'site__exact': 1})
request = RequestFactory().get(path='/', data={'site__exact': site_1.pk})
# we need a session attribute for current_site(request), which is
# used by has_page_add_permission and has_page_change_permission
# used by has_page_add_permission_from_request and has_page_change_permission
request.session = {}
for user in USERS:
# has_page_add_permission and has_page_change_permission both test
# has_page_add_permission_from_request and has_page_change_permission both test
# for this explicitly, to see if it's a superuser.
request.user = user
# Note, the query count is inflated by doing additional lookups
# because there's a site param in the request.
with self.assertNumQueries(FuzzyInt(6, 7)):
# PageAdmin swaps out the methods called for permissions
# if the setting is true, it makes use of cms.utils.permissions
self.assertTrue(has_page_add_permission(request))
self.assertTrue(has_page_add_permission_from_request(request))
self.assertTrue(has_page_change_permission(request))
# internally this calls PageAdmin.has_[add|change|delete]_permission()
self.assertEqual({'add': True, 'change': True, 'delete': False},
Expand All @@ -1183,21 +1185,21 @@ def test_emulate_admin_index(self):
# can't use the above loop for this test, as we're testing that
# user 1 has access, but user 2 does not, as they are only assigned
# to site 1
request = RequestFactory().get('/', data={'site__exact': 2})
request = RequestFactory().get('/', data={'site__exact': site_2.pk})
request.session = {}
# As before, the query count is inflated by doing additional lookups
# because there's a site param in the request
with self.assertNumQueries(FuzzyInt(11, 20)):
# this user shouldn't have access to site 2
request.user = USERS[1]
self.assertTrue(not has_page_add_permission(request))
self.assertTrue(not has_page_add_permission_from_request(request))
self.assertTrue(not has_page_change_permission(request))
self.assertEqual({'add': False, 'change': False, 'delete': False},
site._registry[Page].get_model_perms(request))
# but, going back to the first user, they should.
request = RequestFactory().get('/', data={'site__exact': 2})
request = RequestFactory().get('/', data={'site__exact': site_2.pk})
request.user = USERS[0]
self.assertTrue(has_page_add_permission(request))
self.assertTrue(has_page_add_permission_from_request(request))
self.assertTrue(has_page_change_permission(request))
self.assertEqual({'add': True, 'change': True, 'delete': False},
site._registry[Page].get_model_perms(request))
Expand All @@ -1208,5 +1210,5 @@ def test_has_page_add_permission_with_target(self):
request = RequestFactory().get('/', data={'target': page.pk})
request.session = {}
request.user = user
has_perm = has_page_add_permission(request)
has_perm = has_page_add_permission_from_request(request)
self.assertFalse(has_perm)
2 changes: 1 addition & 1 deletion cms/utils/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def render_admin_menu_item(request, page, template=None, language=None):
from cms.utils import permissions
languages = get_language_list(page.site_id)
context = {
'has_add_permission': permissions.has_page_add_permission(request),
'has_add_permission': permissions.has_page_add_permission_from_request(request),
'site_languages': languages,
}
filtered = 'filtered' in request.GET or 'filtered' in request.POST
Expand Down
108 changes: 68 additions & 40 deletions cms/utils/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,62 +52,90 @@ def user_has_page_add_perm(user, site=None):
:param site: optional Site object (not just PK)
:return: Boolean
"""
opts = Page._meta
if not site:
site = Site.objects.get_current()
global_add_perm = GlobalPagePermission.objects.user_has_add_permission(
user, site.pk).exists()
perm_str = opts.app_label + '.' + get_permission_codename('add', opts)
if user.has_perm(perm_str) and global_add_perm:
return True
return False

if get_cms_setting('PERMISSION'):
global_add_perm = (
GlobalPagePermission
.objects
.user_has_add_permission(user, site.pk)
.exists()
)
else:
global_add_perm = True
return has_auth_page_permission(user, action='add') and global_add_perm

def has_page_add_permission(request):
"""
Return true if the current user has permission to add a new page. This is
just used for general add buttons - only superuser, or user with can_add in
globalpagepermission can add page.

Special case occur when page is going to be added from add page button in
change list - then we have target and position there, so check if user can
add page under target page will occur.
def has_page_add_permission(user, target=None, position=None, site=None):
"""
opts = Page._meta
if request.user.is_superuser:
Return true if the current user has permission to add a new page.
If we have target and position, check if user can
add page under target page.
:param user:
:param target: a Page object
:param position: a String "first-child", "last-child", "left", or "right"
:param site: optional Site object (not just PK)
:return: Boolean
"""
if user.is_superuser:
return True

# if add under page
target = request.GET.get('target', None)
position = request.GET.get('position', None)
if site is None:
if target:
site = target.site
else:
site = Site.objects.get_current()

has_add_permission = user_has_page_add_perm(user, site=site)

if not get_cms_setting('PERMISSION') or not target:
# If CMS permissions are disabled
# we can't really check anything but Django permissions.
# If there's no target then we let the global CMS permission
# handle user access.
return has_add_permission

if has_add_permission:
# There's a target page
# and CMS permissions are enabled.
# User has global add permissions so no need to check
# the target page.
return True

if position in ("first-child", "last-child"):
return target.has_add_permission(request=None, user=user)
elif position in ("left", "right"):
if target.parent_id:
return has_generic_permission(
target.parent_id, user, "add", site)
return False


def has_page_add_permission_from_request(request):
from cms.utils.helpers import current_site

site = current_site(request)
if request.user.is_superuser:
return True

position = request.GET.get('position', None)
target_page_id = request.GET.get('target', None)

if target:
if target_page_id:
try:
page = Page.objects.get(pk=target)
target = Page.objects.get(pk=target_page_id)
except Page.DoesNotExist:
return False
global_add_perm = GlobalPagePermission.objects.user_has_add_permission(
request.user, site).exists()
perm_str = opts.app_label + '.' + get_permission_codename('add', opts)
if request.user.has_perm(perm_str) and global_add_perm:
return True
if position in ("first-child", "last-child"):
return page.has_add_permission(request)
elif position in ("left", "right"):
if page.parent_id:
return has_generic_permission(
page.parent_id, request.user, "add", page.site)
else:
global_add_perm = GlobalPagePermission.objects.user_has_add_permission(
request.user, site).exists()
perm_str = opts.app_label + '.' + get_permission_codename('add', opts)
if request.user.has_perm(perm_str) and global_add_perm:
return True
return False
target = None

has_add_permission = has_page_add_permission(
user=request.user,
target=target,
position=position,
site=current_site(request),
)
return has_add_permission


def has_any_page_change_permissions(request):
Expand Down

0 comments on commit 181db67

Please sign in to comment.