For the complete documentation index, see llms.txt. This page is also available as Markdown.

Права доступа (permissions)

Кто что может делать на сайте, описывается правами. Право — это строковый ключ вида <модуль>.<объект>.<действие> (forum.post, users.ban.manage), который модуль объявляет сам. Права выдаются ролям, а роли — аккаунтам; редактор ролей находится в /admin/roles.

Проверка права

В коде — через AccessCheckerInterface, всегда инъекцией:

use Johncms\Auth\Authorization\AccessCheckerInterface;
use Johncms\Modules\Forum\Application\Services\ForumPermissions;

final readonly class PostMessageUseCase
{
    public function __construct(private AccessCheckerInterface $accessChecker)
    {
    }

    public function execute(): void
    {
        if (! $this->accessChecker->allows(ForumPermissions::POST)) {
            throw new AccessDeniedException();
        }
    }
}

Второй аргумент allows() — объект, о котором идёт речь. Он нужен, когда право зависит не только от роли: куратор темы модерирует свою тему, и об этом спрашивают так:

В шаблонах — функция can():

Целый маршрут закрывается правом в объявлении маршрута, без проверки в контроллере — см. Маршрутизация.

Объявление прав модуля

Модуль объявляет свои права провайдером — классом, реализующим PermissionProviderInterface. Тег для контейнера ставится автоматически, отдельной регистрации не требуется (если каталог src/Application загружается целиком).

Права появляются в редакторе ролей сгруппированными по group, с подписью label. Право, которого нет в каталоге, выдать нельзя — реестр не принимает неизвестные ключи.

После обновления, объявляющего новые права, встроенным ролям их нужно раздать:

Команда создаёт роли, которых у сайта ещё нет, и выдаёт встроенным ролям недостающие права по умолчанию. Она только добавляет — то, что настроено на сайте вручную, остаётся как есть, — поэтому запускать её после каждого обновления безопасно. То же доступно кнопкой в админке, в разделе «Обслуживание».

Иерархия ролей

Право отвечает на вопрос «можно ли делать это», но не на вопрос «кто кого выше». Для второго есть уровень роли и RoleLevels:

Так проверяется, что модератор не редактирует профиль администратора и не банит того, кто стоит выше. Для списка сразу многих аккаунтов есть highestGrantedToMany() — один запрос на страницу вместо запроса на строку.

Роль уровня 90 и выше (supervisor) может всё независимо от выданных прав: это гарантированный способ вернуться в неправильно настроенный сайт.

Голосователи (voters)

Ответ «можно» складывается из голосов. Любой Deny запрещает, один Allow разрешает, вопрос без голосов запрещён. Так бан перебивает роль, а токен API может урезать администратора. Модуль добавляет своё правило классом, реализующим AccessVoterInterface — например, чтобы разрешить действие автору объекта:

Перенос настроек существующего сайта

Значения старых настроек доступа переносятся в права ролей одной командой — той же, что переводит должности в роли:

Она читает mod_forum, mod_guest, mod_lib, mod_down, mod_reg и active и выдаёт (или снимает) соответствующие права ролям guest и user. Это единственное место в системе, которое права снимает: «форум только авторизованным» — это роль guest без forum.view. Именно поэтому команда одноразовая: повторный запуск вернул бы роли к тому, что говорят старые настройки, отменив то, что настроено в /admin/roles после переноса. Пока колонка users.rights на месте, перенос считается незавершённым; после её удаления команда больше ничего не делает.

Последнее обновление

Это было полезно?