Как применить более высокие разрешения к дочерним страницам в Wagtail?

Я создаю интранет-сайт для своей организации с помощью Wagtail, и мы находимся в процессе добавления базы знаний. Весь сайт должен быть ограничен для вошедших в систему пользователей, но определенные страницы должны быть доступны только для пользователей из определенных групп. Например, только члены группы ИТ должны иметь доступ к страницам под страницей базы знаний ИТ.

В настоящее время, если я устанавливаю для страницы верхнего уровня доступ только для зарегистрированных пользователей, это разрешение применяется к каждой странице на сайте, и я не могу установить более конкретные разрешения для любой дочерней страницы. Необходимо, чтобы я мог устанавливать более конкретные разрешения на дочерних страницах.

Я смог найти Wagtail Bug #4277, который, похоже, указывает на то, что логика для более конкретных разрешений реализована, но не отображается в пользовательском интерфейсе администратора.

Я еще не знаком с внутренним устройством Wagtail, особенно с тем, как разрешения Wagtail пересекаются с разрешениями Django. Как я могу добавить более конкретные разрешения на дочерние страницы?

Вы можете ограничить или разрешить пользователям просматривать сайт. Вы также можете ограничить или разрешить пользователям выполнять некоторые действия (возможно, изменять статью).

Для передачи этих ограничений или разрешений 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.

Django и Wagtail ужасно справляются с авторизацией объектов.

Для вашего случая это зависит от того, насколько жесткой вы хотите сделать безопасность и насколько сложной является модель авторизации.

Вы можете установить разрешения для каждой страницы через страницу редактирования группы в меню администратора, любая страница ниже будет наследовать эти разрешения. Проблема в том, что применяются наименее ограничительные разрешения, и нет опции запрета. Если у них есть разрешение на редактирование родительской страницы, у них будет разрешение на редактирование дочерней страницы.

Если вам нужна лишь поверхностная профилактика, чтобы остановить неавторизованных людей, редактирующих все страницы базы знаний, вы можете рассмотреть возможность использования хуков для оценки разрешений вошедшего пользователя.

Вы можете использовать before_edit_page для проверки перед выводом формы страницы для редактирования и перенаправления на страницу уведомления в случае неудачи, или использовать after_page_edit для предотвращения сохранения (не очень дружелюбно после того, как редактор провел некоторое время на странице).

Перед редактированием, для простого одноразового случая, когда есть класс для страницы KB, где вы хотите разрешить доступ только членам групп IT Department и Site Managers, это может быть что-то вроде:

# 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/'))
                

Если пользователь терпит неудачу, он остается на той же странице с сообщением об ошибке в красном баннере в верхней части страницы.

enter image description here

Вы можете построить более сложную модель авторизации, сопоставляя группы пользователей с моделями и разрешениями, если это необходимо, а не жестко закодированный пример выше.

Это не влияет на разрешения CRUD для программных операций, но если вас интересует только интерфейс редактора, то это работает.

Вернуться на верх