Esempio n. 1
0
    def filter_queryset(self, request, queryset, view):
        if request.GET.get("for_explorer"):
            if not hasattr(queryset, "_filtered_by_child_of"):
                raise BadRequestError(
                    "filtering by for_explorer without child_of is not supported"
                )

            parent_page = queryset._filtered_by_child_of
            for hook in hooks.get_hooks("construct_explorer_page_queryset"):
                queryset = hook(parent_page, queryset, request)

            user_perms = UserPagePermissionsProxy(request.user)
            queryset = user_perms.explorable_pages() & queryset

        return queryset
Esempio n. 2
0
    def test_explorable_pages_with_permission_gap_in_hierarchy(self):
        corporate_editor = get_user_model().objects.get(
            email="*****@*****.**")
        user_perms = UserPagePermissionsProxy(corporate_editor)

        about_us_page = Page.objects.get(url_path="/home/about-us/")
        businessy_events = Page.objects.get(
            url_path="/home/events/businessy-events/")
        events_page = Page.objects.get(url_path="/home/events/")

        explorable_pages = user_perms.explorable_pages()

        self.assertTrue(explorable_pages.filter(id=about_us_page.id).exists())
        self.assertTrue(
            explorable_pages.filter(id=businessy_events.id).exists())
        self.assertTrue(explorable_pages.filter(id=events_page.id).exists())
Esempio n. 3
0
    def test_explorable_pages(self):
        event_editor = get_user_model().objects.get(
            email="*****@*****.**")
        christmas_page = EventPage.objects.get(
            url_path="/home/events/christmas/")
        unpublished_event_page = EventPage.objects.get(
            url_path="/home/events/tentative-unpublished-event/")
        someone_elses_event_page = EventPage.objects.get(
            url_path="/home/events/someone-elses-event/")
        about_us_page = Page.objects.get(url_path="/home/about-us/")

        user_perms = UserPagePermissionsProxy(event_editor)
        explorable_pages = user_perms.explorable_pages()

        # Verify all pages below /home/events/ are explorable
        self.assertTrue(explorable_pages.filter(id=christmas_page.id).exists())
        self.assertTrue(
            explorable_pages.filter(id=unpublished_event_page.id).exists())
        self.assertTrue(
            explorable_pages.filter(id=someone_elses_event_page.id).exists())

        # Verify page outside /events/ tree are not explorable
        self.assertFalse(explorable_pages.filter(id=about_us_page.id).exists())
Esempio n. 4
0
 def get_base_queryset(self, models=None):
     queryset = super().get_base_queryset(models=models)
     user_perms = UserPagePermissionsProxy(self.request.user)
     queryset = queryset & user_perms.explorable_pages()
     return queryset
Esempio n. 5
0
def index(request, parent_page_id=None):
    if parent_page_id:
        parent_page = get_object_or_404(Page, id=parent_page_id)
    else:
        parent_page = Page.get_first_root_node()

    # This will always succeed because of the @user_passes_test above.
    root_page = get_explorable_root_page(request.user)

    # If this page isn't a descendant of the user's explorable root page,
    # then redirect to that explorable root page instead.
    if not (parent_page.pk == root_page.pk
            or parent_page.is_descendant_of(root_page)):
        return redirect("wagtailadmin_explore", root_page.pk)

    parent_page = parent_page.specific

    user_perms = UserPagePermissionsProxy(request.user)
    pages = (parent_page.get_children().prefetch_related(
        "content_type", "sites_rooted_here")
             & user_perms.explorable_pages())

    # Get page ordering
    ordering = request.GET.get("ordering", "-latest_revision_created_at")
    if ordering not in [
            "title",
            "-title",
            "content_type",
            "-content_type",
            "live",
            "-live",
            "latest_revision_created_at",
            "-latest_revision_created_at",
            "ord",
    ]:
        ordering = "-latest_revision_created_at"

    if ordering == "ord":
        # preserve the native ordering from get_children()
        pass
    elif ordering == "latest_revision_created_at":
        # order by oldest revision first.
        # Special case NULL entries - these should go at the top of the list.
        # Do this by annotating with Count('latest_revision_created_at'),
        # which returns 0 for these
        pages = pages.annotate(
            null_position=Count("latest_revision_created_at")).order_by(
                "null_position", "latest_revision_created_at")
    elif ordering == "-latest_revision_created_at":
        # order by oldest revision first.
        # Special case NULL entries - these should go at the end of the list.
        pages = pages.annotate(
            null_position=Count("latest_revision_created_at")).order_by(
                "-null_position", "-latest_revision_created_at")
    else:
        pages = pages.order_by(ordering)

    # Don't paginate if sorting by page order - all pages must be shown to
    # allow drag-and-drop reordering
    do_paginate = ordering != "ord"

    # We want specific page instances, but do not need streamfield values here
    pages = pages.defer_streamfields().specific()

    # allow hooks defer_streamfieldsyset
    for hook in hooks.get_hooks("construct_explorer_page_queryset"):
        pages = hook(parent_page, pages, request)

    # Annotate queryset with various states to be used later for performance optimisations
    if getattr(settings, "WAGTAIL_WORKFLOW_ENABLED", True):
        pages = pages.prefetch_workflow_states()

    pages = pages.annotate_site_root_state().annotate_approved_schedule()

    # Pagination
    if do_paginate:
        paginator = Paginator(pages, per_page=50)
        pages = paginator.get_page(request.GET.get("p"))

    show_ordering_column = request.GET.get("ordering") == "ord"

    context = {
        "parent_page": parent_page.specific,
        "ordering": ordering,
        "pages": pages,
        "do_paginate": do_paginate,
        "locale": None,
        "translations": [],
        "show_ordering_column": show_ordering_column,
        "show_bulk_actions": not show_ordering_column,
        "show_locale_labels": False,
    }

    if getattr(settings, "WAGTAIL_I18N_ENABLED", False):
        if not parent_page.is_root():
            context.update({
                "locale":
                parent_page.locale,
                "translations": [{
                    "locale":
                    translation.locale,
                    "url":
                    reverse("wagtailadmin_explore", args=[translation.id]),
                } for translation in parent_page.get_translations().only(
                    "id", "locale").select_related("locale")],
            })
        else:
            context["show_locale_labels"] = True

    return TemplateResponse(request, "wagtailadmin/pages/index.html", context)