Преглед на файлове

Hide titles of items user doesn't have edit permission on

Matt Westcott преди 2 години
родител
ревизия
be72dc5e96

+ 7 - 7
wagtail/documents/templates/wagtaildocs/documents/usage.html

@@ -14,22 +14,22 @@
                 </tr>
             </thead>
             <tbody>
-                {% for object, references in used_by %}
+                {% for label, edit_url, edit_link_title, references in results %}
                     <tr>
                         <td class="title" valign="top">
                             <div class="title-wrapper">
-                                {% if object.edit_url %}<a href="{{ object.edit_url }}" title="{% trans 'Edit this page' %}">{% endif %}
-                                {{ object }}
-                                {% if object.edit_url %}</a>{% endif %}
+                                {% if edit_url %}<a href="{{ edit_url }}" title="{{ edit_link_title }}">{% endif %}
+                                {{ label }}
+                                {% if edit_url %}</a>{% endif %}
                             </div>
                         </td>
                         <td>
                             <ul>
                                 {% for reference in references %}
                                     <li>
-                                        {% if object.edit_url %}<a href="{{ object.edit_url }}#content-path-{{ reference.content_path }}">{% endif %}
+                                        {% if edit_url %}<a href="{{ edit_url }}#content-path-{{ reference.content_path }}">{% endif %}
                                         {{ reference.describe_source_field }}
-                                        {% if object.edit_url %}</a>{% endif %}
+                                        {% if edit_url %}</a>{% endif %}
                                     </li>
                                 {% endfor %}
                             </ul>
@@ -39,5 +39,5 @@
             </tbody>
         </table>
     </div>
-    {% include "wagtailadmin/shared/pagination_nav.html" with items=used_by %}
+    {% include "wagtailadmin/shared/pagination_nav.html" with items=object_page %}
 {% endblock %}

+ 10 - 0
wagtail/documents/tests/test_admin_views.py

@@ -1802,6 +1802,13 @@ class TestGetUsage(TestCase, WagtailTestUtils):
         self.assertRegex(response.content.decode("utf-8"), r"<tbody>(\s|\n)*</tbody>")
 
     def test_usage_page_with_only_change_permission(self):
+        doc = models.Document.objects.get(id=1)
+        page = EventPage.objects.get(id=4)
+        event_page_related_link = EventPageRelatedLink()
+        event_page_related_link.page = page
+        event_page_related_link.link_document = doc
+        event_page_related_link.save()
+
         # Create a user with change_document permission but not add_document
         user = self.create_user(
             username="changeonly", email="changeonly@example.com", password="password"
@@ -1826,6 +1833,9 @@ class TestGetUsage(TestCase, WagtailTestUtils):
         response = self.client.get(reverse("wagtaildocs:document_usage", args=[1]))
 
         self.assertEqual(response.status_code, 200)
+        # User has no permission over the page linked to, so should not see its details
+        self.assertNotContains(response, "Christmas")
+        self.assertContains(response, "(Private page)")
 
     def test_usage_page_without_change_permission(self):
         # Create a user with add_document permission but not change_document

+ 12 - 4
wagtail/documents/views/documents.py

@@ -271,15 +271,23 @@ def usage(request, document_id):
         raise PermissionDenied
 
     paginator = Paginator(doc.get_usage(), per_page=20)
-    used_by = paginator.get_page(request.GET.get("p"))
+    object_page = paginator.get_page(request.GET.get("p"))
 
     # Add edit URLs to each source object
     url_finder = AdminURLFinder(request.user)
-    for object, references in used_by:
-        object.edit_url = url_finder.get_edit_url(object)
+    results = []
+    for object, references in object_page:
+        edit_url = url_finder.get_edit_url(object)
+        if edit_url is None:
+            label = _("(Private %s)") % object._meta.verbose_name
+            edit_link_title = None
+        else:
+            label = str(object)
+            edit_link_title = _("Edit this %s") % object._meta.verbose_name
+        results.append((label, edit_url, edit_link_title, references))
 
     return TemplateResponse(
         request,
         "wagtaildocs/documents/usage.html",
-        {"document": doc, "used_by": used_by},
+        {"document": doc, "results": results, "object_page": object_page},
     )

+ 7 - 7
wagtail/images/templates/wagtailimages/images/usage.html

@@ -14,22 +14,22 @@
                 </tr>
             </thead>
             <tbody>
-                {% for object, references in used_by %}
+                {% for label, edit_url, edit_link_title, references in results %}
                     <tr>
                         <td class="title" valign="top">
                             <div class="title-wrapper">
-                                {% if object.edit_url %}<a href="{{ object.edit_url }}" title="{% trans 'Edit this page' %}">{% endif %}
-                                {{ object }}
-                                {% if object.edit_url %}</a>{% endif %}
+                                {% if edit_url %}<a href="{{ edit_url }}" title="{{ edit_link_title }}">{% endif %}
+                                {{ label }}
+                                {% if edit_url %}</a>{% endif %}
                             </div>
                         </td>
                         <td>
                             <ul>
                                 {% for reference in references %}
                                     <li>
-                                        {% if object.edit_url %}<a href="{{ object.edit_url }}#content-path-{{ reference.content_path }}">{% endif %}
+                                        {% if edit_url %}<a href="{{ edit_url }}#content-path-{{ reference.content_path }}">{% endif %}
                                         {{ reference.describe_source_field }}
-                                        {% if object.edit_url %}</a>{% endif %}
+                                        {% if edit_url %}</a>{% endif %}
                                     </li>
                                 {% endfor %}
                             </ul>
@@ -39,5 +39,5 @@
             </tbody>
         </table>
     </div>
-    {% include "wagtailadmin/shared/pagination_nav.html" with items=used_by %}
+    {% include "wagtailadmin/shared/pagination_nav.html" with items=object_page %}
 {% endblock %}

+ 16 - 0
wagtail/images/tests/test_admin_views.py

@@ -1169,6 +1169,19 @@ class TestUsage(TestCase, WagtailTestUtils):
         self.assertRegex(response.content.decode("utf-8"), r"<tbody>(\s|\n)*</tbody>")
 
     def test_usage_page_with_only_change_permission(self):
+        home_page = Page.objects.get(id=2)
+        home_page.add_child(
+            instance=EventPage(
+                title="Christmas",
+                slug="christmas",
+                feed_image=self.image,
+                date_from=datetime.date.today(),
+                audience="private",
+                location="Test",
+                cost="Test",
+            )
+        ).save_revision().publish()
+
         # Create a user with change_image permission but not add_image
         user = self.create_user(
             username="changeonly", email="changeonly@example.com", password="password"
@@ -1195,6 +1208,9 @@ class TestUsage(TestCase, WagtailTestUtils):
         )
 
         self.assertEqual(response.status_code, 200)
+        # User has no permission over the page linked to, so should not see its details
+        self.assertNotContains(response, "Christmas")
+        self.assertContains(response, "(Private page)")
 
     def test_usage_page_without_change_permission(self):
         # Create a user with add_image permission but not change_image

+ 14 - 4
wagtail/images/views/images.py

@@ -407,13 +407,23 @@ def usage(request, image_id):
         raise PermissionDenied
 
     paginator = Paginator(image.get_usage(), per_page=USAGE_PAGE_SIZE)
-    used_by = paginator.get_page(request.GET.get("p"))
+    object_page = paginator.get_page(request.GET.get("p"))
 
     # Add edit URLs to each source object
     url_finder = AdminURLFinder(request.user)
-    for object, references in used_by:
-        object.edit_url = url_finder.get_edit_url(object)
+    results = []
+    for object, references in object_page:
+        edit_url = url_finder.get_edit_url(object)
+        if edit_url is None:
+            label = _("(Private %s)") % object._meta.verbose_name
+            edit_link_title = None
+        else:
+            label = str(object)
+            edit_link_title = _("Edit this %s") % object._meta.verbose_name
+        results.append((label, edit_url, edit_link_title, references))
 
     return TemplateResponse(
-        request, "wagtailimages/images/usage.html", {"image": image, "used_by": used_by}
+        request,
+        "wagtailimages/images/usage.html",
+        {"image": image, "results": results, "object_page": object_page},
     )

+ 7 - 7
wagtail/snippets/templates/wagtailsnippets/snippets/usage.html

@@ -18,22 +18,22 @@
                 </tr>
             </thead>
             <tbody>
-                {% for object, references in used_by %}
+                {% for label, edit_url, edit_link_title, references in results %}
                     <tr>
                         <td class="title" valign="top">
                             <div class="title-wrapper">
-                                {% if object.edit_url %}<a href="{{ object.edit_url }}" title="{% trans 'Edit this page' %}">{% endif %}
-                                {{ object }}
-                                {% if object.edit_url %}</a>{% endif %}
+                                {% if edit_url %}<a href="{{ edit_url }}" title="{{ edit_link_title }}">{% endif %}
+                                {{ label }}
+                                {% if edit_url %}</a>{% endif %}
                             </div>
                         </td>
                         <td>
                             <ul>
                                 {% for reference in references %}
                                     <li>
-                                        {% if object.edit_url %}<a href="{{ object.edit_url }}#content-path-{{ reference.content_path }}">{% endif %}
+                                        {% if edit_url %}<a href="{{ edit_url }}#content-path-{{ reference.content_path }}">{% endif %}
                                         {{ reference.describe_source_field }}
-                                        {% if object.edit_url %}</a>{% endif %}
+                                        {% if edit_url %}</a>{% endif %}
                                     </li>
                                 {% endfor %}
                             </ul>
@@ -43,5 +43,5 @@
             </tbody>
         </table>
     </div>
-    {% include "wagtailadmin/shared/pagination_nav.html" with items=used_by %}
+    {% include "wagtailadmin/shared/pagination_nav.html" with items=page_obj %}
 {% endblock %}

+ 63 - 0
wagtail/snippets/tests/test_snippets.py

@@ -3076,6 +3076,8 @@ class TestUsedBy(TestCase):
 
 
 class TestSnippetUsageView(TestCase, WagtailTestUtils):
+    fixtures = ["test.json"]
+
     def setUp(self):
         self.user = self.login()
 
@@ -3098,6 +3100,67 @@ class TestSnippetUsageView(TestCase, WagtailTestUtils):
             '<span class="w-header__subtitle">Draft-enabled Bar, In Draft</span>',
         )
 
+    def test_usage(self):
+        # resave so that usage count gets updated
+        page = Page.objects.get(pk=2)
+        page.save()
+
+        response = self.client.get(
+            reverse(
+                "wagtailsnippets_tests_advert:usage",
+                args=["1"],
+            )
+        )
+        self.assertContains(response, "Welcome to the Wagtail test site!")
+
+    def test_usage_without_edit_permission_on_snippet(self):
+        # Create a user with basic admin backend access
+        user = self.create_user(
+            username="basicadmin", email="basicadmin@example.com", password="password"
+        )
+        admin_permission = Permission.objects.get(
+            content_type__app_label="wagtailadmin", codename="access_admin"
+        )
+        user.user_permissions.add(admin_permission)
+        self.login(username="basicadmin", password="password")
+
+        response = self.client.get(
+            reverse(
+                "wagtailsnippets_tests_advert:usage",
+                args=["1"],
+            )
+        )
+        self.assertEqual(response.status_code, 302)
+
+    def test_usage_without_edit_permission_on_page(self):
+        # resave so that usage count gets updated
+        page = Page.objects.get(pk=2)
+        page.save()
+
+        # Create a user with edit access to snippets but not pages
+        user = self.create_user(
+            username="basicadmin", email="basicadmin@example.com", password="password"
+        )
+        admin_permission = Permission.objects.get(
+            content_type__app_label="wagtailadmin", codename="access_admin"
+        )
+        advert_permission = Permission.objects.get(
+            content_type__app_label="tests", codename="change_advert"
+        )
+        user.user_permissions.add(admin_permission)
+        user.user_permissions.add(advert_permission)
+        self.login(username="basicadmin", password="password")
+
+        response = self.client.get(
+            reverse(
+                "wagtailsnippets_tests_advert:usage",
+                args=["1"],
+            )
+        )
+        self.assertEqual(response.status_code, 200)
+        self.assertNotContains(response, "Welcome to the Wagtail test site!")
+        self.assertContains(response, "(Private page)")
+
 
 class TestSnippetHistory(TestCase, WagtailTestUtils):
     fixtures = ["test.json"]

+ 15 - 1
wagtail/snippets/views/snippets.py

@@ -583,10 +583,24 @@ class UsageView(generic.IndexView):
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
+
+        # Add edit URLs to each source object
+        url_finder = AdminURLFinder(self.request.user)
+        results = []
+        for object, references in context.get("page_obj"):
+            edit_url = url_finder.get_edit_url(object)
+            if edit_url is None:
+                label = _("(Private %s)") % object._meta.verbose_name
+                edit_link_title = None
+            else:
+                label = str(object)
+                edit_link_title = _("Edit this %s") % object._meta.verbose_name
+            results.append((label, edit_url, edit_link_title, references))
+
         context.update(
             {
                 "object": self.object,
-                "used_by": context.get("page_obj"),
+                "results": results,
                 "model_opts": self.model._meta,
             }
         )