diff --git a/wagtail/contrib/settings/tests/generic/test_admin.py b/wagtail/contrib/settings/tests/generic/test_admin.py index f0ca5a61d101..fb221beff70f 100644 --- a/wagtail/contrib/settings/tests/generic/test_admin.py +++ b/wagtail/contrib/settings/tests/generic/test_admin.py @@ -14,6 +14,7 @@ PanelGenericSettings, TabbedGenericSettings, TestGenericSetting, + TestPermissionedGenericSetting, ) from wagtail.test.utils import WagtailTestUtils @@ -114,7 +115,7 @@ def setUp(self): self.test_setting.title = "Setting title" self.test_setting.save() - self.login() + self.user = self.login() def test_get_edit(self): response = self.get() @@ -153,6 +154,37 @@ def test_for_request(self): expected_url=f"{url}{TestGenericSetting.objects.first().pk}/", ) + def test_permission_restricted_field(self): + test_setting = TestPermissionedGenericSetting() + test_setting.sensitive_email = "test@example.com" + test_setting.save() + self.user.user_permissions.add( + Permission.objects.get( + content_type__app_label="wagtailadmin", codename="access_admin" + ) + ) + + self.assertTrue(self.user.is_superuser) + response = self.get(setting=TestPermissionedGenericSetting) + self.assertEqual(response.status_code, 200) + self.assertIn("sensitive_email", response.context["form"].fields) + + self.user.is_superuser = False + self.user.save() + + self.assertFalse(self.user.is_superuser) + response = self.get(setting=TestPermissionedGenericSetting) + self.assertEqual(response.status_code, 200) + self.assertNotIn("sensitive_email", list(response.context["form"].fields)) + + self.user.user_permissions.add( + Permission.objects.get(codename="can_edit_sensitive_email_generic_setting") + ) + + response = self.get(setting=TestPermissionedGenericSetting) + self.assertEqual(response.status_code, 200) + self.assertIn("sensitive_email", list(response.context["form"].fields)) + class TestAdminPermission(WagtailTestUtils, TestCase): def test_registered_permission(self): diff --git a/wagtail/contrib/settings/tests/site_specific/test_admin.py b/wagtail/contrib/settings/tests/site_specific/test_admin.py index 6ef914460be7..8da910c8754f 100644 --- a/wagtail/contrib/settings/tests/site_specific/test_admin.py +++ b/wagtail/contrib/settings/tests/site_specific/test_admin.py @@ -14,6 +14,7 @@ IconSiteSetting, PanelSiteSettings, TabbedSiteSettings, + TestPermissionedSiteSetting, TestSiteSetting, ) from wagtail.test.utils import WagtailTestUtils @@ -106,15 +107,15 @@ def test_file_upload_multipart(self): class TestSiteSettingEditView(BaseTestSiteSettingView): def setUp(self): - default_site = Site.objects.get(is_default_site=True) + self.default_site = Site.objects.get(is_default_site=True) self.test_setting = TestSiteSetting() self.test_setting.title = "Site title" self.test_setting.email = "initial@example.com" - self.test_setting.site = default_site + self.test_setting.site = self.default_site self.test_setting.save() - self.login() + self.user = self.login() def test_get_edit(self): response = self.get() @@ -158,6 +159,38 @@ def test_get_redirect_to_relevant_instance_invalid(self): response = self.client.get(url) self.assertRedirects(response, status_code=302, expected_url="/admin/") + def test_permission_restricted_field(self): + test_setting = TestPermissionedSiteSetting() + test_setting.sensitive_email = "test@example.com" + test_setting.site = self.default_site + test_setting.save() + self.user.user_permissions.add( + Permission.objects.get( + content_type__app_label="wagtailadmin", codename="access_admin" + ) + ) + + self.assertTrue(self.user.is_superuser) + response = self.get(setting=TestPermissionedSiteSetting) + self.assertEqual(response.status_code, 200) + self.assertIn("sensitive_email", response.context["form"].fields) + + self.user.is_superuser = False + self.user.save() + + self.assertFalse(self.user.is_superuser) + response = self.get(setting=TestPermissionedSiteSetting) + self.assertEqual(response.status_code, 200) + self.assertNotIn("sensitive_email", list(response.context["form"].fields)) + + self.user.user_permissions.add( + Permission.objects.get(codename="can_edit_sensitive_email_site_setting") + ) + + response = self.get(setting=TestPermissionedSiteSetting) + self.assertEqual(response.status_code, 200) + self.assertIn("sensitive_email", list(response.context["form"].fields)) + @override_settings( ALLOWED_HOSTS=["testserver", "example.com", "noneoftheabove.example.com"] diff --git a/wagtail/contrib/settings/views.py b/wagtail/contrib/settings/views.py index 755b2bcb46f5..fabfd940cb38 100644 --- a/wagtail/contrib/settings/views.py +++ b/wagtail/contrib/settings/views.py @@ -101,6 +101,10 @@ def get_object(self, queryset=None): def get_form_class(self): return get_setting_edit_handler(self.model).get_form_class() + def get_form_kwargs(self): + # Pass the current user, which is needed for permission-restricted fields + return {**super().get_form_kwargs(), "for_user": self.request.user} + def get_edit_url(self): return reverse( "wagtailsettings:edit", diff --git a/wagtail/test/testapp/migrations/0034_testpermissionedgenericsetting_and_more.py b/wagtail/test/testapp/migrations/0034_testpermissionedgenericsetting_and_more.py new file mode 100644 index 000000000000..958e67a5ee1a --- /dev/null +++ b/wagtail/test/testapp/migrations/0034_testpermissionedgenericsetting_and_more.py @@ -0,0 +1,71 @@ +# Generated by Django 4.2.11 on 2024-04-23 13:53 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("wagtailcore", "0091_remove_revision_submitted_for_moderation"), + ("tests", "0033_customcopyformpage"), + ] + + operations = [ + migrations.CreateModel( + name="TestPermissionedGenericSetting", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.CharField(max_length=100)), + ("sensitive_email", models.EmailField(max_length=50)), + ], + options={ + "permissions": [ + ( + "can_edit_sensitive_email_generic_setting", + "Can edit sensitive email generic setting.", + ) + ], + }, + ), + migrations.CreateModel( + name="TestPermissionedSiteSetting", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.CharField(max_length=100)), + ("sensitive_email", models.EmailField(max_length=50)), + ( + "site", + models.OneToOneField( + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="wagtailcore.site", + ), + ), + ], + options={ + "permissions": [ + ( + "can_edit_sensitive_email_site_setting", + "Can edit sensitive email site setting.", + ) + ], + }, + ), + ] diff --git a/wagtail/test/testapp/models.py b/wagtail/test/testapp/models.py index f0ac00fe34d8..e4568d796072 100644 --- a/wagtail/test/testapp/models.py +++ b/wagtail/test/testapp/models.py @@ -1640,6 +1640,49 @@ class TestGenericSetting(BaseGenericSetting): email = models.EmailField(max_length=50) +@register_setting +class TestPermissionedGenericSetting(BaseGenericSetting): + title = models.CharField(max_length=100) + sensitive_email = models.EmailField(max_length=50) + + panels = [ + FieldPanel("title"), + FieldPanel( + "sensitive_email", + permission="tests.can_edit_sensitive_email_generic_setting", + ), + ] + + class Meta: + permissions = [ + ( + "can_edit_sensitive_email_generic_setting", + "Can edit sensitive email generic setting.", + ), + ] + + +@register_setting +class TestPermissionedSiteSetting(BaseSiteSetting): + title = models.CharField(max_length=100) + sensitive_email = models.EmailField(max_length=50) + + panels = [ + FieldPanel("title"), + FieldPanel( + "sensitive_email", permission="tests.can_edit_sensitive_email_site_setting" + ), + ] + + class Meta: + permissions = [ + ( + "can_edit_sensitive_email_site_setting", + "Can edit sensitive email site setting.", + ), + ] + + @register_setting class ImportantPagesSiteSetting(BaseSiteSetting): sign_up_page = models.ForeignKey(