Added command checks #114

This commit is contained in:
Sven Heidemann 2022-11-13 11:56:42 +01:00
parent 8fa6458d6e
commit e754a10241
7 changed files with 120 additions and 11 deletions

View File

@ -12,6 +12,7 @@ from bot.startup_migration_extension import StartupMigrationExtension
from bot.startup_module_extension import StartupModuleExtension from bot.startup_module_extension import StartupModuleExtension
from bot.startup_settings_extension import StartupSettingsExtension from bot.startup_settings_extension import StartupSettingsExtension
from bot_api.app_api_extension import AppApiExtension from bot_api.app_api_extension import AppApiExtension
from bot_core.core_extension.core_extension import CoreExtension
from modules.boot_log.boot_log_extension import BootLogExtension from modules.boot_log.boot_log_extension import BootLogExtension
from modules.database.database_extension import DatabaseExtension from modules.database.database_extension import DatabaseExtension
@ -31,6 +32,7 @@ class Program:
.use_extension(BootLogExtension) \ .use_extension(BootLogExtension) \
.use_extension(DatabaseExtension) \ .use_extension(DatabaseExtension) \
.use_extension(AppApiExtension) \ .use_extension(AppApiExtension) \
.use_extension(CoreExtension) \
.use_startup(Startup) .use_startup(Startup)
self.app: Application = await app_builder.build_async() self.app: Application = await app_builder.build_async()
await self.app.run_async() await self.app.run_async()

View File

@ -0,0 +1,28 @@
from cpl_core.application import ApplicationExtensionABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.dependency_injection import ServiceProviderABC
from cpl_translation import TranslatePipe
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
from bot_core.abc.message_service_abc import MessageServiceABC
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_core.helper.command_checks import CommandChecks
from modules.permission.abc.permission_service_abc import PermissionServiceABC
class CoreExtension(ApplicationExtensionABC):
def __init__(self):
ApplicationExtensionABC.__init__(self)
async def run(self, config: ConfigurationABC, services: ServiceProviderABC):
feature_flags: FeatureFlagsSettings = config.get_configuration(FeatureFlagsSettings)
if not feature_flags.get_flag(FeatureFlagsEnum.core_module):
return
permissions: PermissionServiceABC = services.get_service(PermissionServiceABC)
client_utils: ClientUtilsServiceABC = services.get_service(ClientUtilsServiceABC)
message_service: MessageServiceABC = services.get_service(MessageServiceABC)
t: TranslatePipe = services.get_service(TranslatePipe)
CommandChecks.init(permissions, client_utils, message_service, t)

View File

@ -0,0 +1,7 @@
from discord.ext.commands import CommandError
class CheckError(CommandError):
def __init__(self, message, *args):
CommandError.__init__(self, message, *args)

View File

@ -0,0 +1,76 @@
from typing import Optional
from cpl_translation import TranslatePipe
from discord.ext import commands
from discord.ext.commands import Context
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
from bot_core.abc.message_service_abc import MessageServiceABC
from bot_core.exception.check_error import CheckError
from modules.permission.abc.permission_service_abc import PermissionServiceABC
class CommandChecks:
_permissions: Optional[PermissionServiceABC] = None
_client_utils: Optional[ClientUtilsServiceABC] = None
_message_service: Optional[MessageServiceABC] = None
_t: Optional[TranslatePipe] = None
@classmethod
def init(
cls,
permissions: PermissionServiceABC,
client_utils: ClientUtilsServiceABC,
message_service: MessageServiceABC,
translate: TranslatePipe,
):
cls._permissions = permissions
cls._client_utils = client_utils
cls._message_service = message_service
cls._t = translate
@classmethod
def check_is_ready(cls):
async def check_if_bot_is_ready_yet_and_respond(ctx: Context) -> bool:
result = await cls._client_utils.check_if_bot_is_ready_yet_and_respond(ctx)
if not result:
raise CheckError(f'Bot is not ready')
return result
return commands.check(check_if_bot_is_ready_yet_and_respond)
@classmethod
def check_is_member_admin(cls):
async def check_is_member_admin(ctx: Context):
has_permission = cls._permissions.is_member_admin(ctx.author)
if not has_permission:
await cls._message_service.send_ctx_msg(ctx, cls._t.transform('common.no_permission_message'))
raise CheckError(f'Member {ctx.author.name} is not admin')
return has_permission
return commands.check(check_is_member_admin)
@classmethod
def check_is_member_technician(cls):
async def check_is_member_technician(ctx: Context):
has_permission = cls._permissions.is_member_technician(ctx.author)
if not has_permission:
await cls._message_service.send_ctx_msg(ctx, cls._t.transform('common.no_permission_message'))
raise CheckError(f'Member {ctx.author.name} is not technician')
return has_permission
return commands.check(check_is_member_technician)
@classmethod
def check_is_member_moderator(cls):
async def check_is_member_moderator(ctx: Context):
has_permission = cls._permissions.is_member_moderator(ctx.author)
if not has_permission:
await cls._message_service.send_ctx_msg(ctx, cls._t.transform('common.no_permission_message'))
raise CheckError(f'Member {ctx.author.name} is not moderator')
return has_permission
return commands.check(check_is_member_moderator)

View File

@ -1,6 +1,5 @@
import asyncio import asyncio
import discord
from cpl_core.configuration import ConfigurationABC from cpl_core.configuration import ConfigurationABC
from cpl_discord.command import DiscordCommandABC from cpl_discord.command import DiscordCommandABC
from cpl_discord.service import DiscordBotServiceABC from cpl_discord.service import DiscordBotServiceABC
@ -11,6 +10,7 @@ from discord.ext.commands import Context
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.abc.message_service_abc import MessageServiceABC
from bot_core.configuration.bot_settings import BotSettings from bot_core.configuration.bot_settings import BotSettings
from bot_core.helper.command_checks import CommandChecks
from bot_core.logging.command_logger import CommandLogger from bot_core.logging.command_logger import CommandLogger
from modules.permission.abc.permission_service_abc import PermissionServiceABC from modules.permission.abc.permission_service_abc import PermissionServiceABC
@ -43,18 +43,10 @@ class RestartCommand(DiscordCommandABC):
@commands.hybrid_command() @commands.hybrid_command()
@commands.guild_only() @commands.guild_only()
@CommandChecks.check_is_ready()
@CommandChecks.check_is_member_moderator()
async def restart(self, ctx: Context): async def restart(self, ctx: Context):
self._logger.debug(__name__, f'Received command restart {ctx}') self._logger.debug(__name__, f'Received command restart {ctx}')
if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx):
return
self._client_utils.received_command(ctx.guild.id)
self._client_utils.received_command(ctx.guild.id)
if not self._permissions.is_member_moderator(ctx.author):
await self._message_service.send_ctx_msg(ctx, self._t.transform('common.no_permission_message'))
self._logger.trace(__name__, f'Finished restart command')
return
self._config.add_configuration('IS_RESTART', 'true') self._config.add_configuration('IS_RESTART', 'true')
await self._client_utils.presence_game('common.presence.restart') await self._client_utils.presence_game('common.presence.restart')

View File

@ -13,6 +13,7 @@ from cpl_discord.events.on_command_error_abc import OnCommandErrorABC
from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.abc.message_service_abc import MessageServiceABC
from bot_core.configuration.bot_settings import BotSettings from bot_core.configuration.bot_settings import BotSettings
from bot_core.exception.check_error import CheckError
class BaseOnCommandErrorEvent(OnCommandErrorABC): class BaseOnCommandErrorEvent(OnCommandErrorABC):
@ -35,6 +36,9 @@ class BaseOnCommandErrorEvent(OnCommandErrorABC):
self._t = translate self._t = translate
async def on_command_error(self, ctx: Context, error: CommandError): async def on_command_error(self, ctx: Context, error: CommandError):
if isinstance(error, CheckError):
return
error = getattr(error, 'original', error) error = getattr(error, 'original', error)
uid = uuid.uuid4() uid = uuid.uuid4()
self._logger.error(__name__, f'Got error: {type(error).__name__} UID: {uid}') self._logger.error(__name__, f'Got error: {type(error).__name__} UID: {uid}')