kopia lustrzana https://github.com/wagtail/wagtail
Allow page to change private page options
rodzic
2d568dd825
commit
95eac5ab78
|
@ -24,6 +24,7 @@ Changelog
|
|||
* Support customizations to `UserViewSet` via the app config (Sage Abdullah)
|
||||
* Add word count and reading time metrics within the page editor (Albina Starykova. Sponsored by The Motley Fool)
|
||||
* Implement a new design for accessibility checks (Albina Starykova)
|
||||
* Allow changing available privacy options per page model (Shlomo Markowitz)
|
||||
* Fix: Make `WAGTAILIMAGES_CHOOSER_PAGE_SIZE` setting functional again (Rohit Sharma)
|
||||
* Fix: Enable `richtext` template tag to convert lazy translation values (Benjamin Bach)
|
||||
* Fix: Ensure permission labels on group permissions page are translated where available (Matt Westcott)
|
||||
|
|
|
@ -325,6 +325,33 @@ See also [django-treebeard](https://django-treebeard.readthedocs.io/en/latest/in
|
|||
|
||||
Controls the maximum number of pages of this type that can be created under any one parent page.
|
||||
|
||||
.. attribute:: private_page_options
|
||||
|
||||
Controls what privacy options are available for the page type.
|
||||
|
||||
The following options are available:
|
||||
|
||||
- ``'password'`` - Can restrict to use a shared password
|
||||
- ``'groups'`` - Can restrict to users in specific groups
|
||||
- ``'login'`` - Can restrict to logged in users
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class BreadPage(Page):
|
||||
...
|
||||
|
||||
# default
|
||||
private_page_options = ['password', 'groups', 'login']
|
||||
|
||||
# disable shared password
|
||||
private_page_options = ['groups', 'login']
|
||||
|
||||
# only shared password
|
||||
private_page_options = ['password']
|
||||
|
||||
# no privacy options for this page model
|
||||
private_page_options = []
|
||||
|
||||
.. attribute:: exclude_fields_in_copy
|
||||
|
||||
An array of field names that will not be included when a Page is copied.
|
||||
|
|
|
@ -44,6 +44,7 @@ This feature was developed by Albina Starykova and sponsored by The Motley Fool.
|
|||
* Make `routable_resolver_match` attribute available on RoutablePageMixin responses (Andy Chosak)
|
||||
* Support customizations to `UserViewSet` via the app config (Sage Abdullah)
|
||||
* Implement a new design for accessibility checks (Albina Starykova, sponsored by The Motley Fool)
|
||||
* Allow changing available privacy options per page model (Shlomo Markowitz)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
|
|
|
@ -125,6 +125,9 @@ class CopyForm(forms.Form):
|
|||
|
||||
class PageViewRestrictionForm(BaseViewRestrictionForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
# get the list of private page options from the page
|
||||
private_page_options = kwargs.pop("private_page_options", [])
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
if not getattr(settings, "WAGTAIL_PRIVATE_PAGE_OPTIONS", {}).get(
|
||||
|
@ -136,6 +139,13 @@ class PageViewRestrictionForm(BaseViewRestrictionForm):
|
|||
if choice[0] != PageViewRestriction.PASSWORD
|
||||
]
|
||||
del self.fields["password"]
|
||||
# Remove the fields that are not allowed for the page
|
||||
self.fields["restriction_type"].choices = [
|
||||
choice
|
||||
for choice in self.fields["restriction_type"].choices
|
||||
if choice[0] in private_page_options
|
||||
or choice[0] == PageViewRestriction.NONE
|
||||
]
|
||||
|
||||
class Meta:
|
||||
model = PageViewRestriction
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
{% load i18n %}
|
||||
<p>{% trans "Changing the privacy for this page has been disabled." %}</p>
|
|
@ -544,3 +544,68 @@ class TestPrivacyIndicators(WagtailTestUtils, TestCase):
|
|||
self.assertContains(
|
||||
response, '<div class="w-hidden" data-privacy-sidebar-public>'
|
||||
)
|
||||
|
||||
def test_private_page_options_only_password_groups(self):
|
||||
# change the private_page_options to password and login
|
||||
original_private_page_options = self.public_page.private_page_options
|
||||
self.public_page.specific.__class__.private_page_options = [
|
||||
"password",
|
||||
"groups",
|
||||
]
|
||||
|
||||
response = self.client.get(
|
||||
reverse("wagtailadmin_pages:set_privacy", args=(self.public_page.id,))
|
||||
)
|
||||
|
||||
restriction_types = [
|
||||
choice[0]
|
||||
for choice in response.context["form"].fields["restriction_type"].choices
|
||||
]
|
||||
|
||||
# Check response
|
||||
self.assertListEqual(restriction_types, ["none", "password", "groups"])
|
||||
|
||||
# Reset the private_page_options to previous value
|
||||
self.public_page.specific.__class__.private_page_options = (
|
||||
original_private_page_options
|
||||
)
|
||||
|
||||
def test_private_page_options_only_password_login(self):
|
||||
# change the private_page_options to password and login
|
||||
original_private_page_options = self.public_page.private_page_options
|
||||
self.public_page.specific.__class__.private_page_options = ["password", "login"]
|
||||
|
||||
response = self.client.get(
|
||||
reverse("wagtailadmin_pages:set_privacy", args=(self.public_page.id,))
|
||||
)
|
||||
|
||||
restriction_types = [
|
||||
choice[0]
|
||||
for choice in response.context["form"].fields["restriction_type"].choices
|
||||
]
|
||||
|
||||
# Check response
|
||||
self.assertListEqual(restriction_types, ["none", "password", "login"])
|
||||
|
||||
# Reset the private_page_options to previous value
|
||||
self.public_page.specific.__class__.private_page_options = (
|
||||
original_private_page_options
|
||||
)
|
||||
|
||||
def test_private_page_no_options(self):
|
||||
# change the private_page_options to empty list
|
||||
original_private_page_options = self.public_page.private_page_options
|
||||
self.public_page.specific.__class__.private_page_options = []
|
||||
|
||||
response = self.client.get(
|
||||
reverse("wagtailadmin_pages:set_privacy", args=(self.public_page.id,))
|
||||
)
|
||||
|
||||
# Check response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, "wagtailadmin/page_privacy/no_privacy.html")
|
||||
|
||||
# Reset the private_page_options to previous value
|
||||
self.public_page.specific.__class__.private_page_options = (
|
||||
original_private_page_options
|
||||
)
|
||||
|
|
|
@ -7,7 +7,7 @@ from wagtail.models import Page, PageViewRestriction
|
|||
|
||||
|
||||
def set_privacy(request, page_id):
|
||||
page = get_object_or_404(Page, id=page_id)
|
||||
page = get_object_or_404(Page, id=page_id).specific_deferred
|
||||
page_perms = page.permissions_for_user(request.user)
|
||||
if not page_perms.can_set_view_restrictions():
|
||||
raise PermissionDenied
|
||||
|
@ -16,13 +16,17 @@ def set_privacy(request, page_id):
|
|||
restrictions = page.get_view_restrictions().order_by("page__depth")
|
||||
if restrictions:
|
||||
restriction = restrictions[0]
|
||||
restriction_exists_on_ancestor = restriction.page != page
|
||||
restriction_exists_on_ancestor = restriction.page.id != page.id
|
||||
else:
|
||||
restriction = None
|
||||
restriction_exists_on_ancestor = False
|
||||
|
||||
if request.method == "POST":
|
||||
form = PageViewRestrictionForm(request.POST, instance=restriction)
|
||||
form = PageViewRestrictionForm(
|
||||
request.POST,
|
||||
instance=restriction,
|
||||
private_page_options=page.private_page_options,
|
||||
)
|
||||
if form.is_valid() and not restriction_exists_on_ancestor:
|
||||
if form.cleaned_data["restriction_type"] == PageViewRestriction.NONE:
|
||||
# remove any existing restriction
|
||||
|
@ -49,10 +53,15 @@ def set_privacy(request, page_id):
|
|||
else: # request is a GET
|
||||
if not restriction_exists_on_ancestor:
|
||||
if restriction:
|
||||
form = PageViewRestrictionForm(instance=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"})
|
||||
form = PageViewRestrictionForm(
|
||||
initial={"restriction_type": "none"},
|
||||
private_page_options=page.private_page_options,
|
||||
)
|
||||
|
||||
if restriction_exists_on_ancestor:
|
||||
# display a message indicating that there is a restriction at ancestor level -
|
||||
|
@ -65,6 +74,12 @@ def set_privacy(request, page_id):
|
|||
"page_with_restriction": restriction.page,
|
||||
},
|
||||
)
|
||||
elif 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(
|
||||
|
|
|
@ -1291,6 +1291,9 @@ class Page(AbstractPage, index.Indexed, ClusterableModel, metaclass=PageBase):
|
|||
promote_panels = []
|
||||
settings_panels = []
|
||||
|
||||
# Privacy options for page
|
||||
private_page_options = ["password", "groups", "login"]
|
||||
|
||||
@staticmethod
|
||||
def route_for_request(request: "HttpRequest", path: str) -> RouteResult | None:
|
||||
"""
|
||||
|
|
Ładowanie…
Reference in New Issue