🎭 Роли¶
В Raito встроена система доступа на основе ролей:
именованные роли (у каждой есть slug, подпись, эмодзи и описание);
роли одновременно работают как фильтры aiogram и объединяются через
|;управление прямо в чате через команды
.rt;слэш-команды, автоматически подстроенные под роль пользователя;
подключаемые бэкенды (в памяти, JSON, Redis, SQL).
Ограничить хендлер ролью¶
Импортируйте встроенные роли из rt (или raito.plugins.roles) и применяйте их как фильтры. Роль срабатывает, только если пользователь ею сейчас обладает:
from aiogram import Router, filters, types
from raito.rt import OWNER, ADMINISTRATOR, MODERATOR
router = Router(name="moderation")
@router.message(filters.Command("ban"), OWNER | ADMINISTRATOR | MODERATOR)
async def ban(message: types.Message) -> None:
...
A | B означает «любая из этих ролей». Это единственный комбинатор: у пользователя ровно одна роль, поэтому вам нужен именно | (ИЛИ). Иерархии ролей нет: OWNER сам по себе не проходит фильтр ADMINISTRATOR, поэтому перечисляйте все роли, которые должны проходить.
Дать доступ себе¶
Передайте доверенные ID пользователей в developers. Они неявно получают роль developer без обращения к бэкенду:
raito = Raito(dispatcher, "handlers", developers=[123456789])
Выбрать бэкенд¶
Бэкенд ролей определяется по FSM-хранилищу storage, которое вы передаёте в Raito. Подключать провайдер вручную не нужно:
|
Бэкенд ролей |
|---|---|
|
в памяти (теряется при перезапуске) |
файл JSON |
|
|
Redis |
Хранилище SQLite / PostgreSQL |
таблица SQL |
from raito import Raito
from raito.utils.storages import get_sqlite_storage
SQLiteStorage = get_sqlite_storage()
storage = SQLiteStorage("sqlite+aiosqlite:///bot.db")
raito = Raito(dispatcher, "handlers", storage=storage)
Хранилища в памяти и в JSON подходят для разработки; при production=True Raito предупредит об их использовании на старте. В продакшене используйте Redis или SQL.
Управление ролями из чата¶
Пользователь, у которого уже есть управляющая роль, может выдавать роли другим, не выходя из Telegram:
.rt roles → pick a role, then send a user ID
.rt revoke → send a user ID to remove their role
.rt staff → tree of all users grouped by role
Для управления ролями нужна роль developer, owner или administrator.
Предупреждение
Назначение ролей плоское: любая управляющая роль может выдать любую роль, включая owner и developer. Поэтому administrator может повысить другого пользователя (а через второго администратора и себя) до developer. Выдавайте управляющие роли только тем, кому доверяете это.
Управление ролями из кода¶
raito.role_manager предоставляет те же операции:
from aiogram import Router, filters, types
from raito import Raito, rt
from raito.rt import ADMINISTRATOR, DEVELOPER, OWNER
router = Router(name="tester")
@router.message(filters.Command("give_tester"), DEVELOPER | OWNER | ADMINISTRATOR)
@rt.params(user_id=int)
async def give_tester(message: types.Message, raito: Raito, user_id: int) -> None:
await raito.role_manager.assign_role(
message.bot.id, message.from_user.id, user_id, "tester"
)
await message.answer(f"User <code>{user_id}</code> is now a tester!", parse_mode="HTML")
Основные методы: assign_role(bot_id, initiator_id, target_id, slug), revoke_role(bot_id, initiator_id, target_id), get_role(bot_id, user_id), has_role(...), has_any_roles(...), get_users(bot_id, slug). assign и revoke проверяют, что инициатор вправе управлять ролями и не меняет свою собственную, иначе поднимается PermissionError.
Слэш-команды по ролям¶
Вызовите register_commands() (обычно из хендлера lifespan), чтобы опубликовать меню команд. Raito читает у каждого хендлера роль-фильтр и description(), затем настраивает меню под каждого пользователя, чтобы он видел только доступные ему команды:
await raito.register_commands(bot)
Встроенные роли¶
Роль |
Slug |
Описание |
|---|---|---|
🖥️ Разработчик |
developer |
Полный доступ, включая отладочные инструменты и небезопасные операции. |
👑 Владелец |
owner |
Администратор верхнего уровня; управляет администраторами и глобальными настройками. |
💼 Администратор |
administrator |
Управляет пользователями, модерирует контент, настраивает большинство параметров. |
🛡️ Модератор |
moderator |
Модерирует активность, выдаёт предупреждения, следит за соблюдением правил. |
📊 Менеджер |
manager |
Ведёт нетехнические задачи (кампании, задачи, контент). |
❤️ Спонсор |
sponsor |
Поддерживает проект; обычно без админских прав. |
👤 Гость |
guest |
Временный доступ к отдельным возможностям; обычно приглашённые пользователи. |
💬 Поддержка |
support |
Помогает пользователям и с онбордингом. |
🧪 Тестировщик |
tester |
Тестирует новые функции; может иметь доступ к экспериментальным инструментам. |
Свои роли¶
Задайте роль, обернув RoleFilter в RoleConstraint:
from raito.plugins.roles.constraint import RoleConstraint
from raito.plugins.roles.filter import RoleFilter
DUDE = RoleConstraint(
RoleFilter(slug="dude", name="Dude", description="Just a dude", emoji="😎")
)
Используйте DUDE как фильтр наравне с любой встроенной ролью. Чтобы роль стала управляемой и появилась в .rt staff, унаследуйтесь от RoleManager (переопределив available_roles / get_role_data и при необходимости проверки прав) и передайте его через configuration=RaitoConfiguration(role_manager=...).
Совет
В долгих FSM-сценариях перепроверяйте роль на каждом шаге: роль пользователя может измениться между сообщениями.