Skip to content

permission_system

Dynamic permission system for guild-specific permission hierarchies.

This module provides a database-driven permission system allowing guilds to customize their permission ranks and role assignments. Key features:

  • Dynamic permission ranks (0-10 hierarchy)
  • Role-based access control
  • Command-specific permission overrides
  • Performance caching
  • Configuration file support for self-hosters

Architecture: - PermissionRank: Defines permission ranks (e.g., Moderator, Admin) - PermissionAssignment: Maps Discord roles to permission ranks - PermissionCommand: Sets command-specific permission requirements

Note: "Rank" refers to permission hierarchy (0-100), "Level" refers to XP/progression.

Classes:

  • RankDefinition

    Type definition for permission rank configuration.

  • PermissionSystem

    Main permission system service orchestrating guild-specific permission checking.

Functions:

Classes

RankDefinition

Bases: TypedDict

Type definition for permission rank configuration.

PermissionSystem

Python
PermissionSystem(bot: Tux, db: DatabaseCoordinator)

Main permission system service orchestrating guild-specific permission checking.

This class manages the entire permission lifecycle including rank creation, role assignments, and command permissions.

Attributes:

  • bot (Tux) –

    The bot instance for accessing guild/user data.

  • db (DatabaseCoordinator) –

    Database coordinator for permission storage and retrieval.

  • _default_ranks (dict[int, RankDefinition]) –

    Default permission rank hierarchy (0-7).

Notes

Permission ranks use numeric values (0-10) where higher numbers indicate greater permissions. This is separate from XP-based levels.

Initialize the permission system with bot and database connections.

Parameters:

Methods:

Functions

initialize_guild async
Python
initialize_guild(guild_id: int) -> None

Initialize default permission ranks for a guild.

Creates the standard 8-rank hierarchy (0-7) for guilds that don't have them yet. This method is idempotent - it only creates ranks that are completely missing and never overwrites user customizations.

Parameters:

  • guild_id (int) –

    The Discord guild ID to initialize.

Notes

This is typically called when a guild needs permission ranks initialized. The method respects user customizations: - Creates missing default ranks (preserves user changes to existing ranks) - Never updates existing ranks to avoid overwriting custom names/descriptions - Allows guilds to fully customize their permission hierarchy after initial setup

get_user_permission_rank async
Python
get_user_permission_rank(ctx: Context[Tux]) -> int

Get the highest permission rank a user has in the current guild.

Checks all of the user's roles and returns the highest permission rank assigned to any of them. Returns 0 if the user has no permission ranks.

Parameters:

  • ctx (Context[Tux]) –

    The command context containing guild and user information.

Returns:

  • int

    The highest permission rank (0-10) the user has, or 0 if none.

Notes

This method is used internally by permission decorators to check if a user has sufficient permissions to run a command.

assign_permission_rank async
Python
assign_permission_rank(guild_id: int, rank: int, role_id: int) -> PermissionAssignment

Assign a permission rank to a Discord role.

Links a Discord role to a permission rank, granting all members with that role the specified permission level. Invalidates cache after assignment.

Parameters:

  • guild_id (int) –

    The Discord guild ID.

  • rank (int) –

    The permission rank to assign (0-10).

  • role_id (int) –

    The Discord role ID to assign the rank to.

Returns:

Raises:

  • ValueError

    If the specified rank doesn't exist for the guild.

remove_role_assignment async
Python
remove_role_assignment(guild_id: int, role_id: int) -> bool

Remove permission rank assignment from a Discord role.

Unlinks a role from its permission rank. Members with this role will no longer have the associated permissions.

Parameters:

  • guild_id (int) –

    The Discord guild ID.

  • role_id (int) –

    The Discord role ID to remove the assignment from.

Returns:

  • bool

    True if an assignment was removed, False if no assignment existed.

create_custom_permission_rank async
Python
create_custom_permission_rank(
    guild_id: int, rank: int, name: str, description: str | None = None
) -> PermissionRank

Create a custom permission rank for a guild.

Guilds can create custom ranks or override default ranks with their own names and descriptions. Rank numbers must be between 0-100.

Parameters:

  • guild_id (int) –

    The Discord guild ID.

  • rank (int) –

    The permission rank number (0-10).

  • name (str) –

    Display name for the rank (e.g., "Super Moderator").

  • description (str | None, default: None ) –

    Optional description of the rank's permissions.

Returns:

Raises:

set_command_permission async
Python
set_command_permission(
    guild_id: int, command_name: str, required_rank: int
) -> PermissionCommand

Set the permission rank required for a specific command.

Overrides the default permission requirements for a command in a specific guild. This allows guilds to customize which ranks can use which commands.

Parameters:

  • guild_id (int) –

    The Discord guild ID.

  • command_name (str) –

    The command name (without prefix).

  • required_rank (int) –

    The minimum permission rank required (0-10).

Returns:

Raises:

  • ValueError

    If required_rank is not between 0 and 10.

get_command_permission async
Python
get_command_permission(guild_id: int, command_name: str) -> PermissionCommand | None

Get command-specific permission requirements for a guild.

Parameters:

  • guild_id (int) –

    The Discord guild ID.

  • command_name (str) –

    The command name to look up.

Returns:

  • PermissionCommand | None

    The command permission record, or None if no override exists.

get_guild_permission_ranks async
Python
get_guild_permission_ranks(guild_id: int) -> list[PermissionRank]

Get all permission ranks defined for a guild.

Parameters:

  • guild_id (int) –

    The Discord guild ID.

Returns:

get_guild_assignments async
Python
get_guild_assignments(guild_id: int) -> list[PermissionAssignment]

Get all role-to-rank assignments for a guild.

Parameters:

  • guild_id (int) –

    The Discord guild ID.

Returns:

get_guild_command_permissions async
Python
get_guild_command_permissions(guild_id: int) -> list[PermissionCommand]

Get all command permission overrides for a guild.

Parameters:

  • guild_id (int) –

    The Discord guild ID.

Returns:

load_from_config async
Python
load_from_config(guild_id: int, config: dict[str, Any]) -> None

Load permission configuration from a configuration file.

This allows self-hosters to define their permission structure via configuration files instead of using commands. The config can include custom ranks, role assignments, and command permissions.

Parameters:

  • guild_id (int) –

    The Discord guild ID to configure.

  • config (dict[str, Any]) –

    Configuration dictionary with optional keys: - permission_ranks: List of rank definitions - role_assignments: List of role-to-rank assignments - command_permissions: List of command permission overrides

Examples:

Python Console Session
>>> config = {
...     "permission_ranks": [{"rank": 10, "name": "Elite Mod", "description": "Elite moderators"}],
...     "role_assignments": [{"rank": 10, "role_id": 123456789}],
...     "command_permissions": [{"command": "ban", "rank": 3}],
... }
>>> await system.load_from_config(guild_id, config)

Functions

get_permission_system

Python
get_permission_system() -> PermissionSystem

Get the global permission system instance.

Returns:

Raises:

  • RuntimeError

    If the permission system hasn't been initialized yet.

Notes

Call init_permission_system() during bot startup before using this.

init_permission_system

Python
init_permission_system(bot: Tux, db: DatabaseCoordinator) -> PermissionSystem

Initialize the global permission system instance.

This should be called once during bot startup, after database initialization.

Parameters:

Returns:

Notes

Uses module-level attribute assignment to avoid global statement warning.