1.0.0 #253
@ -283,7 +283,17 @@
|
||||
"technician": {
|
||||
"restart_message": "Bin gleich wieder da :D",
|
||||
"shutdown_message": "Trauert nicht um mich, es war eine logische Entscheidung. Das Wohl von Vielen, es wiegt schwerer als das Wohl von Wenigen oder eines Einzelnen. Ich war es und ich werde es immer sein, Euer Freund. Lebt lange und in Frieden :)",
|
||||
"log_message": "Hier sind deine Logdateien! :)"
|
||||
"log_message": "Hier sind deine Logdateien! :)",
|
||||
"api_key": {
|
||||
"get": "API-Schlüssel für {}: {}",
|
||||
"add": {
|
||||
"success": "API-Schlüssel für {} wurde erstellt: {}"
|
||||
},
|
||||
"remove": {
|
||||
"not_found": "API-Schlüssel konnte nicht gefunden werden!",
|
||||
"success": "API-Schlüssel wurde entfernt :D"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"api": {
|
||||
|
@ -18,6 +18,10 @@ class ApiKeyRepositoryABC(ABC):
|
||||
def get_api_key(self, identifier: str, key: str) -> ApiKey:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_api_key_by_key(self, key: str) -> ApiKey:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def add_api_key(self, api_key: ApiKey):
|
||||
pass
|
||||
|
@ -27,7 +27,8 @@ class ApiKeyMigration(MigrationABC):
|
||||
`LastModifiedAt` DATETIME(6),
|
||||
PRIMARY KEY(`Id`),
|
||||
FOREIGN KEY (`CreatorId`) REFERENCES `Users`(`UserId`),
|
||||
CONSTRAINT UC_Identifier_Key UNIQUE (`Identifier`,`Key`)
|
||||
CONSTRAINT UC_Identifier_Key UNIQUE (`Identifier`,`Key`),
|
||||
CONSTRAINT UC_Key UNIQUE (`Key`)
|
||||
);
|
||||
"""
|
||||
)
|
||||
|
@ -4,7 +4,7 @@ from bot_data.db_context import DBContext
|
||||
|
||||
|
||||
class AutoRoleFix1Migration(MigrationABC):
|
||||
name = "0.3.0_AutoRoleMigration"
|
||||
name = "0.3.0_AutoRoleFixMigration"
|
||||
|
||||
def __init__(self, logger: DatabaseLogger, db: DBContext):
|
||||
MigrationABC.__init__(self)
|
||||
|
@ -54,6 +54,15 @@ class ApiKey(TableABC):
|
||||
"""
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_select_by_key(key: str) -> str:
|
||||
return str(
|
||||
f"""
|
||||
SELECT * FROM `ApiKeys`
|
||||
WHERE `Key` = '{key}';
|
||||
"""
|
||||
)
|
||||
|
||||
@property
|
||||
def insert_string(self) -> str:
|
||||
return str(
|
||||
|
@ -1,7 +1,6 @@
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.database.context import DatabaseContextABC
|
||||
from cpl_core.utils import CredentialManager
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
@ -32,10 +31,6 @@ class ApiKeyRepositoryService(ApiKeyRepositoryABC):
|
||||
return value
|
||||
|
||||
def _api_key_from_result(self, sql_result: tuple) -> ApiKey:
|
||||
code = self._get_value_from_result(sql_result[3])
|
||||
if code is not None:
|
||||
code = CredentialManager.decrypt(code)
|
||||
|
||||
api_key = ApiKey(
|
||||
self._get_value_from_result(sql_result[1]),
|
||||
self._get_value_from_result(sql_result[2]),
|
||||
@ -58,7 +53,11 @@ class ApiKeyRepositoryService(ApiKeyRepositoryABC):
|
||||
|
||||
def get_api_key(self, identifier: str, key: str) -> ApiKey:
|
||||
self._logger.trace(__name__, f"Send SQL command: {ApiKey.get_select_string(identifier, key)}")
|
||||
return self._get_value_from_result(self._context.select(ApiKey.get_select_string(identifier, key))[0])
|
||||
return self._api_key_from_result(self._context.select(ApiKey.get_select_string(identifier, key))[0])
|
||||
|
||||
def get_api_key_by_key(self, key: str) -> ApiKey:
|
||||
self._logger.trace(__name__, f"Send SQL command: {ApiKey.get_select_by_key(key)}")
|
||||
return self._api_key_from_result(self._context.select(ApiKey.get_select_by_key(key))[0])
|
||||
|
||||
def add_api_key(self, api_key: ApiKey):
|
||||
self._logger.trace(__name__, f"Send SQL command: {api_key.insert_string}")
|
||||
|
139
kdb-bot/src/modules/technician/command/api_key_group.py
Normal file
139
kdb-bot/src/modules/technician/command/api_key_group.py
Normal file
@ -0,0 +1,139 @@
|
||||
import hashlib
|
||||
import uuid
|
||||
from typing import List as TList
|
||||
|
||||
import discord
|
||||
from cpl_core.database.context import DatabaseContextABC
|
||||
from cpl_discord.command import DiscordCommandABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from cpl_translation import TranslatePipe
|
||||
from discord import app_commands
|
||||
from discord.ext import commands
|
||||
from discord.ext.commands import Context
|
||||
|
||||
from bot_api.configuration.authentication_settings import AuthenticationSettings
|
||||
from bot_core.abc.client_utils_abc import ClientUtilsABC
|
||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
||||
from bot_core.helper.command_checks import CommandChecks
|
||||
from bot_core.logging.command_logger import CommandLogger
|
||||
from bot_data.abc.api_key_repository_abc import ApiKeyRepositoryABC
|
||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
||||
from bot_data.model.api_key import ApiKey
|
||||
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
||||
|
||||
|
||||
class ApiKeyGroup(DiscordCommandABC):
|
||||
def __init__(
|
||||
self,
|
||||
logger: CommandLogger,
|
||||
auth_settings: AuthenticationSettings,
|
||||
message_service: MessageServiceABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
client_utils: ClientUtilsABC,
|
||||
permission_service: PermissionServiceABC,
|
||||
translate: TranslatePipe,
|
||||
db: DatabaseContextABC,
|
||||
servers: ServerRepositoryABC,
|
||||
users: UserRepositoryABC,
|
||||
api_keys: ApiKeyRepositoryABC,
|
||||
):
|
||||
DiscordCommandABC.__init__(self)
|
||||
|
||||
self._logger = logger
|
||||
self._auth_settings = auth_settings
|
||||
self._message_service = message_service
|
||||
self._bot = bot
|
||||
self._client_utils = client_utils
|
||||
self._permissions = permission_service
|
||||
self._t = translate
|
||||
self._db = db
|
||||
self._servers = servers
|
||||
self._users = users
|
||||
self._api_keys = api_keys
|
||||
|
||||
def _get_api_key_str(self, api_key: ApiKey) -> str:
|
||||
return hashlib.sha256(
|
||||
f"{api_key.identifier}:{api_key.key}+{self._auth_settings.secret_key}".encode("utf-8")
|
||||
).hexdigest()
|
||||
|
||||
@commands.hybrid_group(name="api-key")
|
||||
@commands.guild_only()
|
||||
async def api_key(self, ctx: Context):
|
||||
pass
|
||||
|
||||
@api_key.command()
|
||||
@commands.guild_only()
|
||||
@CommandChecks.check_is_ready()
|
||||
@CommandChecks.check_is_member_technician()
|
||||
async def get(self, ctx: Context, key: str, wait: int = None):
|
||||
self._logger.debug(__name__, f"Received command api-key get {ctx}: {key},{wait}")
|
||||
|
||||
api_key = self._api_keys.get_api_key_by_key(key)
|
||||
await self._message_service.send_ctx_msg(
|
||||
ctx,
|
||||
self._t.transform("modules.technician.api_key.get").format(
|
||||
api_key.identifier, self._get_api_key_str(api_key)
|
||||
),
|
||||
)
|
||||
self._logger.trace(__name__, f"Finished command api-key get")
|
||||
|
||||
@get.autocomplete("key")
|
||||
async def get_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]:
|
||||
keys = self._api_keys.get_api_keys()
|
||||
|
||||
return [
|
||||
app_commands.Choice(name=f"{key.identifier}: {key.key}", value=key.key)
|
||||
for key in self._client_utils.get_auto_complete_list(keys, current, lambda x: x.key)
|
||||
]
|
||||
|
||||
@api_key.command()
|
||||
@commands.guild_only()
|
||||
@CommandChecks.check_is_ready()
|
||||
@CommandChecks.check_is_member_moderator()
|
||||
async def add(self, ctx: Context, identifier: str):
|
||||
self._logger.debug(__name__, f"Received command api-key add {ctx}: {identifier}")
|
||||
|
||||
server = self._servers.get_server_by_discord_id(ctx.guild.id)
|
||||
user = self._users.get_user_by_discord_id_and_server_id(ctx.author.id, server.server_id)
|
||||
api_key = ApiKey(identifier, str(uuid.uuid4()), user)
|
||||
self._api_keys.add_api_key(api_key)
|
||||
self._db.save_changes()
|
||||
await self._message_service.send_ctx_msg(
|
||||
ctx,
|
||||
self._t.transform("modules.technician.api_key.add.success").format(
|
||||
identifier, self._get_api_key_str(api_key)
|
||||
),
|
||||
)
|
||||
|
||||
self._logger.trace(__name__, f"Finished command api-key add")
|
||||
|
||||
@api_key.command()
|
||||
@commands.guild_only()
|
||||
@CommandChecks.check_is_ready()
|
||||
@CommandChecks.check_is_member_moderator()
|
||||
async def remove(self, ctx: Context, key: str):
|
||||
self._logger.debug(__name__, f"Received command api-key remove {ctx}: {key}")
|
||||
|
||||
keys = self._api_keys.get_api_keys().where(lambda x: x.key == key)
|
||||
if keys.count() < 1:
|
||||
await self._message_service.send_ctx_msg(
|
||||
ctx,
|
||||
self._t.transform("modules.technician.api_key.remove.not_found"),
|
||||
)
|
||||
|
||||
api_key = keys.single()
|
||||
self._api_keys.delete_api_key(api_key)
|
||||
self._db.save_changes()
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.technician.api_key.remove.success"))
|
||||
|
||||
self._logger.trace(__name__, f"Finished command api-key remove")
|
||||
|
||||
@remove.autocomplete("key")
|
||||
async def set_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]:
|
||||
keys = self._api_keys.get_api_keys()
|
||||
|
||||
return [
|
||||
app_commands.Choice(name=f"{key.identifier}: {key.key}", value=key.key)
|
||||
for key in self._client_utils.get_auto_complete_list(keys, current, lambda x: x.key)
|
||||
]
|
@ -6,10 +6,11 @@ from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
||||
from bot_core.abc.module_abc import ModuleABC
|
||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||
from modules.base.abc.base_helper_abc import BaseHelperABC
|
||||
from modules.base.service.base_helper_service import BaseHelperService
|
||||
from modules.technician.command.api_key_group import ApiKeyGroup
|
||||
from modules.technician.command.log_command import LogCommand
|
||||
from modules.technician.command.restart_command import RestartCommand
|
||||
from modules.technician.command.shutdown_command import ShutdownCommand
|
||||
from modules.base.service.base_helper_service import BaseHelperService
|
||||
|
||||
|
||||
class TechnicianModule(ModuleABC):
|
||||
@ -25,4 +26,5 @@ class TechnicianModule(ModuleABC):
|
||||
self._dc.add_command(RestartCommand)
|
||||
self._dc.add_command(ShutdownCommand)
|
||||
self._dc.add_command(LogCommand)
|
||||
self._dc.add_command(ApiKeyGroup)
|
||||
# events
|
||||
|
Loading…
Reference in New Issue
Block a user