Prevent shadowing of permissions with the same codename action (#11667)

This can cause issues where e.g. stale permissions become the ones used
to render the checkboxes after a RenameModel operation (changing the
Python class name, not just the verbose_name).

A similar issue can also be triggered with custom permissions that share
the same codename action (first part of the codename before _) as the
built-in permissions.
pull/11575/head
Sage Abdullah 2024-02-14 14:16:59 +00:00 zatwierdzone przez Matt Westcott
rodzic e418cd6e5b
commit 3b87644e07
5 zmienionych plików z 56 dodań i 3 usunięć

Wyświetl plik

@ -10,6 +10,7 @@ Changelog
* Support creating images in .ico format (Jake Howard)
* Add the ability to disable the usage of a shared password for enhanced security for the private pages and collections (documents) feature (Salvo Polizzi, Jake Howard)
* Add system checks to ensure that `WAGTAIL_DATE_FORMAT`, `WAGTAIL_DATETIME_FORMAT`, `WAGTAIL_TIME_FORMAT` are correctly configured (Rohit Sharma, Coen van der Kamp)
* Allow custom permissions with the same prefix as built-in permissions (Sage Abdullah)
* Fix: Fix typo in `__str__` for MySQL search index (Jake Howard)
* Fix: Ensure that unit tests correctly check for migrations in all core Wagtail apps (Matt Westcott)
* Fix: Correctly handle `date` objects on `human_readable_date` template tag (Jhonatan Lopes)

Wyświetl plik

@ -19,6 +19,7 @@ depth: 1
* Support creating images in .ico format (Jake Howard)
* Add the ability to disable the usage of a shared password for enhanced security for the [private pages](private_pages) and [collections (documents)](private_collections) feature (Salvo Polizzi, Jake Howard)
* Add system checks to ensure that `WAGTAIL_DATE_FORMAT`, `WAGTAIL_DATETIME_FORMAT`, `WAGTAIL_TIME_FORMAT` are [correctly configured](wagtail_date_time_formats) (Rohit Sharma, Coen van der Kamp)
* Allow custom permissions with the same prefix as built-in permissions (Sage Abdullah)
### Bug fixes

Wyświetl plik

@ -63,8 +63,8 @@ Users are not allowed to move or delete the collection that is used to assign th
See Django's documentation on [custom permissions](https://docs.djangoproject.com/en/stable/topics/auth/customizing/#custom-permissions) for details on how to set permissions up.
```{note}
Custom permissions starting with `add_`, `change_`, or `delete_` are not currently supported in Wagtail as these will conflict with standard model permissions.
```{versionadded} 6.1
The ability to have custom permissions with codenames starting with `add_`, `change_`, or `delete_` was added.
```
## Displaying custom permissions in the admin

Wyświetl plik

@ -135,7 +135,12 @@ def format_permissions(permission_bound_field):
# identify the main categories of permission, and assign to
# the relevant dict key, else bung in the 'custom_perms' list
permission_action = perm.codename.split("_")[0]
if permission_action in main_permission_names:
is_known = (
permission_action in main_permission_names
and perm.codename == f"{permission_action}_{perm.content_type.model}"
)
if is_known:
if permission_action in extra_perms_exist:
extra_perms_exist[permission_action] = True
content_perms_dict[permission_action] = {

Wyświetl plik

@ -1533,6 +1533,13 @@ class TestGroupCreateView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
| Q(codename__startswith="publish")
).delete()
# A custom permission that happens to also start with "change"
Permission.objects.filter(
codename="change_text",
content_type__app_label="tests",
content_type__model="custompermissionmodel",
).delete()
response = self.get()
self.assertInHTML("Custom permissions", response.content.decode(), count=0)
@ -1591,6 +1598,45 @@ class TestGroupCreateView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
self.assertNotContains(response, "Cause chaos for advanced permission model")
self.assertNotContains(response, "Manage custom permission model")
def test_permission_with_same_action(self):
"""
https://github.com/wagtail/wagtail/issues/11650
Ensure that permissions with the same action (part before the first _ in
the codename) are not hidden.
"""
response = self.get()
soup = self.get_soup(response.content)
main_change_permission = Permission.objects.get(
codename="change_custompermissionmodel",
content_type__app_label="tests",
content_type__model="custompermissionmodel",
)
custom_change_permission = Permission.objects.get(
codename="change_text",
content_type__app_label="tests",
content_type__model="custompermissionmodel",
)
# Main change permission is in the dedicated column, so it's directly
# inside a <td>, not inside a <fieldset>"
self.assertIsNotNone(
soup.select_one(f'td > input[value="{main_change_permission.pk}"]')
)
self.assertIsNone(
soup.select_one(f'td > fieldset input[value="{main_change_permission.pk}"]')
)
# Custom "change_text" permission is in the custom permissions column,
# so it's inside a <fieldset> and not directly inside a <td>
self.assertIsNone(
soup.select_one(f'td > input[value="{custom_change_permission.pk}"]')
)
self.assertIsNotNone(
soup.select_one(
f'td > fieldset input[value="{custom_change_permission.pk}"]'
)
)
class TestGroupEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
def setUp(self):