Skip to content

Commit

Permalink
fix: update permission cache when moving pages and adding pages. (#7090)
Browse files Browse the repository at this point in the history
  • Loading branch information
air-hand committed Jul 7, 2021
1 parent 67f761a commit 53dddb1
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 3 deletions.
5 changes: 5 additions & 0 deletions cms/models/pagemodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
)

from cms import constants
from cms.cache.permissions import clear_permission_cache
from cms.constants import PUBLISHER_STATE_DEFAULT, PUBLISHER_STATE_PENDING, PUBLISHER_STATE_DIRTY, TEMPLATE_INHERITANCE_MAGIC
from cms.exceptions import PublicIsUnmodifiable, PublicVersionNeeded, LanguageError
from cms.models.managers import PageManager, PageNodeManager
Expand Down Expand Up @@ -564,6 +565,8 @@ def move_page(self, target_node, position='first-child'):
self.mark_as_published(language)
self.mark_descendants_as_published(language)
self.clear_cache(menu=True)
if get_cms_setting('PERMISSION'):
clear_permission_cache()
return self

def _copy_titles(self, target, language, published):
Expand Down Expand Up @@ -827,6 +830,8 @@ def save(self, **kwargs):
if created:
self.created_by = self.changed_by
super().save(**kwargs)
if created and get_cms_setting('PERMISSION'):
clear_permission_cache()

def save_base(self, *args, **kwargs):
"""Overridden save_base. If an instance is draft, and was changed, mark
Expand Down
61 changes: 58 additions & 3 deletions cms/tests/test_permissions.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from django.contrib.auth import get_user_model
from django.contrib.sites.models import Site
from django.test.utils import override_settings

from cms.api import create_page, assign_user_to_page
from cms.cache.permissions import (get_permission_cache, set_permission_cache,
clear_user_permission_cache)
from cms.models.permissionmodels import GlobalPagePermission
from cms.test_utils.testcases import CMSTestCase
from cms.utils.page_permissions import get_change_id_list, user_can_publish_page
from cms.models import Page
from cms.models.permissionmodels import GlobalPagePermission, ACCESS_PAGE_AND_DESCENDANTS
from cms.test_utils.testcases import CMSTestCase, URL_CMS_PAGE_ADD
from cms.utils.page_permissions import get_change_id_list, user_can_publish_page, user_can_view_page, user_can_add_subpage


@override_settings(
Expand Down Expand Up @@ -82,3 +84,56 @@ def test_cached_permission_precedence(self):
Site.objects.get_current(),
)
self.assertTrue(can_publish)

def test_visibility_after_move_page(self):
superuser = self.get_superuser()
user1 = self._create_user("user1", is_staff=True, is_superuser=False)

visible = create_page("visible", "nav_playground.html", "en", published=True)
visible_child = create_page("visible_child", "nav_playground.html", "en", parent=visible, published=True)
invisible_for_user1 = create_page("invisible", "nav_playground.html", "en", published=True)

assign_user_to_page(visible, user1, grant_on=ACCESS_PAGE_AND_DESCENDANTS, can_view=True)
assign_user_to_page(invisible_for_user1, superuser, grant_on=ACCESS_PAGE_AND_DESCENDANTS, can_view=True)

with self.login_user_context(user1):
response = self.client.get(visible_child.get_public_object().get_absolute_url())
self.assertEqual(response.status_code, 200)

response = self.client.get(invisible_for_user1.get_public_object().get_absolute_url())
self.assertEqual(response.status_code, 404)

with self.login_user_context(superuser):
move_url = self.get_admin_url(Page, 'move_page', visible_child.pk)
response = self.client.post(move_url, {
'id': visible_child.pk,
'position': 0,
'target': invisible_for_user1.pk,
})
self.assertEqual(response.status_code, 200)
visible_child = visible_child.reload()
self.assertEqual(visible_child.parent_page.pk, invisible_for_user1.pk)

# Ignore cached_func
User = get_user_model()
user1 = User.objects.get(pk=user1.pk)
self.assertFalse(user_can_view_page(user=user1, page=visible_child))

def test_add_page_twice(self):
user1 = self._create_user("user1", is_staff=True, is_superuser=False, add_default_permissions=True)

home = create_page("home", "nav_playground.html", "en", published=True)
home.set_as_homepage()
assign_user_to_page(home, user1, grant_on=ACCESS_PAGE_AND_DESCENDANTS, can_add=True, can_change=True, can_publish=True)

with self.login_user_context(user1):
response = self.client.post(f'{URL_CMS_PAGE_ADD}?parent_node={home.node.pk}', self.get_new_page_data(parent_id=home.node.pk))
self.assertEqual(response.status_code, 302)

child = home.reload().get_child_pages().first()
self.assertIsNotNone(child)

# Ignore cached_func
User = get_user_model()
user1 = User.objects.get(pk=user1.pk)
self.assertTrue(user_can_add_subpage(user1, child))

0 comments on commit 53dddb1

Please sign in to comment.