kopia lustrzana https://github.com/wagtail/wagtail
Allow displaying permissions linked to the Admin model's content type (#11668)
rodzic
2594be387d
commit
bded2cb98b
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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):
|
||||
|
|
Ładowanie…
Reference in New Issue