Исходный код raito.plugins.roles.manager

from __future__ import annotations

from raito.plugins.roles.data import RoleData

from .providers.protocol import IRoleProvider
from .roles import AVAILABLE_ROLES, AVAILABLE_ROLES_BY_SLUG

__all__ = ("RoleManager",)


[документация] class RoleManager: """Central manager for role-based access control in Raito.""" def __init__(self, provider: IRoleProvider, developers: list[int] | None = None) -> None: """Initialize RoleManager. :param provider: Role provider instance for persistent storage :type provider: IRoleProvider """ self.provider = provider self.developers = developers or []
[документация] async def migrate(self) -> None: """Run provider migrations.""" await self.provider.migrate()
[документация] async def get_role(self, bot_id: int, user_id: int) -> str | None: """Get the role for a specific user. :param bot_id: The Telegram bot ID :param user_id: The Telegram user ID :return: The role slug or None if not found """ return await self.provider.get_role(bot_id, user_id)
[документация] async def can_manage_roles(self, bot_id: int, user_id: int) -> bool: """Check whether the user can manage other users' roles. :param bot_id: The Telegram bot ID :param user_id: The Telegram user ID :return: True if user can manage roles, False otherwise """ return await self.has_any_roles( bot_id, user_id, "developer", "administrator", "owner", )
[документация] async def assign_role( self, bot_id: int, initiator_id: int, target_id: int, role_slug: str, ) -> None: """Assign a role to a user. :param bot_id: The Telegram bot ID :param initiator_id: The Telegram user ID of the initiator :param target_id: The Telegram user ID of the target :param role_slug: The role to assign :raises PermissionError: If the user does not have permission to assign role """ if initiator_id == target_id: msg = "You cannot assign your own role." raise PermissionError(msg) if not await self.can_manage_roles(bot_id, initiator_id): msg = "You do not have permission to assign roles." raise PermissionError(msg) await self.provider.set_role(bot_id, target_id, role_slug)
[документация] async def revoke_role(self, bot_id: int, initiator_id: int, target_id: int) -> None: """Revoke a user's role. :param bot_id: The Telegram bot ID :param initiator_id: The Telegram user ID of the initiator :param target_id: The Telegram user ID of the target :raises PermissionError: If the user does not have permission to revoke roles """ if initiator_id == target_id: msg = "You cannot revoke your own role." raise PermissionError(msg) if not await self.can_manage_roles(bot_id, initiator_id): msg = "You do not have permission to assign roles." raise PermissionError(msg) await self.provider.remove_role(bot_id, target_id)
[документация] async def has_any_roles(self, bot_id: int, user_id: int, *roles: str) -> bool: """Check if a user has any of the specified roles. :param bot_id: The Telegram bot ID :param user_id: The Telegram user ID :param roles: Roles to check for :returns: True if user has any of the roles, False otherwise """ if user_id in self.developers and "developer" in roles: return True role = await self.get_role(bot_id, user_id) return role in roles
[документация] async def has_role(self, bot_id: int, user_id: int, role_slug: str) -> bool: """Check if a user has the specified roles. :param bot_id: The Telegram bot ID :param user_id: The Telegram user ID :param role_slug: Role to check for :returns: True if user has the role, False otherwise """ if user_id in self.developers and role_slug == "developer": return True slug = await self.get_role(bot_id, user_id) return slug == role_slug
[документация] async def get_users(self, bot_id: int, role: str) -> set[int]: """Get a list of users with a specific role. :param bot_id: The Telegram bot ID :param role: The role to check for :returns: A list of Telegram user IDs """ users = await self.provider.get_users(bot_id, role) unique_users = set(users) if role == "developer": unique_users.update(self.developers) return unique_users
@property def available_roles(self) -> list[RoleData]: """Get a list of available roles. :returns: A list of roles """ return AVAILABLE_ROLES
[документация] def get_role_data(self, slug: str) -> RoleData: """Get data of specified role. :returns: A data of role :raises: ... """ return AVAILABLE_ROLES_BY_SLUG[slug]