From 8654aadb6380f2a86db04097a7bd08f6acb13817 Mon Sep 17 00:00:00 2001 From: smark-1 <75799735+smark-1@users.noreply.github.com> Date: Mon, 2 Sep 2024 14:38:33 -0400 Subject: [PATCH] Add method to set a default privacy option on Page models Fixes #3708 --- wagtail/admin/tests/pages/test_create_page.py | 122 ++++++++++++++++++ wagtail/admin/views/pages/create.py | 48 ++++++- wagtail/models/pages.py | 4 + 3 files changed, 173 insertions(+), 1 deletion(-) diff --git a/wagtail/admin/tests/pages/test_create_page.py b/wagtail/admin/tests/pages/test_create_page.py index 6bf874e868..5d73077a9f 100644 --- a/wagtail/admin/tests/pages/test_create_page.py +++ b/wagtail/admin/tests/pages/test_create_page.py @@ -783,6 +783,128 @@ class TestPageCreation(WagtailTestUtils, TestCase): # form should be marked as having unsaved changes for the purposes of the dirty-forms warning self.assertContains(response, 'data-w-unsaved-force-value="true"') + def test_create_default_privacy_page_public(self): + post_data = { + "title": "New page!", + "content": "Some content", + "slug": "hello-world", + "action-publish": "Publish", + } + + self.client.post( + reverse( + "wagtailadmin_pages:add", + args=("tests", "simplepage", self.root_page.id), + ), + post_data, + ) + + # Find the page and check it + page = self.root_page.get_children().filter(slug="hello-world").first() + + self.assertEqual(PageViewRestriction.objects.filter(page=page).count(), 0) + + @mock.patch("wagtail.test.testapp.models.SimplePage.get_default_privacy_setting") + def test_create_default_privacy_page_logged_in( + self, mock_get_default_privacy_setting + ): + mock_get_default_privacy_setting.return_value = {"type": "login"} + + post_data = { + "title": "New page!", + "content": "Some content", + "slug": "hello-world", + "action-publish": "Publish", + } + + self.client.post( + reverse( + "wagtailadmin_pages:add", + args=("tests", "simplepage", self.root_page.id), + ), + post_data, + ) + + # Find the page and check it + page = Page.objects.get( + path__startswith=self.root_page.path, slug="hello-world" + ).specific + + self.assertEqual( + PageViewRestriction.objects.filter( + page=page, restriction_type="login" + ).count(), + 1, + ) + + @mock.patch("wagtail.test.testapp.models.SimplePage.get_default_privacy_setting") + def test_create_default_privacy_page_shared_password( + self, mock_get_default_privacy_setting + ): + mock_get_default_privacy_setting.return_value = { + "type": "password", + "password": "password", + } + post_data = { + "title": "New page!", + "content": "Some content", + "slug": "hello-world", + "action-publish": "Publish", + } + + self.client.post( + reverse( + "wagtailadmin_pages:add", + args=("tests", "simplepage", self.root_page.id), + ), + post_data, + ) + + # Find the page and check it + page = Page.objects.get( + path__startswith=self.root_page.path, slug="hello-world" + ).specific + + self.assertEqual( + PageViewRestriction.objects.filter( + page=page, restriction_type="password" + ).count(), + 1, + ) + + @mock.patch("wagtail.test.testapp.models.SimplePage.get_default_privacy_setting") + def test_create_default_privacy_page_user_groups( + self, mock_get_default_privacy_setting + ): + mock_get_default_privacy_setting.return_value = {"type": "groups", "groups": []} + + post_data = { + "title": "New page!", + "content": "Some content", + "slug": "hello-world", + "action-publish": "Publish", + } + + self.client.post( + reverse( + "wagtailadmin_pages:add", + args=("tests", "simplepage", self.root_page.id), + ), + post_data, + ) + + # Find the page and check it + page = Page.objects.get( + path__startswith=self.root_page.path, slug="hello-world" + ).specific + + self.assertEqual( + PageViewRestriction.objects.filter( + page=page, restriction_type="groups" + ).count(), + 1, + ) + def test_create_nonexistantparent(self): response = self.client.get( reverse("wagtailadmin_pages:add", args=("tests", "simplepage", 100000)) diff --git a/wagtail/admin/views/pages/create.py b/wagtail/admin/views/pages/create.py index c378ad1faa..8bbc99fe45 100644 --- a/wagtail/admin/views/pages/create.py +++ b/wagtail/admin/views/pages/create.py @@ -24,7 +24,13 @@ from wagtail.admin.ui.side_panels import ( from wagtail.admin.utils import get_valid_next_url_from_request from wagtail.admin.views.generic import HookResponseMixin from wagtail.admin.views.generic.base import WagtailAdminTemplateMixin -from wagtail.models import Locale, Page, PageSubscription +from wagtail.models import ( + BaseViewRestriction, + Locale, + Page, + PageSubscription, + PageViewRestriction, +) def add_subpage(request, parent_page_id): @@ -182,6 +188,37 @@ class CreateView(WagtailAdminTemplateMixin, HookResponseMixin, View): def get_view_live_message_button(self): return messages.button(self.page.url, _("View live"), new_window=False) + def set_default_privacy_setting(self): + # privacy setting options BaseViewRestriction.RESTRICTION_CHOICES + default_privacy_setting = self.page.get_default_privacy_setting(self.request) + + if default_privacy_setting["type"] == BaseViewRestriction.NONE: + # default privacy setting is public no need to do anything + pass + elif default_privacy_setting["type"] == BaseViewRestriction.LOGIN: + PageViewRestriction.objects.create( + page=self.page, + restriction_type=BaseViewRestriction.LOGIN, + ) + elif default_privacy_setting["type"] == BaseViewRestriction.PASSWORD: + PageViewRestriction.objects.create( + page=self.page, + restriction_type=BaseViewRestriction.PASSWORD, + password=default_privacy_setting["password"], + ) + elif default_privacy_setting["type"] == BaseViewRestriction.GROUPS: + # Create a page view restriction for groups + groups_page_restriction = PageViewRestriction.objects.create( + page=self.page, + restriction_type=BaseViewRestriction.GROUPS, + ) + # add groups to the page view restriction + groups_page_restriction.groups.set(default_privacy_setting["groups"]) + else: + raise ValueError( + f"Invalid privacy setting {default_privacy_setting.get('type')!r}" + ) + def save_action(self): self.page = self.form.save(commit=False) self.page.live = False @@ -189,6 +226,9 @@ class CreateView(WagtailAdminTemplateMixin, HookResponseMixin, View): # Save page self.parent_page.add_child(instance=self.page) + # Set page privacy setting + self.set_default_privacy_setting() + # Save revision self.page.save_revision(user=self.request.user, log_action=True) @@ -216,6 +256,9 @@ class CreateView(WagtailAdminTemplateMixin, HookResponseMixin, View): # Save page self.parent_page.add_child(instance=self.page) + # Set page privacy setting + self.set_default_privacy_setting() + # Save revision revision = self.page.save_revision(user=self.request.user, log_action=True) @@ -270,6 +313,9 @@ class CreateView(WagtailAdminTemplateMixin, HookResponseMixin, View): # Save page self.parent_page.add_child(instance=self.page) + # Set page privacy setting + self.set_default_privacy_setting() + # Save revision self.page.save_revision(user=self.request.user, log_action=True) diff --git a/wagtail/models/pages.py b/wagtail/models/pages.py index 3d123a4cc5..efd938fb85 100644 --- a/wagtail/models/pages.py +++ b/wagtail/models/pages.py @@ -1429,6 +1429,10 @@ class Page(AbstractPage, index.Indexed, ClusterableModel, metaclass=PageBase): except self.specific_class.DoesNotExist: return None + def get_default_privacy_setting(self, request: HttpRequest): + """Set the default privacy setting for a page.""" + return {"type": BaseViewRestriction.NONE} + @classmethod def clean_subpage_models(cls): """