From 322d7e1620066b9b43a61a6c4b927a649eaf207e Mon Sep 17 00:00:00 2001
From: smark-1 <75799735+smark-1@users.noreply.github.com>
Date: Wed, 27 Nov 2024 17:20:26 -0500
Subject: [PATCH] Add documentation for setting the default privacy option on
 pages

---
 docs/advanced_topics/privacy.md | 34 +++++++++++++++++++++++++++++++++
 docs/reference/models.md        | 32 +++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/docs/advanced_topics/privacy.md b/docs/advanced_topics/privacy.md
index 325b6c74da..fb62469cf7 100644
--- a/docs/advanced_topics/privacy.md
+++ b/docs/advanced_topics/privacy.md
@@ -72,6 +72,40 @@ WAGTAIL_FRONTEND_LOGIN_URL = '/accounts/login/'
 
 To integrate Wagtail into a Django site with an existing login mechanism, setting `WAGTAIL_FRONTEND_LOGIN_URL = LOGIN_URL` will usually be sufficient.
 
+(set_default_page_privacy)=
+
+## Setting the default privacy restriction
+
+You can modify the default privacy restriction of a page by overriding the {meth}`~wagtail.models.Page.get_default_privacy_setting` method for the page. This could be done to make a page type require login by default, but it can also be used for more complex configurations, such as adjusting the default privacy setting based on the user or using an auto-generated shared password.
+
+The method must return a dictionary with at least a `type` key. The value must be one of the following values for {class}`~wagtail.models.PageViewRestriction`'s {attr}`~wagtail.models.PageViewRestriction.restriction_type`:
+
+-   `BaseViewRestriction.NONE` - No restrictions
+-   `BaseViewRestriction.PASSWORD` - Password protected (requires additional `password` key in the dictionary)
+-   `BaseViewRestriction.GROUPS` - Group restricted (requires additional `groups` key with list of Group objects)
+-   `BaseViewRestriction.LOGIN` - Login required
+
+```python
+class BlogPage(Page):
+    #...
+    def get_default_privacy_setting(self, request):
+        # set default to group
+        from django.contrib.auth.models import Group
+        from wagtail.models import BaseViewRestriction
+        moderators = Group.objects.filter(name="Moderators").first()
+        editors = Group.objects.filter(name="Editors").first()
+        return {"type": BaseViewRestriction.GROUPS, "groups": [moderators,editors]}
+
+class SecretPage(Page):
+    #...
+    def get_default_privacy_setting(self, request):
+        # set default to auto-generated password
+        from django.utils.crypto import get_random_string
+        from wagtail.models import BaseViewRestriction
+
+        return {"type": BaseViewRestriction.PASSWORD, "password": django.utils.crypto.get_random_string(length=32)}
+```
+
 ## Setting up a global "password required" page
 
 By setting `WAGTAIL_PASSWORD_REQUIRED_TEMPLATE` in your Django settings file, you can specify the path of a template which will be used for all "password required" forms on the site (except for page types that specifically override it - see below):
diff --git a/docs/reference/models.md b/docs/reference/models.md
index cd852af34b..27d942cb62 100644
--- a/docs/reference/models.md
+++ b/docs/reference/models.md
@@ -190,6 +190,38 @@ See also [django-treebeard](inv:treebeard:std:doc#index)'s [node API](inv:treebe
 
     .. automethod:: find_for_request
 
+    .. method:: get_default_privacy_setting(request)
+
+        Set the default privacy setting for the page.
+
+        The method must return a dictionary with at least a 'type' key. The value must be one of the following values from :class:`~wagtail.models.PageViewRestriction`'s :attr:`~wagtail.models.PageViewRestriction.restriction_type`:
+
+        - ``BaseViewRestriction.NONE``: The page is public and can be accessed by anyone. (default) - '{"type": BaseViewRestriction.NONE}'
+
+        - ``BaseViewRestriction.LOGIN``: The page is private and can only be accessed by authenticated users. - '{"type": BaseViewRestriction.LOGIN}'
+
+        - ``BaseViewRestriction.PASSWORD``: The page is private and can only be accessed by users with a shared password. (requires additional ``password`` key in the dictionary) - '{"type": BaseViewRestriction.PASSWORD, "password": "P@ssw0rd123!"}'
+
+        - ``BaseViewRestriction.GROUPS``: The page is private and can only be accessed by users in specific groups. (requires additional ``groups`` key with list of Group objects) - '{"type": BaseViewRestriction.GROUPS, "groups": [moderators, editors]}'
+
+        Example
+
+        .. code-block:: python
+
+            class BreadsIndexPage(Page):
+                #...
+
+                def get_default_privacy_setting(request):
+                    from wagtail.models import BaseViewRestriction
+                    # if the editor has the foo.add_bar permission set the default to groups with the moderators and editors group checked
+                    if request.user.has_perm("foo.add_bar"):
+                        moderators = Group.objects.filter(name="Moderators").first()
+                        editors = Group.objects.filter(name="Editors").first()
+                        return {"type": BaseViewRestriction.GROUPS, "groups": [moderators,editors]}
+                    else:
+                        return {"type": BaseViewRestriction.NONE}
+
+
     .. autoattribute:: context_object_name
 
         Custom name for page instance in page's ``Context``.