0
0
mirror of https://github.com/wagtail/wagtail.git synced 2024-11-29 01:22:07 +01:00

Fix child restriction admin form when ancestors page view restrictions exists (#12124)

Fixes #4277
This commit is contained in:
Bojan Mihelac 2024-07-15 13:55:54 +02:00 committed by Matt Westcott
parent 93f8600c31
commit 83a390661f
5 changed files with 61 additions and 52 deletions

View File

@ -29,6 +29,7 @@ Changelog
* Secondary form actions such as "Delete" are now in the header actions menu (Sage Abdullah)
* Add support for uploading HEIC / HEIF images (Matt Westcott)
* Allow customization of preview device sizes in the live preview panel (Bart Cieliński, alexkiro, Sage Abdullah)
* Allow setting page privacy rules when a restriction already exists on an ancestor page (Bojan Mihelac)
* Fix: Prevent page type business rules from blocking reordering of pages (Andy Babic, Sage Abdullah)
* Fix: Improve layout of object permissions table (Sage Abdullah)
* Fix: Fix typo in aria-label attribute of page explorer navigation link (Sébastien Corbin)

View File

@ -76,6 +76,7 @@ This feature was developed by Bart Cieliński, alexkiro, and Sage Abdullah.
* Add support for specifying different preview modes to the "View draft" URL for pages (Robin Varghese)
* Implement new designs for the footer actions dropdown with more contrast and larger text (Sage Abdullah)
* `StaticBlock` now renders nothing by default when no template is specified (Sævar Öfjörð Magnússon)
* Allow setting page privacy rules when a restriction already exists on an ancestor page (Bojan Mihelac)
### Bug fixes

View File

@ -1,3 +0,0 @@
{% load i18n %}
<p>{% trans "This page has been made private by a parent page." %}</p>
<p>{% trans "You can edit the privacy settings on:" %} <a href="{% url 'wagtailadmin_pages:edit' page_with_restriction.id %}">{{ page_with_restriction.specific_deferred.get_admin_display_title }}</a></p>

View File

@ -1,5 +1,3 @@
import json
from django.contrib.auth.models import Group
from django.test import TestCase, override_settings
from django.urls import reverse
@ -116,27 +114,15 @@ class TestSetPrivacyView(WagtailTestUtils, TestCase):
# Check response
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(
response, "wagtailadmin/page_privacy/ancestor_privacy.html"
)
self.assertContains(
response, "This page has been made private by a parent page."
)
self.assertEqual(
response.context["page_with_restriction"].specific, self.private_page
)
# Should render without any heading, as the dialog already has a heading
soup = self.get_soup(json.loads(response.content)["html"])
self.assertIsNone(soup.select_one("header"))
self.assertIsNone(soup.select_one("h1"))
# Should link to the edit page for the collection with the restriction
link = soup.select_one("a")
parent_edit_url = reverse(
"wagtailadmin_pages:edit",
args=(self.private_page.pk,),
)
self.assertEqual(link.get("href"), parent_edit_url)
html = response.json()["html"]
self.assertIn(
f'<span>Privacy is inherited from the ancestor page - <a href="{parent_edit_url }">Private page (simple page)</a></span>',
html,
)
def test_set_password_restriction(self):
"""

View File

@ -1,9 +1,14 @@
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
from wagtail.admin.forms.pages import PageViewRestrictionForm
from wagtail.admin.modal_workflow import render_modal_workflow
from wagtail.models import Page, PageViewRestriction
from wagtail.models.view_restrictions import BaseViewRestriction
def set_privacy(request, page_id):
@ -12,14 +17,20 @@ def set_privacy(request, page_id):
if not page_perms.can_set_view_restrictions():
raise PermissionDenied
# fetch restriction records in depth order so that ancestors appear first
restrictions = page.get_view_restrictions().order_by("page__depth")
restrictions = page.get_view_restrictions().order_by("-page__depth")
if restrictions:
restriction = restrictions[0]
restriction_exists_on_ancestor = restriction.page.id != page.id
if restrictions[0].page.id == page.id:
restriction = restrictions[0]
if len(restrictions) > 1:
restriction_on_ancestor = restrictions[1]
else:
restriction_on_ancestor = None
else:
restriction = None
restriction_on_ancestor = restrictions[0]
else:
restriction = None
restriction_exists_on_ancestor = False
restriction_on_ancestor = None
if request.method == "POST":
form = PageViewRestrictionForm(
@ -27,7 +38,7 @@ def set_privacy(request, page_id):
instance=restriction,
private_page_options=page.private_page_options,
)
if form.is_valid() and not restriction_exists_on_ancestor:
if form.is_valid():
if form.cleaned_data["restriction_type"] == PageViewRestriction.NONE:
# remove any existing restriction
if restriction:
@ -51,37 +62,50 @@ def set_privacy(request, page_id):
)
else: # request is a GET
if not restriction_exists_on_ancestor:
if restriction:
form = PageViewRestrictionForm(
instance=restriction, private_page_options=page.private_page_options
)
else:
# no current view restrictions on this page
form = PageViewRestrictionForm(
initial={"restriction_type": "none"},
private_page_options=page.private_page_options,
)
if restriction:
form = PageViewRestrictionForm(
instance=restriction,
private_page_options=page.private_page_options,
)
if restriction_exists_on_ancestor:
# display a message indicating that there is a restriction at ancestor level -
# do not provide the form for setting up new restrictions
return render_modal_workflow(
request,
"wagtailadmin/page_privacy/ancestor_privacy.html",
None,
{
"page_with_restriction": restriction.page,
},
)
elif len(page.private_page_options) == 0:
else:
# no current view restrictions on this page
form = PageViewRestrictionForm(
initial={"restriction_type": "none"},
private_page_options=page.private_page_options,
)
if restriction_on_ancestor:
ancestor_page_link = format_html(
'<a href="{url}">{title}</a>',
url=reverse(
"wagtailadmin_pages:edit", args=[restriction_on_ancestor.page_id]
),
title=restriction_on_ancestor.page.specific_deferred.get_admin_display_title(),
)
inherit_from_parent_choice = (
BaseViewRestriction.NONE,
format_html(
"<span>{}</span>",
mark_safe(
_(
"Privacy is inherited from the ancestor page - %(ancestor_page)s"
)
% {"ancestor_page": ancestor_page_link}
),
),
)
form.fields["restriction_type"].choices = [
inherit_from_parent_choice
] + list(form.fields["restriction_type"].choices[1:])
if len(page.private_page_options) == 0:
return render_modal_workflow(
request,
"wagtailadmin/page_privacy/no_privacy.html",
None,
)
else:
# no restriction set at ancestor level - can set restrictions here
return render_modal_workflow(
request,
"wagtailadmin/page_privacy/set_privacy.html",