From 2dcbc9b5c002ef27215532fbb8eb2ac00abb345c Mon Sep 17 00:00:00 2001 From: Daniel Pollithy Date: Fri, 2 Jun 2017 13:32:04 +0000 Subject: [PATCH] Fixed #32 1) copy page permissions 2) transform page permissions of parents to suite (ACCESS_DESCENDANTS -> ACCESS_PAGE_AND_DESCENDANTS and ACCESS_CHILDREN -> ACCESS_PAGE) 3) copy the transformed permissions Note: The middleware is obsolete now --- utils.py | 54 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/utils.py b/utils.py index 4b6a953..20d91c5 100644 --- a/utils.py +++ b/utils.py @@ -12,11 +12,14 @@ from cms import api, constants from cms.exceptions import PublicIsUnmodifiable from cms.extensions import extension_pool -from cms.models import Page, Placeholder, Title, menu_pool, copy_plugins_to +from cms.models import Page, Placeholder, Title, menu_pool, copy_plugins_to, Q, ACCESS_DESCENDANTS, \ + ACCESS_PAGE_AND_DESCENDANTS, ACCESS_CHILDREN, ACCESS_PAGE_AND_CHILDREN, ACCESS_PAGE, PagePermission from cms.utils.conf import get_cms_setting from django.db import IntegrityError from django.db import transaction + + VERSION_ROOT_TITLE = '.~VERSIONS' VERSION_FIELD_DEFAULTS = { @@ -107,21 +110,52 @@ def revise_page(page, language): new_page = new_page.move(version_page_root, pos="last-child") - # Copy the permissions from the old page to the new page - # TODO: get parent permission - # so far this only covers permissions that are directly attached to a page, not its descendants - # if get_cms_setting('PERMISSION'): - # new_permissions = [] - # origin_page = Page.objects.get(pk=origin_id) - # # copy all permissions to hidden_page and replace the page - # for perm in origin_page.pagepermission_set.iterator(): - # new_permissions.append(_copy_model(perm, page=new_page)) + # Copy the permissions from the old page and its parents to the new page + + # MAP the parent permission to new child permissions + mapping = { + ACCESS_DESCENDANTS: ACCESS_PAGE_AND_DESCENDANTS, + ACCESS_CHILDREN: ACCESS_PAGE + } + # for_page sadly doesn't work as expected + if get_cms_setting('PERMISSION'): + origin_page = Page.objects.get(pk=origin_id) + # store the new permissions + new_permissions = [] + # Copy page's permissions + for perm in origin_page.pagepermission_set.all(): + new_permissions.append(_copy_model(perm, page=new_page)) + # the permission of all relevant parents + perms = inherited_permissions(origin_page) + for perm in perms: + latest = _copy_model(perm, page=new_page) + if latest.grant_on in mapping.keys(): + new_permissions.append(latest) + # apply the mapping (see some lines above) + latest.grant_on = mapping[latest.grant_on] + latest.save() # invalidate the menu for this site menu_pool.clear(site_id=site.pk) return new_page +def inherited_permissions(page): + """Returns queryset containing all instances somehow connected to given + page. + """ + paths = [ + page.path[0:pos] + for pos in range(0, len(page.path), page.steplen)[1:] + ] + parents = Q(page__path__in=paths) & (Q(grant_on=ACCESS_DESCENDANTS) | Q(grant_on=ACCESS_PAGE_AND_DESCENDANTS)) + direct_parents = Q(page__pk=page.parent_id) & (Q(grant_on=ACCESS_CHILDREN) | Q(grant_on=ACCESS_PAGE_AND_CHILDREN)) + #page_qs = Q(page=page) & (Q(grant_on=ACCESS_PAGE_AND_DESCENDANTS) | Q(grant_on=ACCESS_PAGE_AND_CHILDREN) | + # Q(grant_on=ACCESS_PAGE)) + query = (parents | direct_parents) + return PagePermission.objects.filter(query).order_by('-page__depth') + + def revert_page(page_version, language): from .models import PageVersion # copy all relevant attributes from hidden_page to draft