django 如何在Wagtail中对子页面应用更高的权限?

kulphzqa  于 2023-02-05  发布在  Go
关注(0)|答案(2)|浏览(129)

我正在使用Wagtail为我的组织构建一个Intranet站点,我们正在添加知识库。整个站点需要限制为登录用户访问,但某些页需要仅允许某些组中的用户访问。例如,只有IT组的成员才能访问“IT知识库”页下的页。
目前,如果我将顶级页面设置为只有登录用户才能访问,则该权限将应用于网站上的每个页面,并且禁止我在任何子页面上设置更具体的权限。我必须能够在子页面上设置更具体的权限。
我能够找到Wagtail Bug #4277,这似乎表明实现了更具体的权限逻辑,但没有在管理UI中公开。
我还不熟悉Wagtail的内部工作机制,尤其是Wagtail权限和Django权限的交叉。我怎样才能为子页面添加更具体的权限?

i2loujxw

i2loujxw1#

您可以限制或允许用户查看站点。您还可以限制或允许用户执行某些操作(可能是修改文章)。
为了传递这些限制或许可,django使用了组和权限,基本上都是基于权限的但是有时候你想把权限传递给整个组而不是显式地传递给用户。
因此,您可以创建it_group。然后,您将添加权限,我们将其命名为it_permission到该组。然后,当您将用户添加到该组时,该用户将拥有所有组权限。如前所述,您不需要使用组来组织这些步骤。您也可以直接添加权限,我们将其命名为admin_status到用户。
构建视图时,会有多个操作符检查当前登录用户的权限。您可以使用permission-required-operator修饰视图。请参阅示例:

from django.contrib.auth.decorators import permission_required

@permission_required('your_user_app.it_permission')
def my_view(request):
    # only users with permissions can view this view.
6ie5vjzr

6ie5vjzr2#

Django和Wagtail在对象授权方面都很糟糕。
对于您的情况,这取决于您希望安全性有多严格,以及授权模型有多复杂。
您可以通过管理菜单中的组编辑页面设置每个页面的权限,下面的任何页面都将继承这些权限。这样做的问题是限制最少的权限适用,并且没有拒绝选项。如果他们在父页面上有编辑权限,他们将在子页面上有编辑权限。
如果你只是想从表面上阻止未经授权的人编辑所有的知识库页面,你可以考虑使用钩子来评估登录用户的权限。
您可以使用before_edit_page在页面表单呈现以供编辑之前进行检查,如果失败则重定向到通知页面,或者使用after_page_edit阻止保存(编辑器在页面上花费一些时间后,不太友好)。
对于编辑前、简单的一次性案例、存在知识库页面类的情况、您希望仅允许IT部门和站点管理员组的成员访问的情况,它可能如下所示:

# wagtail_hooks.py
from django.contrib import messages
from django.http import HttpResponseRedirect
from wagtail import hooks

from kb.models import KnowledgeBasePage

@hooks.register("before_create_page")
@hooks.register("before_delete_page")
@hooks.register("before_edit_page")
def check_kb_permissions(request, page, page_class=None):
    if (page_class or page.specific_class) == KnowledgeBasePage:
        if not request.user.groups.get_queryset().filter(name__in=['Site Managers','IT Department']).exists():
            messages.error(
                request, 
                'You do not have permission to add, edit or delete knowledge base articles.\
                <br><span style="padding-left:2.3em;">Contact <a href="/lalala">support</a> \
                to report this issue</span>'
            )
            return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/admin/'))

如果用户失败了,他们会停留在同一个页面上,并在页面顶部显示一条红色的错误消息。

您可以将其构建为更复杂的授权模型,如果需要,将用户组与模型和权限匹配,而不是上面的硬编码示例。
这不会影响编程操作的CRUD权限,但是如果您只关心编辑器界面,那么这是可行的。

相关问题