Repository: wagtail/wagtail

Issue:
Page aliases are not inheriting the source page privacy settings
### Issue Summary

This issue may be related to #6749
When using page aliases (e.g. with wagtail-localize), the source page privacy settings are not reflected on the page aliases. For instance, setting a source page in English to be password-protected will still be accessible in other languages

cc @kaedroho 

### Steps to Reproduce

1. Set up wagtail-localize
2. Add at least one locale to Settings > Locales
3. Set a password to a source page 
4. Open /*your locale*/*your page slug*/, the page is  still public.

* I have confirmed that this issue can be reproduced as described on a fresh Wagtail project: No, but I’ve reproduced locally with a test DB.


### Technical details

* Python version: 3.7.8
* Django version: 2.2.13
* Wagtail version: 2.11.2
* Wagtail-localize version: 0.9.3



Discussion:

Resolving patch:
diff --git a/wagtail/core/models.py b/wagtail/core/models.py
--- a/wagtail/core/models.py
+++ b/wagtail/core/models.py
@@ -2668,8 +2668,32 @@ def get_prev_siblings(self, inclusive=False):
         return self.get_siblings(inclusive).filter(path__lte=self.path).order_by('-path')
 
     def get_view_restrictions(self):
-        """Return a query set of all page view restrictions that apply to this page"""
-        return PageViewRestriction.objects.filter(page__in=self.get_ancestors(inclusive=True))
+        """
+        Return a query set of all page view restrictions that apply to this page.
+
+        This checks the current page and all ancestor pages for page view restrictions.
+
+        If any of those pages are aliases, it will resolve them to their source pages
+        before querying PageViewRestrictions so alias pages use the same view restrictions
+        as their source page and they cannot have their own.
+        """
+        page_ids_to_check = set()
+
+        def add_page_to_check_list(page):
+            # If the page is an alias, add the source page to the check list instead
+            if page.alias_of:
+                add_page_to_check_list(page.alias_of)
+            else:
+                page_ids_to_check.add(page.id)
+
+        # Check current page for view restrictions
+        add_page_to_check_list(self)
+
+        # Check each ancestor for view restrictions as well
+        for page in self.get_ancestors().only('alias_of'):
+            add_page_to_check_list(page)
+
+        return PageViewRestriction.objects.filter(page_id__in=page_ids_to_check)
 
     password_required_template = getattr(settings, 'PASSWORD_REQUIRED_TEMPLATE', 'wagtailcore/password_required.html')
 


Test patch:
diff --git a/wagtail/core/tests/test_page_privacy.py b/wagtail/core/tests/test_page_privacy.py
--- a/wagtail/core/tests/test_page_privacy.py
+++ b/wagtail/core/tests/test_page_privacy.py
@@ -83,6 +83,43 @@ def test_view_restrictions_apply_to_subpages(self):
         response = self.client.get('/secret-plans/steal-underpants/')
         self.assertEqual(response.templates[0].name, 'tests/event_page.html')
 
+    def test_view_restrictions_apply_to_aliases(self):
+        secret_plans_page = Page.objects.get(url_path='/home/secret-plans/')
+        secret_plans_alias_page = secret_plans_page.create_alias(update_slug='alias-secret-plans')
+
+        response = self.client.get('/alias-secret-plans/')
+
+        self.assertEqual(response.templates[0].name, 'wagtailcore/password_required.html')
+
+        submit_url = "/_util/authenticate_with_password/%d/%d/" % (self.view_restriction.id, secret_plans_alias_page.id)
+        self.assertContains(response, '<form action="%s"' % submit_url)
+        self.assertContains(
+            response,
+            '<input id="id_return_url" name="return_url" type="hidden" value="/alias-secret-plans/" />',
+            html=True
+        )
+
+    def test_view_restrictions_apply_to_subpages_of_aliases(self):
+        secret_plans_page = Page.objects.get(url_path='/home/secret-plans/')
+        secret_plans_alias_page = secret_plans_page.create_alias(update_slug='alias-secret-plans')
+
+        underpants_page = Page.objects.get(url_path='/home/secret-plans/steal-underpants/')
+        underpants_alias_page = underpants_page.create_alias(parent=secret_plans_alias_page)
+
+        response = self.client.get('/alias-secret-plans/steal-underpants/')
+
+        # check that we're overriding the default password_required template for this page type
+        self.assertEqual(response.templates[0].name, 'tests/event_page_password_required.html')
+
+        submit_url = "/_util/authenticate_with_password/%d/%d/" % (self.view_restriction.id, underpants_alias_page.id)
+        self.assertContains(response, '<title>Steal underpants</title>')
+        self.assertContains(response, '<form action="%s"' % submit_url)
+        self.assertContains(
+            response,
+            '<input id="id_return_url" name="return_url" type="hidden" value="/alias-secret-plans/steal-underpants/" />',
+            html=True
+        )
+
     def test_group_restriction_with_anonymous_user(self):
         response = self.client.get('/secret-event-editor-plans/')
         self.assertRedirects(response, '/_util/login/?next=/secret-event-editor-plans/')