Permactions и права доступа

В Ecosystem54 права - это не только флаг доступа, но и правило, которое может содержать собственную исполняемую проверку.

Что такое permaction

Permaction объединяет две идеи: permission и action. То есть система хранит не только сам факт разрешения, но и кодовую логику, которая определяет, допустимо ли выполнение действия.

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

Путь запроса

  1. Запрос попадает в FastAPI endpoint.
  2. Endpoint получает зависимости, например request и db.
  3. Внутри handler вызывается permaction.execute().
  4. Декоратор @perms_check определяет текущего эктора и проверяет его permaction.
  5. Если проверка проходит, endpoint продолжает выполнение и возвращает response; если нет, клиент получает отказ в доступе.

Приоритеты прав

В основе приоритизации лежит вес групп. Чем выше вес, тем сильнее влияние группы на итоговое решение о доступе.

  1. ROOT - максимальный приоритет.
  2. BAN - запретительная группа с наивысшим весом среди обычных групп.
  3. ADMIN - административный доступ, идущий сразу после BAN.
  4. Индивидуально выданные права эктора.
  5. Пользовательские группы, упорядоченные по весу.

С точки зрения разработчика

Все permactions для функциональности сервиса располагаются в папке actions. В FastAPI метод execute() обычно асинхронный и принимает request и db, потому что декоратор @perms_check использует их для проверки текущего эктора и цепочки прав.

Пример simple-permaction

from fastapi import Request

from submodules.auth_perms.core.action import BasePermAction
from submodules.auth_perms.fast_api.database.async_manager import AsyncDatabaseAdapter
from submodules.auth_perms.fast_api.decorators import perms_check


class CanSeeSecretPage(BasePermAction):
    @perms_check
    async def execute(self, request: Request, db: AsyncDatabaseAdapter):
        return True

    @classmethod
    def title(cls) -> str:
        return "Allow to use Can See Secret Page"

    @classmethod
    def description(cls) -> str:
        return "PermAction allows opening the secret page"

    @classmethod
    def permaction_type(cls) -> str:
        return "simple"

    def biom_perm(self, params: dict) -> bool:
        return True

    @classmethod
    def permaction_uuid(cls) -> str:
        return "70ef15f8-ab8e-4cf2-aaff-03c9fe3b462f"

    @classmethod
    def default_value(cls) -> int:
        return 0

    @classmethod
    def unions(cls) -> list[str]:
        return ["Secret Page"]

У permaction есть два базовых типа: simple и check. Для типа check можно объявить params() и использовать их внутри biom_perm().

Пример check-permaction

from datetime import date


class CanSeeSecretPage(BasePermAction):
    @perms_check
    async def execute(self, request: Request, db: AsyncDatabaseAdapter):
        return True

    @classmethod
    def permaction_type(cls) -> str:
        return "check"

    @classmethod
    def params(cls) -> dict:
        return {"weekdays": []}

    def biom_perm(self, params: dict) -> bool:
        allowed_weekdays = params.get("weekdays", [0, 1, 2, 3, 4, 5, 6])
        return date.today().weekday() in allowed_weekdays

После добавления новых прав их нужно зарегистрировать командой uv run manage.py collect_perms.

Ниже приведен отдельный пример того, как вызвать permaction внутри FastAPI endpoint и только после успешной проверки вернуть защищенный ресурс.

Пример использования permaction в endpoint

from fastapi import APIRouter, Depends, Request

from submodules.auth_perms.fast_api.database.async_manager import AsyncDatabaseAdapter
from submodules.auth_perms.fast_api.dependencies import get_db_connection_for_submodule

router = APIRouter()


@router.get("/secret/")
async def secret_page(
    request: Request,
    db: AsyncDatabaseAdapter = Depends(get_db_connection_for_submodule),
):
    await CanSeeSecretPage().execute(request=request, db=db)
    return {"detail": "Secret page"}

С точки зрения администратора

Способ управления permaction зависит от режима работы сервиса.

  • Standalone. Администратор настраивает permaction через панель /auth_admin/ внутри самого сервиса.
  • Biome. Управление permaction и назначениями выполняется на стороне auth-сервиса, а локальная панель /auth_admin/ для этого не используется.

Ниже показан базовый сценарий для Standalone-режима: как назначить доступ, как применить Override и как проверить результат.

Как назначить permaction

  1. Откройте карточку нужного пользователя.
  2. Найдите permaction, который отвечает за нужное действие или страницу.
  3. Добавьте Override, если настройка должна действовать точечно для этого пользователя.
  4. Установите значение override: включено - доступ открыт, выключено - доступ закрыт.
  5. Сохраните изменение и проверьте результат на защищенном endpoint или странице.

Проверка результата

  • Если permaction не назначен или override выключен, пользователь получает отказ.
  • Если permaction назначен и проверка проходит, пользователь открывает защищенную страницу.