Limit the explorer breadcrumb to the pages the user has explore permission over

Refactor of #3133
pull/3197/head
Matt Westcott 2016-12-01 16:03:00 +00:00
rodzic 2a76a30e7b
commit e953cb36dc
4 zmienionych plików z 105 dodań i 11 usunięć

Wyświetl plik

@ -5,17 +5,22 @@ from django.db.models import Q
from wagtail.wagtailcore.models import Page
def get_navigation_menu_items(user):
def get_pages_with_direct_explore_permission(user):
# Get all pages that the user has direct add/edit/publish/lock permission on
if user.is_superuser:
# superuser has implicit permission on the root node
pages_with_direct_permission = Page.objects.filter(depth=1)
return Page.objects.filter(depth=1)
else:
pages_with_direct_permission = Page.objects.filter(
return Page.objects.filter(
group_permissions__group__in=user.groups.all(),
group_permissions__permission_type__in=['add', 'edit', 'publish', 'lock']
)
def get_navigation_menu_items(user):
# Get all pages that the user has direct add/edit/publish/lock permission on
pages_with_direct_permission = get_pages_with_direct_explore_permission(user)
if not(pages_with_direct_permission):
return []

Wyświetl plik

@ -2,8 +2,9 @@
<ul class="breadcrumb">
{% for page in pages %}
{% if page.is_root %}
<li class="home"><a href="{% url 'wagtailadmin_explore_root' %}" class="icon icon-home text-replace">{% trans 'Home' %}</a></li>
{% if forloop.first %}
{# first item in breadcrumb displays as a 'home' icon in place of the title #}
<li class="home"><a href="{% if page.is_root %}{% url 'wagtailadmin_explore_root' %}{% else %}{% url 'wagtailadmin_explore' page.id %}{% endif %}" class="icon icon-home text-replace">{% trans 'Home' %}</a></li>
{% else %}
<li><a href="{% url 'wagtailadmin_explore' page.id %}">{{ page.get_admin_display_title }}</a></li>
{% endif %}

Wyświetl plik

@ -2,7 +2,6 @@ from __future__ import absolute_import, unicode_literals
import itertools
import django
from django import template
from django.conf import settings
@ -14,10 +13,11 @@ from django.utils.safestring import mark_safe
from wagtail.utils.pagination import DEFAULT_PAGE_KEY, replace_page_in_query
from wagtail.wagtailadmin.menu import admin_menu
from wagtail.wagtailadmin.navigation import get_navigation_menu_items
from wagtail.wagtailadmin.navigation import (
get_navigation_menu_items, get_pages_with_direct_explore_permission)
from wagtail.wagtailadmin.search import admin_search_areas
from wagtail.wagtailcore import hooks
from wagtail.wagtailcore.models import PageViewRestriction, UserPagePermissionsProxy
from wagtail.wagtailcore.models import Page, PageViewRestriction, UserPagePermissionsProxy
from wagtail.wagtailcore.utils import cautious_slugify as _cautious_slugify
from wagtail.wagtailcore.utils import camelcase_to_underscore, escape_script
@ -55,10 +55,21 @@ def main_nav(context):
}
@register.inclusion_tag('wagtailadmin/shared/breadcrumb.html')
def explorer_breadcrumb(page, include_self=False):
@register.inclusion_tag('wagtailadmin/shared/breadcrumb.html', takes_context=True)
def explorer_breadcrumb(context, page, include_self=False):
user = context['request'].user
# find the closest common ancestor of the pages that this user has direct explore permission
# (i.e. add/edit/publish/lock) over; this will be the root of the breadcrumb
try:
cca = get_pages_with_direct_explore_permission(user).first_common_ancestor(
include_self=True, strict=True
)
except Page.DoesNotExist:
return {'pages': Page.objects.none()}
return {
'pages': page.get_ancestors(inclusive=include_self)
'pages': page.get_ancestors(inclusive=include_self).descendant_of(cca, inclusive=True)
}

Wyświetl plik

@ -331,6 +331,83 @@ class TestPageExplorerSignposting(TestCase, WagtailTestUtils):
self.assertNotContains(response, "Pages created here will not be accessible")
class TestExplorablePageVisibility(TestCase, WagtailTestUtils):
"""
Test the way that the Explorable Pages functionality manifests within the Explorer.
This is isolated in its own test case because it requires a custom page tree and custom set of
users and groups.
The fixture sets up this page tree:
========================================================
ID Site Path
========================================================
1 /
2 testserver /home/
3 testserver /home/about-us/
4 example.com /example-home/
5 example.com /example-home/content/
6 example.com /example-home/content/page-1/
7 example.com /example-home/content/page-2/
9 example.com /example-home/content/page-2/child-1
8 example.com /example-home/other-content/
10 example2.com /home-2/
========================================================
Group 1 has explore and choose permissions rooted at testserver's homepage.
Group 2 has explore and choose permissions rooted at example.com's page-1.
Group 3 has explore and choose permissions rooted at example.com's other-content.
User "jane" is in Group 1.
User "bob" is in Group 2.
User "sam" is in Groups 1 and 2.
User "josh" is in Groups 2 and 3.
User "mary" is is no Groups, but she has the "access wagtail admin" permission.
User "superman" is an admin.
"""
fixtures = ['test_explorable_pages.json']
# Integration tests adapted from @coredumperror
def test_admin_can_explore_every_page(self):
self.assertTrue(self.client.login(username='superman', password='password'))
for page in Page.objects.all():
response = self.client.get(reverse('wagtailadmin_explore', args=[page.pk]))
self.assertEqual(response.status_code, 200)
def test_admin_sees_root_page_as_explorer_root(self):
self.assertTrue(self.client.login(username='superman', password='password'))
response = self.client.get(reverse('wagtailadmin_explore_root'))
self.assertEqual(response.status_code, 200)
# Administrator should see the full list of children of the Root page.
self.assertContains(response, "Welcome to testserver!")
self.assertContains(response, "Welcome to example.com!")
def test_admin_sees_breadcrumbs_up_to_root_page(self):
self.assertTrue(self.client.login(username='superman', password='password'))
response = self.client.get(reverse('wagtailadmin_explore', args=[6]))
self.assertEqual(response.status_code, 200)
self.assertInHTML(
"""<li class="home"><a href="/admin/pages/" class="icon icon-home text-replace">Home</a></li>""",
str(response.content)
)
self.assertInHTML("""<li><a href="/admin/pages/4/">Welcome to example.com!</a></li>""", str(response.content))
self.assertInHTML("""<li><a href="/admin/pages/5/">Content</a></li>""", str(response.content))
def test_nonadmin_sees_breadcrumbs_up_to_cca(self):
self.assertTrue(self.client.login(username='josh', password='password'))
response = self.client.get(reverse('wagtailadmin_explore', args=[6]))
self.assertEqual(response.status_code, 200)
# While at "Page 1", Josh should see the breadcrumbs leading only as far back as the example.com homepage,
# since it's his Closest Common Ancestor.
self.assertInHTML(
"""<li class="home"><a href="/admin/pages/4/" class="icon icon-home text-replace">Home</a></li>""",
str(response.content)
)
self.assertInHTML("""<li><a href="/admin/pages/5/">Content</a></li>""", str(response.content))
# The page title shouldn't appear because it's the "home" breadcrumb.
self.assertNotContains(response, "Welcome to example.com!")
class TestPageCreation(TestCase, WagtailTestUtils):
def setUp(self):
# Find root page