Allow displaying permissions linked to the Admin model's content type (#11668)

pull/11620/head
Sage Abdullah 2024-02-15 17:28:44 +00:00 zatwierdzone przez Matt Westcott
rodzic 2594be387d
commit bded2cb98b
5 zmienionych plików z 84 dodań i 10 usunięć

Wyświetl plik

@ -11,6 +11,7 @@ Changelog
* 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)
* Allow displaying permissions linked to the Admin model's content type (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

@ -20,6 +20,7 @@ depth: 1
* 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)
* Allow displaying permissions linked to the Admin model's content type (Sage Abdullah)
### Bug fixes

Wyświetl plik

@ -67,9 +67,29 @@ See Django's documentation on [custom permissions](https://docs.djangoproject.co
The ability to have custom permissions with codenames starting with `add_`, `change_`, or `delete_` was added.
```
## Displaying custom permissions in the admin
Permissions for models registered with Wagtail will automatically show up in the Wagtail admin Group edit form. For other models, you can also add the permissions using the `register_permissions` hook (see [](register_permissions)).
Most permissions will automatically show up in the Wagtail admin Group edit form, however, you can also add them using the `register_permissions` hook (see [](register_permissions)).
To add a custom permission to be used in the Wagtail admin without relating to a specific model, you can create it using the content type of the `wagtail.admin.models.Admin` model. For example:
```python
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from wagtail.admin.models import Admin
content_type = ContentType.objects.get_for_model(Admin)
permission = Permission.objects.create(
content_type=content_type,
codename="can_do_something",
name="Can do something",
)
```
After registering the permission using the `register_permissions` hook, it will be displayed in the Wagtail admin Group edit form under the 'Other permissions' section, alongside the 'Can access Wagtail admin' permission.
```{versionadded} 6.1
The ability to register custom permissions in the "Other permissions" section was added.
```
## `FieldPanel` and `PanelGroup` permissions

Wyświetl plik

@ -4,9 +4,11 @@ from collections import defaultdict
from django import template
from django.contrib.auth import get_permission_codename
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from django.utils.text import camel_case_to_spaces
from wagtail import hooks
from wagtail.admin.models import Admin
from wagtail.users.permission_order import CONTENT_TYPE_ORDER
register = template.Library()
@ -97,9 +99,6 @@ def format_permissions(permission_bound_field):
for checkbox in permission_bound_field
}
object_perms = []
other_perms = []
# Permissions that are known by Wagtail, to be shown under their own columns.
# Other permissions will be shown under the "custom permissions" column.
main_permission_names = ["add", "change", "delete", "publish", "lock", "unlock"]
@ -118,17 +117,29 @@ def format_permissions(permission_bound_field):
for permission in permissions:
content_perms_by_ct_id[permission.content_type_id].append(permission)
# Permissions that use Wagtail's Admin content type, to be displayed
# under the "Other permissions" section alongside the
# "Can access Wagtail admin" permission.
admin_content_type = ContentType.objects.get_for_model(Admin)
admin_permissions = content_perms_by_ct_id.pop(admin_content_type.id, [])
other_perms = [(perm, checkboxes_by_id[perm.id]) for perm in admin_permissions]
# We're done with the admin content type, so remove it from the list of content types
# but make sure the sorted order is preserved.
content_type_ids = [
ct_id for ct_id in content_type_ids if ct_id != admin_content_type.pk
]
# Permissions for all other content types, to be displayed under the
# "Object permissions" section.
object_perms = []
# Iterate using the sorted content_type_ids
for ct_id in content_type_ids:
content_perms = content_perms_by_ct_id[ct_id]
content_perms_dict = {}
custom_perms = []
if content_perms[0].content_type.name == "admin":
perm = content_perms[0]
other_perms.append((perm, checkboxes_by_id[perm.id]))
continue
for perm in content_perms:
content_perms_dict["object"] = perm.content_type.name
checkbox = checkboxes_by_id[perm.id]

Wyświetl plik

@ -5,6 +5,7 @@ from django.apps import apps
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ImproperlyConfigured
from django.core.files.uploadedfile import SimpleUploadedFile
from django.db.models import Q
@ -14,6 +15,7 @@ from django.urls import reverse
from wagtail import hooks
from wagtail.admin.admin_url_finder import AdminURLFinder
from wagtail.admin.models import Admin
from wagtail.compat import AUTH_USER_APP_LABEL, AUTH_USER_MODEL_NAME
from wagtail.models import (
Collection,
@ -1637,6 +1639,45 @@ class TestGroupCreateView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
)
)
def test_custom_other_permissions_with_wagtail_admin_content_type(self):
"""
https://github.com/wagtail/wagtail/issues/8086
Allow custom permissions using Wagtail's Admin content type to be
displayed in the "Other permissions" section.
"""
admin_ct = ContentType.objects.get_for_model(Admin)
custom_permission = Permission.objects.create(
codename="roadmap_sync",
name="Can sync roadmap items from GitHub",
content_type=admin_ct,
)
with self.register_hook(
"register_permissions",
lambda: Permission.objects.filter(
codename="roadmap_sync", content_type=admin_ct
),
):
response = self.get()
soup = self.get_soup(response.content)
other_permissions = soup.select_one("#other-permissions-section")
self.assertIsNotNone(other_permissions)
custom_checkbox = other_permissions.select_one(
f'input[value="{custom_permission.pk}"]'
)
self.assertIsNotNone(custom_checkbox)
custom_label = other_permissions.select_one(
f'label[for="{custom_checkbox.attrs.get("id")}"]'
)
self.assertIsNotNone(custom_label)
self.assertEqual(
custom_label.get_text(strip=True), "Can sync roadmap items from GitHub"
)
class TestGroupEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
def setUp(self):