Wagtail filter page-childs-elements on the basis of logged-in user's permissions

℡╲_俬逩灬. 提交于 2020-12-12 06:18:08

问题


I am working on a small site using Wagtail. This site is all about a "mainpage" and several "subpages". So far it is pretty simple! But, depending on what group the user (not admin) is in, the right subpages should show up!

See the following setup (minimized), to get an idea of what I am talking about.

If I set permissions on ToolKitPart (like requiring explicit user-login and group-membership), then the following is happening:

  • when going to the page using the fully qualified path, the user is requested to login and, in the case of insufficient rights, the user will not see the content!

  • when going to the ToolkitIndex-Page, all children are displayed, including the ones the user never should see, without the need to be logged in or being a member of a certain group.

    class ToolkitIndex(Page):
        def get_context(self, request):
            # Update context to include only published posts, ordered by reverse-chron
            context = super().get_context(request)
            blogpages = self.get_children().live().order_by('-first_published_at')
            context['pages'] = blogpages    
            return context
    
    class ToolkitPart(Page):
        body = StreamField([
            ('staff', MpStaff()),
            ('news', MpNews()),
            ('stuff', MpStuff()),
            ('teditor', blocks.RichTextBlock()),
            ('reditor', blocks.RawHTMLBlock()),
        ], blank=True)
    
        content_panels = Page.content_panels + [
            StreamFieldPanel('body'),
        ]
    
    class MpNews(blocks.StructBlock):
        head = blocks.TextBlock(required=True, help_text='Schlagzeile')
        lead = blocks.TextBlock(required=False, help_text='Einleitung')
        body = blocks.RichTextBlock(required=True, help_text='Inhalt')
        image = ImageChooserBlock(required=False)
    
        type = blocks.ChoiceBlock(
            choices=[('default', 'Standard'),
                 ('highlight', 'Hervorgehoben'),
                 ], required=True)
    
        class Meta:
            template = 'home/mparts/toolkit_news.html'
            icon = 'code'
    

Any idea how to solve this?


回答1:


Assuming you've set these permissions up using Wagtail's private pages feature, these are stored in the PageViewRestriction model. Unfortunately Wagtail doesn't currently provide a way to apply these permission checks against anything other than the current page request, so you'd have to recreate this logic yourself to filter a queryset to the user's view permissions. This would be something like (untested):

from django.db.models import Q

class ToolkitIndex(Page):
    def get_context(self, request):
        context = super().get_context(request)
        blogpages = self.get_children().live().order_by('-first_published_at')

        if not request.user.is_authenticated:
            blogpages = blogpages.public()  # only pages with no view restrictions at all

        else:
            blogpages = blogpages.filter(
                # pages with no view restrictions
                Q(view_restrictions__isnull=True)
                # pages restricted to any logged-in user
                | Q(view_restrictions__restriction_type='login')
                # pages restricted by group
                | Q(view_restrictions__restriction_type='groups', view_restrictions__groups__in=request.user.groups.all())
            )

Disclaimers:

  • This doesn't account for pages that are protected by a shared password
  • To be fully correct, we'd need to account for the fact that view restrictions propagate down the tree (and so a subpage may still be restricted even if it doesn't have a view restriction record directly attached to it); however, we're only looking at immediate children of the current page (which they evidently do have access to...) so that issue doesn't come up here.
  • PageViewRestriction is not a public Wagtail API and may change in future releases - in particular, see RFC 32 for a proposed change that may happen in the fairly near future.


来源:https://stackoverflow.com/questions/54629835/wagtail-filter-page-childs-elements-on-the-basis-of-logged-in-users-permissions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!