Skip to content

Права доступа

Мы используем ролевую модель доступов (RBAC) в системе. У пользователя есть роль в системе (CompanyUser.role), а у каждой роли есть права доступа (RolePermission).

Описание прав доступа RolePermission

RolePermission состоит из двух сущностей и набора свойста.

Сущности:

  • Роль (Role) — описание Роли в системе
  • Право доступа (Permission) — описание права доступа, где оно расположено (Permission.module), уникальный ключ (Permission.alias). Право доступа олицетворяет сущность, бизнес единицу, в 99% случаев это модель, например, Файл или Папка в диске, Проект или Объект в сервисе проектов и так далее.

Свойства:

  • RolePermission.read — может ли эта роль читать объекты из права доступа (чтение как одного объекта так и списка объектов).
  • RolePermission.create — может ли эта роль создавать объекты из права доступа.
  • RolePermission.update — может ли эта роль изменять объекты из права доступа.
  • RolePermission.delete — может ли эта роль удалять объекты из права доступа.
  • RolePermission.actions — может ли эта роль выполнять дополнительные действия над сущностью из права доступа. Не все сущности имеют дополнительные действия.
  • RolePermission.scope — когда роль выполняет действие над конкретным объектом, то какие объекты ей доступны (только те, что создал пользователь, все объекты компании, любые объекты в системе).

Как применяются RolePermission

В django проектах ASU мы используем один ModelViewSet для конкретной модели и описываем все бизнес процессы (действия) в рамках этого вьюсета.

Пример:

FileView из диска это ModelViewSet для модели File, мы можем его читать, создавать, изменять итд. У нас есть Permission(alias="file", module="disk"), который описывает эту модель. Этот Permission задан для конкретной роли и настроен в RolePermission.

FileView для проверки прав доступа имеет несколько свойств:

  • permission_classes, который включает в себя asu_s_sdk.utils.rest_framework.permissions.permission.AsuPermission("file"), который во время выполнения запроса проверяет права доступа
  • permission_scope_path это словарь в котором мы описываем какие поля из модели нужно проверять для доступа к объекту. Например:
python
from asu_s_sdk.utils.rest_framework.permissions.permission import AsuPermissionScope

permission_scope_path = {
    AsuPermissionScope.COMPANY: "file.company_id",
    AsuPermissionScope.SELF: ["author_id", "file.user_id"],
}
  • Для скоупа объектов компании мы у объекта ищем поле obj.file.company_id и сравниваем его с request.user.company_id
  • Для скоупа собственных объектов мы у объекта сравниваем два поля obj.author_id или obj.fle.user_id с request.user.id

У FileView также есть дополнительные действия, которые мы описываем с помощью декоратора @action(methods=..., detail=...), этот action также должен быть добавлен в право доступа (Permission)

Если добавляется новая модель

  1. Добавить новую запись в конце фикстуры permissions.json. defaults всегда заполняем в false.
  2. После деплоя для всех Role объектов нужно добавить новые права доступа. В django-admin есть удобный action update_permissions для RoleAdmin, чтобы это сделать.

Если добавляется допольнительное действие над моделью

  1. Найти нужный объект права доступа в фикстуре permissions.json.
  2. В объекте actions добавить ключ (название action из вьюсета) и значение false.
  3. После деплоя для всех Role объектов нужно добавить новые права доступа. В django-admin есть удобный action update_permissions для RoleAdmin, чтобы это сделать.

Важно

  1. При изменении прав доступа у RolePermission они не всегда применяются моментально, т.к. межсервисные запросы кэшируются. Кэш обновится максимум через 2 минуты.
  2. Следить за тем, чтобы при каждом деплое помимо миграций вызывалась команда manage.py loaddata permissions, которая будет добавлять новые права доступа.