Skip to content

fix: Accept legacy action names for page permission check #8021

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cms/admin/pageadmin.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ def get_permissions(self, request, page_id):
if can_change_global_permissions:
can_change = True
else:
page_path = permission.page.node.path
page_path = permission.page.path
can_change = any(perm_tuple.contains(page_path) for perm_tuple in allowed_pages)

row = PermissionRow(
Expand Down
3 changes: 1 addition & 2 deletions cms/models/permissionmodels.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,7 @@ def clean(self):
raise ValidationError(message)

def get_page_permission_tuple(self):
node = self.page.node
return PermissionTuple((self.grant_on, node.path))
return PermissionTuple((self.grant_on, self.page.path))

def get_page_ids(self):
import warnings
Expand Down
2 changes: 0 additions & 2 deletions cms/test_utils/testcases.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,6 @@ def failUnlessWarns(self, category, message, f, *args, **kwargs):
self.fail(f"Warning {message} not given.")
return result

assertWarns = failUnlessWarns

def load_template_from_string(self, template):
return engines['django'].from_string(template)

Expand Down
2 changes: 1 addition & 1 deletion cms/tests/test_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ def populate(self):

message = "get_title_extension_admin has been deprecated and replaced by get_page_content_extension_admin"
with self.login_user_context(self.admin):
self.assertWarns(
self.failUnlessWarns(
RemovedInDjangoCMS43Warning,
message,
lambda: self.client.get(self.page.get_absolute_url()),
Expand Down
23 changes: 23 additions & 0 deletions cms/tests/test_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
)
from cms.models.permissionmodels import ACCESS_PAGE_AND_DESCENDANTS, GlobalPagePermission
from cms.test_utils.testcases import CMSTestCase
from cms.utils.compat.warnings import RemovedInDjangoCMS43Warning
from cms.utils.page_permissions import (
get_change_perm_tuples,
has_generic_permission,
user_can_publish_page,
)

Expand Down Expand Up @@ -88,3 +90,24 @@ def test_cached_permission_precedence(self):
Site.objects.get_current(),
)
self.assertTrue(can_publish)

def test_has_generic_permissions_compatibiltiy(self):
from cms.utils.permissions import has_page_permission

page_b = create_page("page_b", "nav_playground.html", "en",
created_by=self.user_super)
assign_user_to_page(page_b, self.user_normal, can_view=True,
can_change=True)

self.assertTrue(has_generic_permission(page_b, self.user_normal, "change_page"))
self.assertFalse(has_generic_permission(page_b, self.user_normal, "publish_page"))

message = ("has_page_permission is deprecated and will be removed in django CMS 4.3. "
"Use cms.utils.page_permissions.has_generic_permission instead.")
# Backwards compatibility: check if the old permission names work
with self.assertWarns(RemovedInDjangoCMS43Warning) as w:
self.assertTrue(has_page_permission(self.user_normal, page_b, "change"))
self.assertEqual(str(w.warning), message)
with self.assertWarns(RemovedInDjangoCMS43Warning) as w:
self.assertFalse(has_page_permission(self.user_normal, page_b, "publish"))
self.assertEqual(str(w.warning), message)
2 changes: 1 addition & 1 deletion cms/tests/test_placeholder.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def test_placeholder_scanning_nested(self):
self.assertEqual(sorted(placeholders), sorted(['new_one', 'new_two', 'new_three']))

def test_placeholder_scanning_duplicate(self):
placeholders = self.assertWarns(
placeholders = self.failUnlessWarns(
DuplicatePlaceholderWarning,
'Duplicate {% placeholder "one" %} in template placeholder_tests/test_seven.html.',
_get_placeholder_slots, 'placeholder_tests/test_seven.html'
Expand Down
2 changes: 1 addition & 1 deletion cms/tests/test_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ def test_page_attribute_warns(self):
def get_page(plugin):
return plugin.page

self.assertWarns(
self.failUnlessWarns(
DontUsePageAttributeWarning,
"Don't use the page attribute on CMSPlugins! "
"CMSPlugins are not guaranteed to have a page associated with them!",
Expand Down
3 changes: 2 additions & 1 deletion cms/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ def test_context_current_page(self):
template = Variable('CMS_TEMPLATE').resolve(response.context)
self.assertEqual(template, page_template)


class EndpointTests(CMSTestCase):

def setUp(self) -> None:
Expand Down Expand Up @@ -437,7 +438,7 @@ def test_render_object_structure_i18n(self):
self._add_plugin_to_placeholder(placeholder, "TextPlugin", language="fr")
with force_language("fr"):
setting, _ = UserSettings.objects.get_or_create(user=self.get_superuser())
setting.language="fr"
setting.language = "fr"
setting.save()
structure_endpoint_url = admin_reverse(
"cms_placeholder_render_object_structure",
Expand Down
2 changes: 1 addition & 1 deletion cms/utils/page_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ def has_generic_permission(page, user, action, site=None, check_global=True, use
if site is None:
site = get_current_site()

page_path = page.node.path
page_path = page.path
actions_map = {
'add_page': get_add_perm_tuples,
'change_page': get_change_perm_tuples,
Expand Down
11 changes: 11 additions & 0 deletions cms/utils/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,17 @@ def has_page_permission(user, page, action, use_cache=True):
"Use cms.utils.page_permissions.has_generic_permission instead.",
RemovedInDjangoCMS43Warning, stacklevel=2)

action_map = {
"change": "change_page",
"add": "add_page",
"move": "move_page",
"publish": "publish_page",
"delete": "delete_page",
"view": "view_page",
}
if action in action_map:
action = action_map[action]

return has_generic_permission(page, user, action, site=page.site, check_global=False, use_cache=use_cache)


Expand Down
7 changes: 7 additions & 0 deletions docs/upgrade/4.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ Miscellaneous
on page content objects. Use ``cms.cms_menus.get_visible_page_contents``
instead.

* The ``cms.test_utils.testcases.CMSTestCase`` class's ``assertWarns`` has been
removed since it was an alias of ``CMSTestCase.failUnlessWarns`` and shadows
Python's ``assertWarns``. In your test cases, use
Python's ``assertWarns`` instead, or use the ``failUnlessWarns`` method
of ``CMSTestCase`` which retains the syntax of the original method.


Features deprecated in 4.2.0
============================

Expand Down
Loading