在 Wagtail 管理中将编辑者限制为他们自己的内容的问题

Problems limiting editors to their own content in Wagtail admin

被分配到具有 'add' 权限的组的用户可以通过管理员搜索或直接在浏览器中输入正确的路径来访问、复制、移动和添加其他用户创建的页面。

目标是防止用户看到其他用户正在做的任何事情。我原以为它已经实现了。

我的页面树是这样的:

首页 > 人物 > 人物简介 > 人物故事

用户注册一个帐户并自动分配到自定义 'Authors' 组。该组在“人员”页面上具有 'add' 和 'publish' 权限。用户对其团队中的任意数量的人负责。通过此设置,他们能够为其团队的每个成员添加一个个人资料页面。然后可以为每个具有个人资料的人添加多个故事。现在每个人都有故事的子页面链接到他们的个人资料。

我设置了页面浏览器,因此用户只能看到他们的页面:

@hooks.register('construct_explorer_page_queryset')
def show_authors_only_their_articles(parent_page, pages, request):
    user_group = request.user.groups.filter(name='Authors').exists()
    if user_group:
        pages = pages.filter(owner=request.user)

    return pages

图片选择器也只显示用户上传的图片:

@hooks.register('construct_image_chooser_queryset')
def filter_images_by_user(images, request):
    images = images.filter(uploaded_by_user=request.user)

    return images

并且页面摘要项目仅显示属于使用类似代码的用户的内容。

但在我认为将要进行最终测试的过程中,我发现使用管理员搜索完成的搜索会导致包含这些搜索词的所有可用人物简介和人物故事页面的列表。例如,如果他们搜索 'John',则会返回 John 的所有个人资料和故事页面。然后用户可以单击 John 的个人资料页面。一旦到达 John 在资源管理器中的个人资料页面,他们就可以将故事添加到 John 的个人资料、复制、移动或取消发布!他们可以对 John 的故事做同样的事情,只是不添加子页面。

这是一个游戏规则改变者,对我们不起作用。

我环顾四周,看看可能有几种解决方案:

1) 使用 ModelAdmin 创建类似的设置,但我想我会遇到同样的问题。搜索时,用户仍然可以找到和操作禁止的内容。

2) 按照 post 中的建议为每个用户创建一个唯一的用户组:Wagtail per page user permission

在第二种方法中,创建用户后我需要以编程方式:

1) 为他们创建一个新的用户组,可能使用他们的用户名。

2) 将他们分配到新用户组

3) 创建一个专门针对他们的新 'Person' 页面并授予他们 'add' 和 'publish' 权限。

最后一步,因为如果我将他们全部分配到同一个个人页面,他们仍然可以将页面添加到其他用户配置文件,而不管他们在不同的用户组中,因为所有这些不同的用户组仍将具有对同一个人页面的添加访问权限。

最终我需要阻止每个用户了解其他用户正在做的事情。非常感谢您的想法。自从我完成任何编程以来已经有好几年了,但我仍在追赶。与此同时,我将开始看看我能想出什么。

我认为我们很接近。该系统运行良好且流畅!

我最终通过在 Wagtail 核心包中搜索 GroupPagePermission 和 GroupCollectionPermission 的实例来解决这个问题。能够拼凑起来看看他们是怎么做到的。

在我称为 'users' 的应用程序的 models.py 中,我实现了 django-allauth user_sign_up @receiver。一旦用户成功注册,它就会运行以下代码:

from django.contrib.auth.models import Group, Permission
from django.dispatch import receiver
from allauth.account.signals import user_signed_up
from wagtail.core.models import Page, GroupPagePermission, GroupCollectionPermission, Collection
from article.models import PersonIndexPage

@receiver(user_signed_up)
def create_user_group_and_pages(sender, **kwargs):
    """
    When a new user signs up create a unique group and page for them.
    Assign it the appropriate permission for admin, page and collection access.
    """

    # Grab the new user
    user = kwargs['user']

    # Create a group object that matches their username
    new_group, created = Group.objects.get_or_create(name=user.username)

    # Add the new group to the database
    user.groups.add(new_group)

    # Create new permission to access the wagtail admin
    access_admin = Permission.objects.get(codename='access_admin')

    # Add the permission to the group
    new_group.permissions.add(access_admin)

    # Now start creating page access
    # First find the homepage
    home = Page.objects.get(slug='home').specific

    # Create unique PersonIndexPage for the user
    person_index_page = PersonIndexPage(title=user.username)

    # Add PersonIndexPage to homepage as a child
    home.add_child(instance=person_index_page)

    # Save new page as first revision
    person_index_page.save_revision()

    # Create new add GroupPagePermission
    GroupPagePermission.objects.create(
        group=new_group,
        page=person_index_page,
        permission_type='add'
    )

    # Create new GroupCollectionPermission for Profile Images collection
    GroupCollectionPermission.objects.create(
        group=new_group,
        collection=Collection.objects.get(name='Images'),
        permission=Permission.objects.get(codename='add_image')
    )

现在,当 a 创建新帐户时,会为他们创建一个新的索引页面,其中创建了一个唯一的组,使他们只能访问该索引页面及其子页面。有效地阻止他们访问网站上的任何其他内容。他们仍然可以在管理员搜索中查看其他页面的结果,但无权对这些结果执行任何操作。

用户可以登录,为每个人创建个人资料,然后为每个人创建任意数量的故事。