Compare commits
	
		
			36 Commits
		
	
	
		
			1.1.8
			...
			dd6b609094
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| dd6b609094 | |||
| 3810dec927 | |||
| a87380f6f8 | |||
| 98ac7835b6 | |||
| 0a76068604 | |||
| f9caf59180 | |||
| 284318bb10 | |||
| 6130cac6fe | |||
| 3a64c51600 | |||
| 90fce5a79a | |||
| d448ad7707 | |||
| 19791ff9d8 | |||
| 3cba8de675 | |||
| b7ff070676 | |||
| c88e07d743 | |||
| f5b978b231 | |||
| 0e2b7d03fc | |||
| c7f5ab0161 | |||
| 01e8e4256d | |||
| 75adc2285e | |||
| 9e12d84ba0 | |||
| d3b503d3ef | |||
| dd86c3a657 | |||
| aba6e48e2b | |||
| 73848c3141 | |||
| 33d6015088 | |||
| 7e962e05f6 | |||
| c73c6876b2 | |||
| 8e949c3e1a | |||
| 472a76d563 | |||
| f5d88ec94c | |||
| 2182c021b9 | |||
| a9c9880fd4 | |||
| d91c76467d | |||
| 2f10ace27f | |||
| 0ed93c56d0 | 
							
								
								
									
										18
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -1,9 +1,9 @@ | |||||||
| [submodule "kdb-bot/src/bot/config"] | [submodule "bot/src/bot/config"] | ||||||
| 	path = kdb-bot/src/bot/config | 	path = bot/src/bot/config | ||||||
| 	url = https://git.sh-edraft.de/sh-edraft.de/kd_discord_bot.config.git | 	url = https://git.sh-edraft.de/sh-edraft.de/sh_discord_bot.config.git | ||||||
| [submodule "kdb-bot/src/bot_api/config"] | [submodule "bot/src/bot_api/config"] | ||||||
| 	path = kdb-bot/src/bot_api/config | 	path = bot/src/bot_api/config | ||||||
| 	url = https://git.sh-edraft.de/sh-edraft.de/kd_discord_bot.api.config.git | 	url = https://git.sh-edraft.de/sh-edraft.de/sh_discord_bot.api.config.git | ||||||
| [submodule "kdb-bot/docker"] | [submodule "bot/docker"] | ||||||
| 	path = kdb-bot/docker | 	path = bot/docker | ||||||
| 	url = https://git.sh-edraft.de/sh-edraft.de/kd_discord_bot.docker.git | 	url = https://git.sh-edraft.de/sh-edraft.de/sh_discord_bot.docker.git | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ | |||||||
|       "permission": "src/modules/permission/permission.json", |       "permission": "src/modules/permission/permission.json", | ||||||
|       "technician": "src/modules/technician/technician.json", |       "technician": "src/modules/technician/technician.json", | ||||||
|       "short-role-name": "src/modules/short_role_name/short-role-name.json", |       "short-role-name": "src/modules/short_role_name/short-role-name.json", | ||||||
|  |       "special-offers": "src/modules/special_offers/special-offers.json", | ||||||
|       "checks": "tools/checks/checks.json", |       "checks": "tools/checks/checks.json", | ||||||
|       "get-version": "tools/get_version/get-version.json", |       "get-version": "tools/get_version/get-version.json", | ||||||
|       "post-build": "tools/post_build/post-build.json", |       "post-build": "tools/post_build/post-build.json", | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -8,6 +8,7 @@ from cpl_discord.service import DiscordBotServiceABC, DiscordBotService | |||||||
| from cpl_translation import TranslatePipe, TranslationServiceABC, TranslationSettings | from cpl_translation import TranslatePipe, TranslationServiceABC, TranslationSettings | ||||||
| 
 | 
 | ||||||
| from bot_api.api_thread import ApiThread | from bot_api.api_thread import ApiThread | ||||||
|  | from bot_core.abc.task_abc import TaskABC | ||||||
| from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
| from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_core.service.data_integrity_service import DataIntegrityService | from bot_core.service.data_integrity_service import DataIntegrityService | ||||||
| @@ -22,15 +23,25 @@ class Application(DiscordBotApplicationABC): | |||||||
| 
 | 
 | ||||||
|         # cpl-core |         # cpl-core | ||||||
|         self._logger: LoggerABC = services.get_service(LoggerABC) |         self._logger: LoggerABC = services.get_service(LoggerABC) | ||||||
|         self._data_integrity: DataIntegrityService = services.get_service(DataIntegrityService) |         self._data_integrity: DataIntegrityService = services.get_service( | ||||||
|  |             DataIntegrityService | ||||||
|  |         ) | ||||||
|         # cpl-discord |         # cpl-discord | ||||||
|         self._bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC) |         self._bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC) | ||||||
|         self._bot_settings: DiscordBotSettings = config.get_configuration(DiscordBotSettings) |         self._bot_settings: DiscordBotSettings = config.get_configuration( | ||||||
|  |             DiscordBotSettings | ||||||
|  |         ) | ||||||
|         # cpl-translation |         # cpl-translation | ||||||
|         self._translation: TranslationServiceABC = services.get_service(TranslationServiceABC) |         self._translation: TranslationServiceABC = services.get_service( | ||||||
|  |             TranslationServiceABC | ||||||
|  |         ) | ||||||
|         self._t: TranslatePipe = services.get_service(TranslatePipe) |         self._t: TranslatePipe = services.get_service(TranslatePipe) | ||||||
|  |         # internal stuff | ||||||
|  |         self._tasks = services.get_services(TaskABC) | ||||||
| 
 | 
 | ||||||
|         self._feature_flags: FeatureFlagsSettings = config.get_configuration(FeatureFlagsSettings) |         self._feature_flags: FeatureFlagsSettings = config.get_configuration( | ||||||
|  |             FeatureFlagsSettings | ||||||
|  |         ) | ||||||
| 
 | 
 | ||||||
|         # api |         # api | ||||||
|         if self._feature_flags.get_flag(FeatureFlagsEnum.api_module): |         if self._feature_flags.get_flag(FeatureFlagsEnum.api_module): | ||||||
| @@ -39,7 +50,9 @@ class Application(DiscordBotApplicationABC): | |||||||
|         self._is_stopping = False |         self._is_stopping = False | ||||||
| 
 | 
 | ||||||
|     async def configure(self): |     async def configure(self): | ||||||
|         self._translation.load_by_settings(self._configuration.get_configuration(TranslationSettings)) |         self._translation.load_by_settings( | ||||||
|  |             self._configuration.get_configuration(TranslationSettings) | ||||||
|  |         ) | ||||||
| 
 | 
 | ||||||
|     async def main(self): |     async def main(self): | ||||||
|         try: |         try: | ||||||
| @@ -55,6 +68,9 @@ class Application(DiscordBotApplicationABC): | |||||||
|                 return |                 return | ||||||
| 
 | 
 | ||||||
|             self._logger.info(__name__, f"Try to start {DiscordBotService.__name__}") |             self._logger.info(__name__, f"Try to start {DiscordBotService.__name__}") | ||||||
|  |             for task in self._tasks: | ||||||
|  |                 await self._bot.add_cog(task) | ||||||
|  | 
 | ||||||
|             await self._bot.start_async() |             await self._bot.start_async() | ||||||
|             await self._bot.stop_async() |             await self._bot.stop_async() | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
| @@ -79,4 +95,8 @@ class Application(DiscordBotApplicationABC): | |||||||
|         Console.write_line() |         Console.write_line() | ||||||
| 
 | 
 | ||||||
|     def is_restart(self): |     def is_restart(self): | ||||||
|         return True if self._configuration.get_configuration("IS_RESTART") == "true" else False |         return ( | ||||||
|  |             True | ||||||
|  |             if self._configuration.get_configuration("IS_RESTART") == "true" | ||||||
|  |             else False | ||||||
|  |         ) | ||||||
| @@ -3,8 +3,8 @@ | |||||||
|     "Name": "bot", |     "Name": "bot", | ||||||
|     "Version": { |     "Version": { | ||||||
|       "Major": "1", |       "Major": "1", | ||||||
|       "Minor": "1", |       "Minor": "2", | ||||||
|       "Micro": "8" |       "Micro": "0" | ||||||
|     }, |     }, | ||||||
|     "Author": "Sven Heidemann", |     "Author": "Sven Heidemann", | ||||||
|     "AuthorEmail": "sven.heidemann@sh-edraft.de", |     "AuthorEmail": "sven.heidemann@sh-edraft.de", | ||||||
| @@ -16,22 +16,22 @@ | |||||||
|     "LicenseName": "MIT", |     "LicenseName": "MIT", | ||||||
|     "LicenseDescription": "MIT, see LICENSE for more details.", |     "LicenseDescription": "MIT, see LICENSE for more details.", | ||||||
|     "Dependencies": [ |     "Dependencies": [ | ||||||
|       "cpl-core==2023.4.0.post5", |       "cpl-core==2023.10.0", | ||||||
|       "cpl-translation==2023.4.0.post1", |       "cpl-translation==2023.4.0.post1", | ||||||
|       "cpl-query==2023.4.0.post1", |       "cpl-query==2023.10.0", | ||||||
|       "cpl-discord==2023.4.0.post3", |       "cpl-discord==2023.10.0.post1", | ||||||
|       "Flask==2.3.2", |       "Flask==3.0.0", | ||||||
|       "Flask-Classful==0.14.2", |       "Flask-Classful==0.16.0", | ||||||
|       "Flask-Cors==4.0.0", |       "Flask-Cors==4.0.0", | ||||||
|       "PyJWT==2.8.0", |       "PyJWT==2.8.0", | ||||||
|       "waitress==2.1.2", |       "waitress==2.1.2", | ||||||
|       "Flask-SocketIO==5.3.4", |       "Flask-SocketIO==5.3.6", | ||||||
|       "eventlet==0.33.3", |       "eventlet==0.33.3", | ||||||
|       "requests-oauthlib==1.3.1", |       "requests-oauthlib==1.3.1", | ||||||
|       "icmplib==3.0.3", |       "icmplib==3.0.4", | ||||||
|       "ariadne==0.20.1", |       "ariadne==0.20.1", | ||||||
|       "cryptography==41.0.2", |       "cryptography==41.0.4", | ||||||
|       "discord>=2.3.2" |       "discord==2.3.2" | ||||||
|     ], |     ], | ||||||
|     "DevDependencies": [ |     "DevDependencies": [ | ||||||
|       "cpl-cli==2023.4.0.post3", |       "cpl-cli==2023.4.0.post3", | ||||||
| @@ -69,6 +69,7 @@ | |||||||
|       "../modules/level/level.json", |       "../modules/level/level.json", | ||||||
|       "../modules/permission/permission.json", |       "../modules/permission/permission.json", | ||||||
|       "../modules/short_role_name/short-role-name.json", |       "../modules/short_role_name/short-role-name.json", | ||||||
|  |       "../modules/special_offers/special-offers.json", | ||||||
|       "../modules/technician/technician.json" |       "../modules/technician/technician.json" | ||||||
|     ] |     ] | ||||||
|   } |   } | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot.extension" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -13,4 +13,6 @@ class InitBotExtension(ApplicationExtensionABC): | |||||||
|     async def run(self, config: ConfigurationABC, services: ServiceProviderABC): |     async def run(self, config: ConfigurationABC, services: ServiceProviderABC): | ||||||
|         settings = config.get_configuration(TechnicianConfig) |         settings = config.get_configuration(TechnicianConfig) | ||||||
| 
 | 
 | ||||||
|         bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC, max_messages=settings.cache_max_messages) |         bot: DiscordBotServiceABC = services.get_service( | ||||||
|  |             DiscordBotServiceABC, max_messages=settings.cache_max_messages | ||||||
|  |         ) | ||||||
| @@ -14,6 +14,7 @@ from modules.database.database_module import DatabaseModule | |||||||
| from modules.level.level_module import LevelModule | from modules.level.level_module import LevelModule | ||||||
| from modules.permission.permission_module import PermissionModule | from modules.permission.permission_module import PermissionModule | ||||||
| from modules.short_role_name.short_role_name_module import ShortRoleNameModule | from modules.short_role_name.short_role_name_module import ShortRoleNameModule | ||||||
|  | from modules.special_offers.special_offers_module import SteamSpecialOffersModule | ||||||
| from modules.technician.technician_module import TechnicianModule | from modules.technician.technician_module import TechnicianModule | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @@ -37,6 +38,7 @@ class ModuleList: | |||||||
|                 TechnicianModule, |                 TechnicianModule, | ||||||
|                 AchievementsModule, |                 AchievementsModule, | ||||||
|                 ShortRoleNameModule, |                 ShortRoleNameModule, | ||||||
|  |                 SteamSpecialOffersModule, | ||||||
|                 # has to be last! |                 # has to be last! | ||||||
|                 BootLogModule, |                 BootLogModule, | ||||||
|                 CoreExtensionModule, |                 CoreExtensionModule, | ||||||
| @@ -16,6 +16,7 @@ from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | |||||||
| from bot_core.logging.command_logger import CommandLogger | from bot_core.logging.command_logger import CommandLogger | ||||||
| from bot_core.logging.database_logger import DatabaseLogger | from bot_core.logging.database_logger import DatabaseLogger | ||||||
| from bot_core.logging.message_logger import MessageLogger | from bot_core.logging.message_logger import MessageLogger | ||||||
|  | from bot_core.logging.task_logger import TaskLogger | ||||||
| from bot_data.db_context import DBContext | from bot_data.db_context import DBContext | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @@ -43,12 +44,15 @@ class Startup(StartupABC): | |||||||
|             services.add_singleton(CustomFileLoggerABC, CommandLogger) |             services.add_singleton(CustomFileLoggerABC, CommandLogger) | ||||||
|             services.add_singleton(CustomFileLoggerABC, DatabaseLogger) |             services.add_singleton(CustomFileLoggerABC, DatabaseLogger) | ||||||
|             services.add_singleton(CustomFileLoggerABC, MessageLogger) |             services.add_singleton(CustomFileLoggerABC, MessageLogger) | ||||||
|  |             services.add_singleton(CustomFileLoggerABC, TaskLogger) | ||||||
| 
 | 
 | ||||||
|         if self._feature_flags.get_flag(FeatureFlagsEnum.api_module): |         if self._feature_flags.get_flag(FeatureFlagsEnum.api_module): | ||||||
|             services.add_singleton(CustomFileLoggerABC, ApiLogger) |             services.add_singleton(CustomFileLoggerABC, ApiLogger) | ||||||
| 
 | 
 | ||||||
|         services.add_translation() |         services.add_translation() | ||||||
|         services.add_db_context(DBContext, self._config.get_configuration(DatabaseSettings)) |         services.add_db_context( | ||||||
|  |             DBContext, self._config.get_configuration(DatabaseSettings) | ||||||
|  |         ) | ||||||
| 
 | 
 | ||||||
|         provider = services.build_service_provider() |         provider = services.build_service_provider() | ||||||
|         # instantiate custom logger |         # instantiate custom logger | ||||||
| @@ -9,9 +9,13 @@ class StartupDiscordExtension(StartupExtensionABC): | |||||||
|     def __init__(self): |     def __init__(self): | ||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
|     def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): |     def configure_configuration( | ||||||
|  |         self, config: ConfigurationABC, env: ApplicationEnvironmentABC | ||||||
|  |     ): | ||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
|     def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): |     def configure_services( | ||||||
|  |         self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC | ||||||
|  |     ): | ||||||
|         services.add_discord() |         services.add_discord() | ||||||
|         dcc = get_discord_collection(services) |         dcc = get_discord_collection(services) | ||||||
							
								
								
									
										106
									
								
								bot/src/bot/startup_migration_extension.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								bot/src/bot/startup_migration_extension.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | |||||||
|  | from cpl_core.application import StartupExtensionABC | ||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
|  | from cpl_core.dependency_injection import ServiceCollectionABC | ||||||
|  | from cpl_core.environment import ApplicationEnvironmentABC | ||||||
|  |  | ||||||
|  | from bot_data.abc.migration_abc import MigrationABC | ||||||
|  | from bot_data.migration.achievements_migration import AchievementsMigration | ||||||
|  | from bot_data.migration.api_key_migration import ApiKeyMigration | ||||||
|  | from bot_data.migration.api_migration import ApiMigration | ||||||
|  | from bot_data.migration.auto_role_fix1_migration import AutoRoleFix1Migration | ||||||
|  | from bot_data.migration.auto_role_migration import AutoRoleMigration | ||||||
|  | from bot_data.migration.birthday_migration import BirthdayMigration | ||||||
|  | from bot_data.migration.config_feature_flags_migration import ( | ||||||
|  |     ConfigFeatureFlagsMigration, | ||||||
|  | ) | ||||||
|  | from bot_data.migration.config_migration import ConfigMigration | ||||||
|  | from bot_data.migration.db_history_migration import DBHistoryMigration | ||||||
|  | from bot_data.migration.default_role_migration import DefaultRoleMigration | ||||||
|  | from bot_data.migration.fix_updates_migration import FixUpdatesMigration | ||||||
|  | from bot_data.migration.fix_user_history_migration import FixUserHistoryMigration | ||||||
|  | from bot_data.migration.initial_migration import InitialMigration | ||||||
|  | from bot_data.migration.level_migration import LevelMigration | ||||||
|  | from bot_data.migration.remove_stats_migration import RemoveStatsMigration | ||||||
|  | from bot_data.migration.short_role_name_migration import ShortRoleNameMigration | ||||||
|  | from bot_data.migration.short_role_name_only_highest_migration import ( | ||||||
|  |     ShortRoleNameOnlyHighestMigration, | ||||||
|  | ) | ||||||
|  | from bot_data.migration.stats_migration import StatsMigration | ||||||
|  | from bot_data.migration.steam_special_offer_migration import SteamSpecialOfferMigration | ||||||
|  | from bot_data.migration.user_joined_game_server_migration import ( | ||||||
|  |     UserJoinedGameServerMigration, | ||||||
|  | ) | ||||||
|  | from bot_data.migration.user_message_count_per_hour_migration import ( | ||||||
|  |     UserMessageCountPerHourMigration, | ||||||
|  | ) | ||||||
|  | from bot_data.migration.user_warning_migration import UserWarningMigration | ||||||
|  | from bot_data.service.migration_service import MigrationService | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class StartupMigrationExtension(StartupExtensionABC): | ||||||
|  |     def __init__(self): | ||||||
|  |         pass | ||||||
|  |  | ||||||
|  |     def configure_configuration( | ||||||
|  |         self, config: ConfigurationABC, env: ApplicationEnvironmentABC | ||||||
|  |     ): | ||||||
|  |         pass | ||||||
|  |  | ||||||
|  |     def configure_services( | ||||||
|  |         self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC | ||||||
|  |     ): | ||||||
|  |         services.add_transient(MigrationService) | ||||||
|  |         services.add_transient(MigrationABC, InitialMigration) | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, AutoRoleMigration | ||||||
|  |         )  # 03.10.2022 #54 - 0.2.2 | ||||||
|  |         services.add_transient(MigrationABC, ApiMigration)  # 15.10.2022 #70 - 0.3.0 | ||||||
|  |         services.add_transient(MigrationABC, LevelMigration)  # 06.11.2022 #25 - 0.3.0 | ||||||
|  |         services.add_transient(MigrationABC, StatsMigration)  # 09.11.2022 #46 - 0.3.0 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, AutoRoleFix1Migration | ||||||
|  |         )  # 30.12.2022 #151 - 0.3.0 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, UserMessageCountPerHourMigration | ||||||
|  |         )  # 11.01.2023 #168 - 0.3.1 | ||||||
|  |         services.add_transient(MigrationABC, ApiKeyMigration)  # 09.02.2023 #162 - 1.0.0 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, UserJoinedGameServerMigration | ||||||
|  |         )  # 12.02.2023 #181 - 1.0.0 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, RemoveStatsMigration | ||||||
|  |         )  # 19.02.2023 #190 - 1.0.0 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, UserWarningMigration | ||||||
|  |         )  # 21.02.2023 #35 - 1.0.0 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, DBHistoryMigration | ||||||
|  |         )  # 06.03.2023 #246 - 1.0.0 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, AchievementsMigration | ||||||
|  |         )  # 14.06.2023 #268 - 1.1.0 | ||||||
|  |         services.add_transient(MigrationABC, ConfigMigration)  # 19.07.2023 #127 - 1.1.0 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, ConfigFeatureFlagsMigration | ||||||
|  |         )  # 15.08.2023 #334 - 1.1.0 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, DefaultRoleMigration | ||||||
|  |         )  # 24.09.2023 #360 - 1.1.3 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, ShortRoleNameMigration | ||||||
|  |         )  # 28.09.2023 #378 - 1.1.7 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, FixUpdatesMigration | ||||||
|  |         )  # 28.09.2023 #378 - 1.1.7 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, ShortRoleNameOnlyHighestMigration | ||||||
|  |         )  # 02.10.2023 #391 - 1.1.9 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, FixUserHistoryMigration | ||||||
|  |         )  # 10.10.2023 #401 - 1.2.0 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, BirthdayMigration | ||||||
|  |         )  # 10.10.2023 #401 - 1.2.0 | ||||||
|  |         services.add_transient( | ||||||
|  |             MigrationABC, SteamSpecialOfferMigration | ||||||
|  |         )  # 10.10.2023 #188 - 1.2.0 | ||||||
| @@ -18,11 +18,15 @@ class StartupModuleExtension(StartupExtensionABC): | |||||||
| 
 | 
 | ||||||
|         self._modules = ModuleList.get_modules() |         self._modules = ModuleList.get_modules() | ||||||
| 
 | 
 | ||||||
|     def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): |     def configure_configuration( | ||||||
|  |         self, config: ConfigurationABC, env: ApplicationEnvironmentABC | ||||||
|  |     ): | ||||||
|         self._config = config |         self._config = config | ||||||
|         self._feature_flags = config.get_configuration(FeatureFlagsSettings) |         self._feature_flags = config.get_configuration(FeatureFlagsSettings) | ||||||
| 
 | 
 | ||||||
|     def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): |     def configure_services( | ||||||
|  |         self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC | ||||||
|  |     ): | ||||||
|         provider = services.build_service_provider() |         provider = services.build_service_provider() | ||||||
|         dc_collection: DiscordCollectionABC = provider.get_service(DiscordCollectionABC) |         dc_collection: DiscordCollectionABC = provider.get_service(DiscordCollectionABC) | ||||||
| 
 | 
 | ||||||
| @@ -14,26 +14,38 @@ class StartupSettingsExtension(StartupExtensionABC): | |||||||
|     def __init__(self): |     def __init__(self): | ||||||
|         self._start_time = datetime.now() |         self._start_time = datetime.now() | ||||||
| 
 | 
 | ||||||
|     def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironmentABC): |     def configure_configuration( | ||||||
|  |         self, configuration: ConfigurationABC, environment: ApplicationEnvironmentABC | ||||||
|  |     ): | ||||||
|         # this shit has to be done here because we need settings in subsequent startup extensions |         # this shit has to be done here because we need settings in subsequent startup extensions | ||||||
|         environment.set_working_directory(os.path.dirname(os.path.realpath(__file__))) |         environment.set_working_directory(os.path.dirname(os.path.realpath(__file__))) | ||||||
|         configuration.add_environment_variables("KDB_") |         configuration.add_environment_variables("KDB_") | ||||||
|         configuration.add_environment_variables("DISCORD_") |         configuration.add_environment_variables("DISCORD_") | ||||||
| 
 | 
 | ||||||
|         configuration.add_json_file(f"config/appsettings.json", optional=False) |         configuration.add_json_file(f"config/appsettings.json", optional=False) | ||||||
|         configuration.add_json_file(f"config/appsettings.{environment.environment_name}.json", optional=True) |         configuration.add_json_file( | ||||||
|         configuration.add_json_file(f"config/appsettings.{environment.host_name}.json", optional=True) |             f"config/appsettings.{environment.environment_name}.json", optional=True | ||||||
|  |         ) | ||||||
|  |         configuration.add_json_file( | ||||||
|  |             f"config/appsettings.{environment.host_name}.json", optional=True | ||||||
|  |         ) | ||||||
|         # load feature-flags |         # load feature-flags | ||||||
|         configuration.add_json_file(f"config/feature-flags.json", optional=False) |         configuration.add_json_file(f"config/feature-flags.json", optional=False) | ||||||
|         configuration.add_json_file(f"config/feature-flags.{environment.environment_name}.json", optional=True) |         configuration.add_json_file( | ||||||
|         configuration.add_json_file(f"config/feature-flags.{environment.host_name}.json", optional=True) |             f"config/feature-flags.{environment.environment_name}.json", optional=True | ||||||
|  |         ) | ||||||
|  |         configuration.add_json_file( | ||||||
|  |             f"config/feature-flags.{environment.host_name}.json", optional=True | ||||||
|  |         ) | ||||||
| 
 | 
 | ||||||
|         configuration.add_configuration("Startup_StartTime", str(self._start_time)) |         configuration.add_configuration("Startup_StartTime", str(self._start_time)) | ||||||
|         self._configure_settings_with_sub_settings( |         self._configure_settings_with_sub_settings( | ||||||
|             configuration, BotLoggingSettings, lambda x: x.files, lambda x: x.key |             configuration, BotLoggingSettings, lambda x: x.files, lambda x: x.key | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): |     def configure_services( | ||||||
|  |         self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC | ||||||
|  |     ): | ||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
| @@ -45,4 +57,6 @@ class StartupSettingsExtension(StartupExtensionABC): | |||||||
|             return |             return | ||||||
| 
 | 
 | ||||||
|         for sub_settings in list_atr(settings): |         for sub_settings in list_atr(settings): | ||||||
|             config.add_configuration(f"{type(sub_settings).__name__}_{atr(sub_settings)}", sub_settings) |             config.add_configuration( | ||||||
|  |                 f"{type(sub_settings).__name__}_{atr(sub_settings)}", sub_settings | ||||||
|  |             ) | ||||||
| @@ -94,6 +94,11 @@ | |||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   "modules": { |   "modules": { | ||||||
|  |     "special_offers": { | ||||||
|  |       "price": "Preis", | ||||||
|  |       "discount": "Rabatt", | ||||||
|  |       "discount_price": "Neuer Preis" | ||||||
|  |     }, | ||||||
|     "achievements": { |     "achievements": { | ||||||
|       "commands": { |       "commands": { | ||||||
|         "check": "Alles klar, ich schaue eben nach... nom nom" |         "check": "Alles klar, ich schaue eben nach... nom nom" | ||||||
| @@ -229,6 +234,11 @@ | |||||||
|         "success": "Verlinkung wurde entfernt :D" |         "success": "Verlinkung wurde entfernt :D" | ||||||
|       }, |       }, | ||||||
|       "user": { |       "user": { | ||||||
|  |         "birthday": { | ||||||
|  |           "has_birthday": "Alles Gute zum Geburtag {} :D", | ||||||
|  |           "success": "Dein Geburtstag wurde eingetragen.", | ||||||
|  |           "success_team": "{} hat seinen Geburtstag eingetragen: {}" | ||||||
|  |         }, | ||||||
|         "add": { |         "add": { | ||||||
|           "xp": "Die {} von {} wurden um {} erhöht" |           "xp": "Die {} von {} wurden um {} erhöht" | ||||||
|         }, |         }, | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.abc" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -40,11 +40,15 @@ class AuthServiceABC(ABC): | |||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
|     async def get_filtered_auth_users_async(self, criteria: AuthUserSelectCriteria) -> AuthUserFilteredResultDTO: |     async def get_filtered_auth_users_async( | ||||||
|  |         self, criteria: AuthUserSelectCriteria | ||||||
|  |     ) -> AuthUserFilteredResultDTO: | ||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
|     async def get_auth_user_by_email_async(self, email: str, with_password: bool = False) -> AuthUserDTO: |     async def get_auth_user_by_email_async( | ||||||
|  |         self, email: str, with_password: bool = False | ||||||
|  |     ) -> AuthUserDTO: | ||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
| @@ -3,7 +3,9 @@ from abc import ABC, abstractmethod | |||||||
| 
 | 
 | ||||||
| class SelectCriteriaABC(ABC): | class SelectCriteriaABC(ABC): | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
|     def __init__(self, page_index: int, page_size: int, sort_direction: str, sort_column: str): |     def __init__( | ||||||
|  |         self, page_index: int, page_size: int, sort_direction: str, sort_column: str | ||||||
|  |     ): | ||||||
|         self.page_index = page_index |         self.page_index = page_index | ||||||
|         self.page_size = page_size |         self.page_size = page_size | ||||||
|         self.sort_direction = sort_direction |         self.sort_direction = sort_direction | ||||||
| @@ -57,7 +57,9 @@ class Api(Flask): | |||||||
|         # Added async_mode see link below |         # Added async_mode see link below | ||||||
|         # https://github.com/miguelgrinberg/Flask-SocketIO/discussions/1849 |         # https://github.com/miguelgrinberg/Flask-SocketIO/discussions/1849 | ||||||
|         # https://stackoverflow.com/questions/39370848/flask-socket-io-sometimes-client-calls-freeze-the-server |         # https://stackoverflow.com/questions/39370848/flask-socket-io-sometimes-client-calls-freeze-the-server | ||||||
|         self._socketio = SocketIO(self, cors_allowed_origins="*", path="/api/socket.io", async_mode="eventlet") |         self._socketio = SocketIO( | ||||||
|  |             self, cors_allowed_origins="*", path="/api/socket.io", async_mode="eventlet" | ||||||
|  |         ) | ||||||
|         self._socketio.on_event("connect", self.on_connect) |         self._socketio.on_event("connect", self.on_connect) | ||||||
|         self._socketio.on_event("disconnect", self.on_disconnect) |         self._socketio.on_event("disconnect", self.on_disconnect) | ||||||
| 
 | 
 | ||||||
| @@ -143,19 +145,26 @@ class Api(Flask): | |||||||
|         data = request.get_data() |         data = request.get_data() | ||||||
|         data = "" if len(data) == 0 else str(data.decode(encoding="utf-8")) |         data = "" if len(data) == 0 else str(data.decode(encoding="utf-8")) | ||||||
| 
 | 
 | ||||||
|         text = textwrap.dedent(f"Request: {request_id}:\n\tHeader:\n\t\t{headers}\n\tResponse: {data}") |         text = textwrap.dedent( | ||||||
|  |             f"Request: {request_id}:\n\tHeader:\n\t\t{headers}\n\tResponse: {data}" | ||||||
|  |         ) | ||||||
|         self._logger.trace(__name__, text) |         self._logger.trace(__name__, text) | ||||||
| 
 | 
 | ||||||
|         return response |         return response | ||||||
| 
 | 
 | ||||||
|     def start(self): |     def start(self): | ||||||
|         self._logger.info(__name__, f"Starting API {self._api_settings.host}:{self._api_settings.port}") |         self._logger.info( | ||||||
|  |             __name__, | ||||||
|  |             f"Starting API {self._api_settings.host}:{self._api_settings.port}", | ||||||
|  |         ) | ||||||
|         self._register_routes() |         self._register_routes() | ||||||
|         self.secret_key = CredentialManager.decrypt(self._auth_settings.secret_key) |         self.secret_key = CredentialManager.decrypt(self._auth_settings.secret_key) | ||||||
|         # from waitress import serve |         # from waitress import serve | ||||||
|         # https://docs.pylonsproject.org/projects/waitress/en/stable/arguments.html |         # https://docs.pylonsproject.org/projects/waitress/en/stable/arguments.html | ||||||
|         # serve(self, host=self._apt_settings.host, port=self._apt_settings.port, threads=10, connection_limit=1000, channel_timeout=10) |         # serve(self, host=self._apt_settings.host, port=self._apt_settings.port, threads=10, connection_limit=1000, channel_timeout=10) | ||||||
|         self._socket = eventlet.listen((self._api_settings.host, self._api_settings.port)) |         self._socket = eventlet.listen( | ||||||
|  |             (self._api_settings.host, self._api_settings.port) | ||||||
|  |         ) | ||||||
|         wsgi.server(self._socket, self, log_output=False) |         wsgi.server(self._socket, self, log_output=False) | ||||||
| 
 | 
 | ||||||
|     def stop(self): |     def stop(self): | ||||||
| @@ -26,15 +26,21 @@ class ApiModule(ModuleABC): | |||||||
|     def __init__(self, dc: DiscordCollectionABC): |     def __init__(self, dc: DiscordCollectionABC): | ||||||
|         ModuleABC.__init__(self, dc, FeatureFlagsEnum.api_module) |         ModuleABC.__init__(self, dc, FeatureFlagsEnum.api_module) | ||||||
| 
 | 
 | ||||||
|     def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): |     def configure_configuration( | ||||||
|  |         self, config: ConfigurationABC, env: ApplicationEnvironmentABC | ||||||
|  |     ): | ||||||
|         cwd = env.working_directory |         cwd = env.working_directory | ||||||
|         env.set_working_directory(os.path.dirname(os.path.realpath(__file__))) |         env.set_working_directory(os.path.dirname(os.path.realpath(__file__))) | ||||||
|         config.add_json_file(f"config/apisettings.json", optional=False) |         config.add_json_file(f"config/apisettings.json", optional=False) | ||||||
|         config.add_json_file(f"config/apisettings.{env.environment_name}.json", optional=True) |         config.add_json_file( | ||||||
|  |             f"config/apisettings.{env.environment_name}.json", optional=True | ||||||
|  |         ) | ||||||
|         config.add_json_file(f"config/apisettings.{env.host_name}.json", optional=True) |         config.add_json_file(f"config/apisettings.{env.host_name}.json", optional=True) | ||||||
|         env.set_working_directory(cwd) |         env.set_working_directory(cwd) | ||||||
| 
 | 
 | ||||||
|     def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): |     def configure_services( | ||||||
|  |         self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC | ||||||
|  |     ): | ||||||
|         services.add_singleton(EMailClientABC, EMailClient) |         services.add_singleton(EMailClientABC, EMailClient) | ||||||
| 
 | 
 | ||||||
|         services.add_singleton(ApiThread) |         services.add_singleton(ApiThread) | ||||||
| @@ -48,4 +54,4 @@ class ApiModule(ModuleABC): | |||||||
|         services.add_transient(GraphQLController) |         services.add_transient(GraphQLController) | ||||||
| 
 | 
 | ||||||
|         # cpl-discord |         # cpl-discord | ||||||
|         self._dc.add_event(DiscordEventTypesEnum.on_ready.value, BotApiOnReadyEvent) |         services.add_transient(DiscordEventTypesEnum.on_ready.value, BotApiOnReadyEvent) | ||||||
| @@ -12,7 +12,9 @@ class AppApiExtension(ApplicationExtensionABC): | |||||||
|         ApplicationExtensionABC.__init__(self) |         ApplicationExtensionABC.__init__(self) | ||||||
| 
 | 
 | ||||||
|     async def run(self, config: ConfigurationABC, services: ServiceProviderABC): |     async def run(self, config: ConfigurationABC, services: ServiceProviderABC): | ||||||
|         feature_flags: FeatureFlagsSettings = config.get_configuration(FeatureFlagsSettings) |         feature_flags: FeatureFlagsSettings = config.get_configuration( | ||||||
|  |             FeatureFlagsSettings | ||||||
|  |         ) | ||||||
|         if not feature_flags.get_flag(FeatureFlagsEnum.api_module): |         if not feature_flags.get_flag(FeatureFlagsEnum.api_module): | ||||||
|             return |             return | ||||||
| 
 | 
 | ||||||
| @@ -3,8 +3,8 @@ | |||||||
|     "Name": "bot-api", |     "Name": "bot-api", | ||||||
|     "Version": { |     "Version": { | ||||||
|       "Major": "1", |       "Major": "1", | ||||||
|       "Minor": "1", |       "Minor": "2", | ||||||
|       "Micro": "8" |       "Micro": "0" | ||||||
|     }, |     }, | ||||||
|     "Author": "", |     "Author": "", | ||||||
|     "AuthorEmail": "", |     "AuthorEmail": "", | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.configuration" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports | # imports | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -16,7 +16,9 @@ class AuthenticationSettings(ConfigurationModelABC): | |||||||
|         self._issuer = "" if issuer is None else issuer |         self._issuer = "" if issuer is None else issuer | ||||||
|         self._audience = "" if audience is None else audience |         self._audience = "" if audience is None else audience | ||||||
|         self._token_expire_time = 0 if token_expire_time is None else token_expire_time |         self._token_expire_time = 0 if token_expire_time is None else token_expire_time | ||||||
|         self._refresh_token_expire_time = 0 if refresh_token_expire_time is None else refresh_token_expire_time |         self._refresh_token_expire_time = ( | ||||||
|  |             0 if refresh_token_expire_time is None else refresh_token_expire_time | ||||||
|  |         ) | ||||||
| 
 | 
 | ||||||
|     @property |     @property | ||||||
|     def secret_key(self) -> str: |     def secret_key(self) -> str: | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.controller" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -70,7 +70,9 @@ class AuthController: | |||||||
| 
 | 
 | ||||||
|     @Route.post(f"{BasePath}/register") |     @Route.post(f"{BasePath}/register") | ||||||
|     async def register(self): |     async def register(self): | ||||||
|         dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True)) |         dto: AuthUserDTO = JSONProcessor.process( | ||||||
|  |             AuthUserDTO, request.get_json(force=True, silent=True) | ||||||
|  |         ) | ||||||
|         self._auth_service.add_auth_user(dto) |         self._auth_service.add_auth_user(dto) | ||||||
|         return "", 200 |         return "", 200 | ||||||
| 
 | 
 | ||||||
| @@ -81,7 +83,9 @@ class AuthController: | |||||||
| 
 | 
 | ||||||
|     @Route.post(f"{BasePath}/login") |     @Route.post(f"{BasePath}/login") | ||||||
|     async def login(self) -> Response: |     async def login(self) -> Response: | ||||||
|         dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True)) |         dto: AuthUserDTO = JSONProcessor.process( | ||||||
|  |             AuthUserDTO, request.get_json(force=True, silent=True) | ||||||
|  |         ) | ||||||
|         result = await self._auth_service.login_async(dto) |         result = await self._auth_service.login_async(dto) | ||||||
|         return jsonify(result.to_dict()) |         return jsonify(result.to_dict()) | ||||||
| 
 | 
 | ||||||
| @@ -110,40 +114,52 @@ class AuthController: | |||||||
| 
 | 
 | ||||||
|     @Route.post(f"{BasePath}/reset-password") |     @Route.post(f"{BasePath}/reset-password") | ||||||
|     async def reset_password(self): |     async def reset_password(self): | ||||||
|         dto: ResetPasswordDTO = JSONProcessor.process(ResetPasswordDTO, request.get_json(force=True, silent=True)) |         dto: ResetPasswordDTO = JSONProcessor.process( | ||||||
|  |             ResetPasswordDTO, request.get_json(force=True, silent=True) | ||||||
|  |         ) | ||||||
|         await self._auth_service.reset_password_async(dto) |         await self._auth_service.reset_password_async(dto) | ||||||
|         return "", 200 |         return "", 200 | ||||||
| 
 | 
 | ||||||
|     @Route.post(f"{BasePath}/update-user") |     @Route.post(f"{BasePath}/update-user") | ||||||
|     @Route.authorize |     @Route.authorize | ||||||
|     async def update_user(self): |     async def update_user(self): | ||||||
|         dto: UpdateAuthUserDTO = JSONProcessor.process(UpdateAuthUserDTO, request.get_json(force=True, silent=True)) |         dto: UpdateAuthUserDTO = JSONProcessor.process( | ||||||
|  |             UpdateAuthUserDTO, request.get_json(force=True, silent=True) | ||||||
|  |         ) | ||||||
|         await self._auth_service.update_user_async(dto) |         await self._auth_service.update_user_async(dto) | ||||||
|         return "", 200 |         return "", 200 | ||||||
| 
 | 
 | ||||||
|     @Route.post(f"{BasePath}/update-user-as-admin") |     @Route.post(f"{BasePath}/update-user-as-admin") | ||||||
|     @Route.authorize(role=AuthRoleEnum.admin) |     @Route.authorize(role=AuthRoleEnum.admin) | ||||||
|     async def update_user_as_admin(self): |     async def update_user_as_admin(self): | ||||||
|         dto: UpdateAuthUserDTO = JSONProcessor.process(UpdateAuthUserDTO, request.get_json(force=True, silent=True)) |         dto: UpdateAuthUserDTO = JSONProcessor.process( | ||||||
|  |             UpdateAuthUserDTO, request.get_json(force=True, silent=True) | ||||||
|  |         ) | ||||||
|         await self._auth_service.update_user_as_admin_async(dto) |         await self._auth_service.update_user_as_admin_async(dto) | ||||||
|         return "", 200 |         return "", 200 | ||||||
| 
 | 
 | ||||||
|     @Route.post(f"{BasePath}/refresh") |     @Route.post(f"{BasePath}/refresh") | ||||||
|     async def refresh(self) -> Response: |     async def refresh(self) -> Response: | ||||||
|         dto: TokenDTO = JSONProcessor.process(TokenDTO, request.get_json(force=True, silent=True)) |         dto: TokenDTO = JSONProcessor.process( | ||||||
|  |             TokenDTO, request.get_json(force=True, silent=True) | ||||||
|  |         ) | ||||||
|         result = await self._auth_service.refresh_async(dto) |         result = await self._auth_service.refresh_async(dto) | ||||||
|         return jsonify(result.to_dict()) |         return jsonify(result.to_dict()) | ||||||
| 
 | 
 | ||||||
|     @Route.post(f"{BasePath}/revoke") |     @Route.post(f"{BasePath}/revoke") | ||||||
|     async def revoke(self): |     async def revoke(self): | ||||||
|         dto: TokenDTO = JSONProcessor.process(TokenDTO, request.get_json(force=True, silent=True)) |         dto: TokenDTO = JSONProcessor.process( | ||||||
|  |             TokenDTO, request.get_json(force=True, silent=True) | ||||||
|  |         ) | ||||||
|         await self._auth_service.revoke_async(dto) |         await self._auth_service.revoke_async(dto) | ||||||
|         return "", 200 |         return "", 200 | ||||||
| 
 | 
 | ||||||
|     @Route.post(f"{BasePath}/delete-user") |     @Route.post(f"{BasePath}/delete-user") | ||||||
|     @Route.authorize(role=AuthRoleEnum.admin) |     @Route.authorize(role=AuthRoleEnum.admin) | ||||||
|     async def delete_user(self): |     async def delete_user(self): | ||||||
|         dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True)) |         dto: AuthUserDTO = JSONProcessor.process( | ||||||
|  |             AuthUserDTO, request.get_json(force=True, silent=True) | ||||||
|  |         ) | ||||||
|         await self._auth_service.delete_auth_user_async(dto) |         await self._auth_service.delete_auth_user_async(dto) | ||||||
|         return "", 200 |         return "", 200 | ||||||
| 
 | 
 | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.event" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.exception" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.filter" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -13,7 +13,9 @@ class AuthUserSelectCriteria(SelectCriteriaABC): | |||||||
|         email: str, |         email: str, | ||||||
|         auth_role: int, |         auth_role: int, | ||||||
|     ): |     ): | ||||||
|         SelectCriteriaABC.__init__(self, page_index, page_size, sort_direction, sort_column) |         SelectCriteriaABC.__init__( | ||||||
|  |             self, page_index, page_size, sort_direction, sort_column | ||||||
|  |         ) | ||||||
| 
 | 
 | ||||||
|         self.first_name = first_name |         self.first_name = first_name | ||||||
|         self.last_name = last_name |         self.last_name = last_name | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.filter.discord" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -10,6 +10,8 @@ class ServerSelectCriteria(SelectCriteriaABC): | |||||||
|         sort_column: str, |         sort_column: str, | ||||||
|         name: str, |         name: str, | ||||||
|     ): |     ): | ||||||
|         SelectCriteriaABC.__init__(self, page_index, page_size, sort_direction, sort_column) |         SelectCriteriaABC.__init__( | ||||||
|  |             self, page_index, page_size, sort_direction, sort_column | ||||||
|  |         ) | ||||||
| 
 | 
 | ||||||
|         self.name = name |         self.name = name | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.logging" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.model" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.model.discord" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -11,7 +11,9 @@ class ErrorDTO(DtoABC): | |||||||
|     def __init__(self, error_code: Optional[ServiceErrorCode], message: str): |     def __init__(self, error_code: Optional[ServiceErrorCode], message: str): | ||||||
|         DtoABC.__init__(self) |         DtoABC.__init__(self) | ||||||
| 
 | 
 | ||||||
|         self._error_code = ServiceErrorCode.Unknown if error_code is None else error_code |         self._error_code = ( | ||||||
|  |             ServiceErrorCode.Unknown if error_code is None else error_code | ||||||
|  |         ) | ||||||
|         self._message = message |         self._message = message | ||||||
| 
 | 
 | ||||||
|     @property |     @property | ||||||
| @@ -27,4 +27,8 @@ class TokenDTO(DtoABC): | |||||||
|         self._first_login = values["firstLogin"] |         self._first_login = values["firstLogin"] | ||||||
| 
 | 
 | ||||||
|     def to_dict(self) -> dict: |     def to_dict(self) -> dict: | ||||||
|         return {"token": self._token, "refreshToken": self._refresh_token, "firstLogin": self._first_login} |         return { | ||||||
|  |             "token": self._token, | ||||||
|  |             "refreshToken": self._refresh_token, | ||||||
|  |             "firstLogin": self._first_login, | ||||||
|  |         } | ||||||
| @@ -34,7 +34,9 @@ class UpdateAuthUserDTO(DtoABC): | |||||||
|     def from_dict(self, values: dict): |     def from_dict(self, values: dict): | ||||||
|         self._auth_user = AuthUserDTO().from_dict(values["authUser"]) |         self._auth_user = AuthUserDTO().from_dict(values["authUser"]) | ||||||
|         self._new_auth_user = AuthUserDTO().from_dict(values["newAuthUser"]) |         self._new_auth_user = AuthUserDTO().from_dict(values["newAuthUser"]) | ||||||
|         self._change_password = False if "changePassword" not in values else bool(values["changePassword"]) |         self._change_password = ( | ||||||
|  |             False if "changePassword" not in values else bool(values["changePassword"]) | ||||||
|  |         ) | ||||||
| 
 | 
 | ||||||
|     def to_dict(self) -> dict: |     def to_dict(self) -> dict: | ||||||
|         return { |         return { | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.route" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -25,7 +25,12 @@ class Route: | |||||||
| 
 | 
 | ||||||
|     @classmethod |     @classmethod | ||||||
|     @ServiceProviderABC.inject |     @ServiceProviderABC.inject | ||||||
|     def init_authorize(cls, env: ApplicationEnvironmentABC, auth_users: AuthUserRepositoryABC, auth: AuthServiceABC): |     def init_authorize( | ||||||
|  |         cls, | ||||||
|  |         env: ApplicationEnvironmentABC, | ||||||
|  |         auth_users: AuthUserRepositoryABC, | ||||||
|  |         auth: AuthServiceABC, | ||||||
|  |     ): | ||||||
|         cls._auth_users = auth_users |         cls._auth_users = auth_users | ||||||
|         cls._auth = auth |         cls._auth = auth | ||||||
|         cls._env = env.environment_name |         cls._env = env.environment_name | ||||||
| @@ -52,9 +57,17 @@ class Route: | |||||||
|         return user |         return user | ||||||
| 
 | 
 | ||||||
|     @classmethod |     @classmethod | ||||||
|     def authorize(cls, f: Callable = None, role: AuthRoleEnum = None, skip_in_dev=False, by_api_key=False): |     def authorize( | ||||||
|  |         cls, | ||||||
|  |         f: Callable = None, | ||||||
|  |         role: AuthRoleEnum = None, | ||||||
|  |         skip_in_dev=False, | ||||||
|  |         by_api_key=False, | ||||||
|  |     ): | ||||||
|         if f is None: |         if f is None: | ||||||
|             return functools.partial(cls.authorize, role=role, skip_in_dev=skip_in_dev, by_api_key=by_api_key) |             return functools.partial( | ||||||
|  |                 cls.authorize, role=role, skip_in_dev=skip_in_dev, by_api_key=by_api_key | ||||||
|  |             ) | ||||||
| 
 | 
 | ||||||
|         @wraps(f) |         @wraps(f) | ||||||
|         async def decorator(*args, **kwargs): |         async def decorator(*args, **kwargs): | ||||||
| @@ -65,7 +78,9 @@ class Route: | |||||||
|             api_key = None |             api_key = None | ||||||
|             if "Authorization" in request.headers: |             if "Authorization" in request.headers: | ||||||
|                 if " " not in request.headers.get("Authorization"): |                 if " " not in request.headers.get("Authorization"): | ||||||
|                     ex = ServiceException(ServiceErrorCode.Unauthorized, f"Token not set") |                     ex = ServiceException( | ||||||
|  |                         ServiceErrorCode.Unauthorized, f"Token not set" | ||||||
|  |                     ) | ||||||
|                     error = ErrorDTO(ex.error_code, ex.message) |                     error = ErrorDTO(ex.error_code, ex.message) | ||||||
|                     return jsonify(error.to_dict()), 401 |                     return jsonify(error.to_dict()), 401 | ||||||
| 
 | 
 | ||||||
| @@ -87,7 +102,9 @@ class Route: | |||||||
|                     return jsonify(e), 500 |                     return jsonify(e), 500 | ||||||
| 
 | 
 | ||||||
|                 if not valid: |                 if not valid: | ||||||
|                     ex = ServiceException(ServiceErrorCode.Unauthorized, f"API-Key invalid") |                     ex = ServiceException( | ||||||
|  |                         ServiceErrorCode.Unauthorized, f"API-Key invalid" | ||||||
|  |                     ) | ||||||
|                     error = ErrorDTO(ex.error_code, ex.message) |                     error = ErrorDTO(ex.error_code, ex.message) | ||||||
|                     return jsonify(error.to_dict()), 401 |                     return jsonify(error.to_dict()), 401 | ||||||
| 
 | 
 | ||||||
| @@ -99,7 +116,9 @@ class Route: | |||||||
|                 return jsonify(error.to_dict()), 401 |                 return jsonify(error.to_dict()), 401 | ||||||
| 
 | 
 | ||||||
|             if cls._auth_users is None or cls._auth is None: |             if cls._auth_users is None or cls._auth is None: | ||||||
|                 ex = ServiceException(ServiceErrorCode.Unauthorized, f"Authorize is not initialized") |                 ex = ServiceException( | ||||||
|  |                     ServiceErrorCode.Unauthorized, f"Authorize is not initialized" | ||||||
|  |                 ) | ||||||
|                 error = ErrorDTO(ex.error_code, ex.message) |                 error = ErrorDTO(ex.error_code, ex.message) | ||||||
|                 return jsonify(error.to_dict()), 401 |                 return jsonify(error.to_dict()), 401 | ||||||
| 
 | 
 | ||||||
| @@ -121,7 +140,9 @@ class Route: | |||||||
|                 return jsonify(error.to_dict()), 401 |                 return jsonify(error.to_dict()), 401 | ||||||
| 
 | 
 | ||||||
|             if role is not None and user.auth_role.value < role.value: |             if role is not None and user.auth_role.value < role.value: | ||||||
|                 ex = ServiceException(ServiceErrorCode.Unauthorized, f"Role {role} required") |                 ex = ServiceException( | ||||||
|  |                     ServiceErrorCode.Unauthorized, f"Role {role} required" | ||||||
|  |                 ) | ||||||
|                 error = ErrorDTO(ex.error_code, ex.message) |                 error = ErrorDTO(ex.error_code, ex.message) | ||||||
|                 return jsonify(error.to_dict()), 403 |                 return jsonify(error.to_dict()), 403 | ||||||
| 
 | 
 | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.service" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports | # imports | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -90,7 +90,9 @@ class AuthService(AuthServiceABC): | |||||||
| 
 | 
 | ||||||
|     def _get_api_key_str(self, api_key: ApiKey) -> str: |     def _get_api_key_str(self, api_key: ApiKey) -> str: | ||||||
|         return hashlib.sha256( |         return hashlib.sha256( | ||||||
|             f"{api_key.identifier}:{api_key.key}+{self._auth_settings.secret_key}".encode("utf-8") |             f"{api_key.identifier}:{api_key.key}+{self._auth_settings.secret_key}".encode( | ||||||
|  |                 "utf-8" | ||||||
|  |             ) | ||||||
|         ).hexdigest() |         ).hexdigest() | ||||||
| 
 | 
 | ||||||
|     def generate_token(self, user: AuthUser) -> str: |     def generate_token(self, user: AuthUser) -> str: | ||||||
| @@ -99,7 +101,8 @@ class AuthService(AuthServiceABC): | |||||||
|                 "user_id": user.id, |                 "user_id": user.id, | ||||||
|                 "email": user.email, |                 "email": user.email, | ||||||
|                 "role": user.auth_role.value, |                 "role": user.auth_role.value, | ||||||
|                 "exp": datetime.now(tz=timezone.utc) + timedelta(days=self._auth_settings.token_expire_time), |                 "exp": datetime.now(tz=timezone.utc) | ||||||
|  |                 + timedelta(days=self._auth_settings.token_expire_time), | ||||||
|                 "iss": self._auth_settings.issuer, |                 "iss": self._auth_settings.issuer, | ||||||
|                 "aud": self._auth_settings.audience, |                 "aud": self._auth_settings.audience, | ||||||
|             }, |             }, | ||||||
| @@ -155,7 +158,9 @@ class AuthService(AuthServiceABC): | |||||||
|     def _create_and_save_refresh_token(self, user: AuthUser) -> str: |     def _create_and_save_refresh_token(self, user: AuthUser) -> str: | ||||||
|         token = str(uuid.uuid4()) |         token = str(uuid.uuid4()) | ||||||
|         user.refresh_token = token |         user.refresh_token = token | ||||||
|         user.refresh_token_expire_time = datetime.now() + timedelta(days=self._auth_settings.refresh_token_expire_time) |         user.refresh_token_expire_time = datetime.now() + timedelta( | ||||||
|  |             days=self._auth_settings.refresh_token_expire_time | ||||||
|  |         ) | ||||||
|         self._auth_users.update_auth_user(user) |         self._auth_users.update_auth_user(user) | ||||||
|         self._db.save_changes() |         self._db.save_changes() | ||||||
|         return token |         return token | ||||||
| @@ -188,8 +193,12 @@ class AuthService(AuthServiceABC): | |||||||
| 
 | 
 | ||||||
|         self._send_link_mail( |         self._send_link_mail( | ||||||
|             user.email, |             user.email, | ||||||
|             self._t.transform("api.auth.confirmation.subject").format(user.first_name, user.last_name), |             self._t.transform("api.auth.confirmation.subject").format( | ||||||
|             self._t.transform("api.auth.confirmation.message").format(url, user.confirmation_id), |                 user.first_name, user.last_name | ||||||
|  |             ), | ||||||
|  |             self._t.transform("api.auth.confirmation.message").format( | ||||||
|  |                 url, user.confirmation_id | ||||||
|  |             ), | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     def _send_forgot_password_id_to_user(self, user: AuthUser): |     def _send_forgot_password_id_to_user(self, user: AuthUser): | ||||||
| @@ -199,28 +208,38 @@ class AuthService(AuthServiceABC): | |||||||
| 
 | 
 | ||||||
|         self._send_link_mail( |         self._send_link_mail( | ||||||
|             user.email, |             user.email, | ||||||
|             self._t.transform("api.auth.forgot_password.subject").format(user.first_name, user.last_name), |             self._t.transform("api.auth.forgot_password.subject").format( | ||||||
|             self._t.transform("api.auth.forgot_password.message").format(url, user.forgot_password_id), |                 user.first_name, user.last_name | ||||||
|  |             ), | ||||||
|  |             self._t.transform("api.auth.forgot_password.message").format( | ||||||
|  |                 url, user.forgot_password_id | ||||||
|  |             ), | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     async def get_all_auth_users_async(self) -> List[AuthUserDTO]: |     async def get_all_auth_users_async(self) -> List[AuthUserDTO]: | ||||||
|         result = self._auth_users.get_all_auth_users().select(lambda x: AUT.to_dto(x)) |         result = self._auth_users.get_all_auth_users().select(lambda x: AUT.to_dto(x)) | ||||||
|         return List(AuthUserDTO, result) |         return List(AuthUserDTO, result) | ||||||
| 
 | 
 | ||||||
|     async def get_filtered_auth_users_async(self, criteria: AuthUserSelectCriteria) -> AuthUserFilteredResultDTO: |     async def get_filtered_auth_users_async( | ||||||
|  |         self, criteria: AuthUserSelectCriteria | ||||||
|  |     ) -> AuthUserFilteredResultDTO: | ||||||
|         users = self._auth_users.get_filtered_auth_users(criteria) |         users = self._auth_users.get_filtered_auth_users(criteria) | ||||||
|         result = users.result.select(lambda x: AUT.to_dto(x)) |         result = users.result.select(lambda x: AUT.to_dto(x)) | ||||||
| 
 | 
 | ||||||
|         return AuthUserFilteredResultDTO(List(AuthUserDTO, result), users.total_count) |         return AuthUserFilteredResultDTO(List(AuthUserDTO, result), users.total_count) | ||||||
| 
 | 
 | ||||||
|     async def get_auth_user_by_email_async(self, email: str, with_password: bool = False) -> AuthUserDTO: |     async def get_auth_user_by_email_async( | ||||||
|  |         self, email: str, with_password: bool = False | ||||||
|  |     ) -> AuthUserDTO: | ||||||
|         try: |         try: | ||||||
|             # todo: check if logged in user is admin then send mail |             # todo: check if logged in user is admin then send mail | ||||||
|             user = self._auth_users.get_auth_user_by_email(email) |             user = self._auth_users.get_auth_user_by_email(email) | ||||||
|             return AUT.to_dto(user, password=user.password if with_password else None) |             return AUT.to_dto(user, password=user.password if with_password else None) | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             self._logger.error(__name__, f"AuthUser not found", e) |             self._logger.error(__name__, f"AuthUser not found", e) | ||||||
|             raise ServiceException(ServiceErrorCode.InvalidData, f"User not found {email}") |             raise ServiceException( | ||||||
|  |                 ServiceErrorCode.InvalidData, f"User not found {email}" | ||||||
|  |             ) | ||||||
| 
 | 
 | ||||||
|     async def find_auth_user_by_email_async(self, email: str) -> Optional[AuthUser]: |     async def find_auth_user_by_email_async(self, email: str) -> Optional[AuthUser]: | ||||||
|         user = self._auth_users.find_auth_user_by_email(email) |         user = self._auth_users.find_auth_user_by_email(email) | ||||||
| @@ -238,16 +257,22 @@ class AuthService(AuthServiceABC): | |||||||
|         user.password_salt = uuid.uuid4() |         user.password_salt = uuid.uuid4() | ||||||
|         user.password = self._hash_sha256(user_dto.password, user.password_salt) |         user.password = self._hash_sha256(user_dto.password, user.password_salt) | ||||||
|         if not self._is_email_valid(user.email): |         if not self._is_email_valid(user.email): | ||||||
|             raise ServiceException(ServiceErrorCode.InvalidData, "Invalid E-Mail address") |             raise ServiceException( | ||||||
|  |                 ServiceErrorCode.InvalidData, "Invalid E-Mail address" | ||||||
|  |             ) | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
|             user.confirmation_id = uuid.uuid4() |             user.confirmation_id = uuid.uuid4() | ||||||
|             self._auth_users.add_auth_user(user) |             self._auth_users.add_auth_user(user) | ||||||
|             self._send_confirmation_id_to_user(user) |             self._send_confirmation_id_to_user(user) | ||||||
|             self._db.save_changes() |             self._db.save_changes() | ||||||
|             self._logger.info(__name__, f"Added auth user with E-Mail: {user_dto.email}") |             self._logger.info( | ||||||
|  |                 __name__, f"Added auth user with E-Mail: {user_dto.email}" | ||||||
|  |             ) | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             self._logger.error(__name__, f"Cannot add user with E-Mail {user_dto.email}", e) |             self._logger.error( | ||||||
|  |                 __name__, f"Cannot add user with E-Mail {user_dto.email}", e | ||||||
|  |             ) | ||||||
|             raise ServiceException(ServiceErrorCode.UnableToAdd, "Invalid E-Mail") |             raise ServiceException(ServiceErrorCode.UnableToAdd, "Invalid E-Mail") | ||||||
| 
 | 
 | ||||||
|     async def add_auth_user_by_oauth_async(self, dto: OAuthDTO): |     async def add_auth_user_by_oauth_async(self, dto: OAuthDTO): | ||||||
| @@ -263,14 +288,20 @@ class AuthService(AuthServiceABC): | |||||||
|             db_user.first_name = dto.user.first_name |             db_user.first_name = dto.user.first_name | ||||||
|             db_user.last_name = dto.user.last_name |             db_user.last_name = dto.user.last_name | ||||||
|             db_user.password_salt = uuid.uuid4() |             db_user.password_salt = uuid.uuid4() | ||||||
|             db_user.password = self._hash_sha256(dto.user.password, db_user.password_salt) |             db_user.password = self._hash_sha256( | ||||||
|  |                 dto.user.password, db_user.password_salt | ||||||
|  |             ) | ||||||
|             db_user.oauth_id = None |             db_user.oauth_id = None | ||||||
|             db_user.confirmation_id = uuid.uuid4() |             db_user.confirmation_id = uuid.uuid4() | ||||||
|             self._send_confirmation_id_to_user(db_user) |             self._send_confirmation_id_to_user(db_user) | ||||||
|             self._auth_users.update_auth_user(db_user) |             self._auth_users.update_auth_user(db_user) | ||||||
|             self._logger.info(__name__, f"Added auth user with E-Mail: {dto.user.email}") |             self._logger.info( | ||||||
|  |                 __name__, f"Added auth user with E-Mail: {dto.user.email}" | ||||||
|  |             ) | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             self._logger.error(__name__, f"Cannot add user with E-Mail {dto.user.email}", e) |             self._logger.error( | ||||||
|  |                 __name__, f"Cannot add user with E-Mail {dto.user.email}", e | ||||||
|  |             ) | ||||||
|             raise ServiceException(ServiceErrorCode.UnableToAdd, "Invalid E-Mail") |             raise ServiceException(ServiceErrorCode.UnableToAdd, "Invalid E-Mail") | ||||||
| 
 | 
 | ||||||
|         self._db.save_changes() |         self._db.save_changes() | ||||||
| @@ -280,14 +311,16 @@ class AuthService(AuthServiceABC): | |||||||
|             raise ServiceException(ServiceErrorCode.InvalidData, f"User is empty") |             raise ServiceException(ServiceErrorCode.InvalidData, f"User is empty") | ||||||
| 
 | 
 | ||||||
|         if update_user_dto.auth_user is None: |         if update_user_dto.auth_user is None: | ||||||
|             raise ServiceException(ServiceErrorCode.InvalidData, f"Existing user is empty") |             raise ServiceException( | ||||||
|  |                 ServiceErrorCode.InvalidData, f"Existing user is empty" | ||||||
|  |             ) | ||||||
| 
 | 
 | ||||||
|         if update_user_dto.new_auth_user is None: |         if update_user_dto.new_auth_user is None: | ||||||
|             raise ServiceException(ServiceErrorCode.InvalidData, f"New user is empty") |             raise ServiceException(ServiceErrorCode.InvalidData, f"New user is empty") | ||||||
| 
 | 
 | ||||||
|         if not self._is_email_valid(update_user_dto.auth_user.email) or not self._is_email_valid( |         if not self._is_email_valid( | ||||||
|             update_user_dto.new_auth_user.email |             update_user_dto.auth_user.email | ||||||
|         ): |         ) or not self._is_email_valid(update_user_dto.new_auth_user.email): | ||||||
|             raise ServiceException(ServiceErrorCode.InvalidData, f"Invalid E-Mail") |             raise ServiceException(ServiceErrorCode.InvalidData, f"Invalid E-Mail") | ||||||
| 
 | 
 | ||||||
|         user = self._auth_users.find_auth_user_by_email(update_user_dto.auth_user.email) |         user = self._auth_users.find_auth_user_by_email(update_user_dto.auth_user.email) | ||||||
| @@ -300,7 +333,8 @@ class AuthService(AuthServiceABC): | |||||||
|         # update first name |         # update first name | ||||||
|         if ( |         if ( | ||||||
|             update_user_dto.new_auth_user.first_name is not None |             update_user_dto.new_auth_user.first_name is not None | ||||||
|             and update_user_dto.auth_user.first_name != update_user_dto.new_auth_user.first_name |             and update_user_dto.auth_user.first_name | ||||||
|  |             != update_user_dto.new_auth_user.first_name | ||||||
|         ): |         ): | ||||||
|             user.first_name = update_user_dto.new_auth_user.first_name |             user.first_name = update_user_dto.new_auth_user.first_name | ||||||
| 
 | 
 | ||||||
| @@ -308,7 +342,8 @@ class AuthService(AuthServiceABC): | |||||||
|         if ( |         if ( | ||||||
|             update_user_dto.new_auth_user.last_name is not None |             update_user_dto.new_auth_user.last_name is not None | ||||||
|             and update_user_dto.new_auth_user.last_name != "" |             and update_user_dto.new_auth_user.last_name != "" | ||||||
|             and update_user_dto.auth_user.last_name != update_user_dto.new_auth_user.last_name |             and update_user_dto.auth_user.last_name | ||||||
|  |             != update_user_dto.new_auth_user.last_name | ||||||
|         ): |         ): | ||||||
|             user.last_name = update_user_dto.new_auth_user.last_name |             user.last_name = update_user_dto.new_auth_user.last_name | ||||||
| 
 | 
 | ||||||
| @@ -318,22 +353,33 @@ class AuthService(AuthServiceABC): | |||||||
|             and update_user_dto.new_auth_user.email != "" |             and update_user_dto.new_auth_user.email != "" | ||||||
|             and update_user_dto.auth_user.email != update_user_dto.new_auth_user.email |             and update_user_dto.auth_user.email != update_user_dto.new_auth_user.email | ||||||
|         ): |         ): | ||||||
|             user_by_new_e_mail = self._auth_users.find_auth_user_by_email(update_user_dto.new_auth_user.email) |             user_by_new_e_mail = self._auth_users.find_auth_user_by_email( | ||||||
|  |                 update_user_dto.new_auth_user.email | ||||||
|  |             ) | ||||||
|             if user_by_new_e_mail is not None: |             if user_by_new_e_mail is not None: | ||||||
|                 raise ServiceException(ServiceErrorCode.InvalidUser, "User already exists") |                 raise ServiceException( | ||||||
|  |                     ServiceErrorCode.InvalidUser, "User already exists" | ||||||
|  |                 ) | ||||||
|             user.email = update_user_dto.new_auth_user.email |             user.email = update_user_dto.new_auth_user.email | ||||||
| 
 | 
 | ||||||
|         update_user_dto.auth_user.password = self._hash_sha256(update_user_dto.auth_user.password, user.password_salt) |         update_user_dto.auth_user.password = self._hash_sha256( | ||||||
|  |             update_user_dto.auth_user.password, user.password_salt | ||||||
|  |         ) | ||||||
|         if update_user_dto.auth_user.password != user.password: |         if update_user_dto.auth_user.password != user.password: | ||||||
|             raise ServiceException(ServiceErrorCode.InvalidUser, "Wrong password") |             raise ServiceException(ServiceErrorCode.InvalidUser, "Wrong password") | ||||||
| 
 | 
 | ||||||
|         # update password |         # update password | ||||||
|         if ( |         if ( | ||||||
|             update_user_dto.new_auth_user.password is not None |             update_user_dto.new_auth_user.password is not None | ||||||
|             and self._hash_sha256(update_user_dto.new_auth_user.password, user.password_salt) != user.password |             and self._hash_sha256( | ||||||
|  |                 update_user_dto.new_auth_user.password, user.password_salt | ||||||
|  |             ) | ||||||
|  |             != user.password | ||||||
|         ): |         ): | ||||||
|             user.password_salt = uuid.uuid4() |             user.password_salt = uuid.uuid4() | ||||||
|             user.password = self._hash_sha256(update_user_dto.new_auth_user.password, user.password_salt) |             user.password = self._hash_sha256( | ||||||
|  |                 update_user_dto.new_auth_user.password, user.password_salt | ||||||
|  |             ) | ||||||
| 
 | 
 | ||||||
|         self._auth_users.update_auth_user(user) |         self._auth_users.update_auth_user(user) | ||||||
|         self._db.save_changes() |         self._db.save_changes() | ||||||
| @@ -343,23 +389,31 @@ class AuthService(AuthServiceABC): | |||||||
|             raise ServiceException(ServiceErrorCode.InvalidData, f"User is empty") |             raise ServiceException(ServiceErrorCode.InvalidData, f"User is empty") | ||||||
| 
 | 
 | ||||||
|         if update_user_dto.auth_user is None: |         if update_user_dto.auth_user is None: | ||||||
|             raise ServiceException(ServiceErrorCode.InvalidData, f"Existing user is empty") |             raise ServiceException( | ||||||
|  |                 ServiceErrorCode.InvalidData, f"Existing user is empty" | ||||||
|  |             ) | ||||||
| 
 | 
 | ||||||
|         if update_user_dto.new_auth_user is None: |         if update_user_dto.new_auth_user is None: | ||||||
|             raise ServiceException(ServiceErrorCode.InvalidData, f"New user is empty") |             raise ServiceException(ServiceErrorCode.InvalidData, f"New user is empty") | ||||||
| 
 | 
 | ||||||
|         if not self._is_email_valid(update_user_dto.auth_user.email) or not self._is_email_valid( |         if not self._is_email_valid( | ||||||
|             update_user_dto.new_auth_user.email |             update_user_dto.auth_user.email | ||||||
|         ): |         ) or not self._is_email_valid(update_user_dto.new_auth_user.email): | ||||||
|             raise ServiceException(ServiceErrorCode.InvalidData, f"Invalid E-Mail") |             raise ServiceException(ServiceErrorCode.InvalidData, f"Invalid E-Mail") | ||||||
| 
 | 
 | ||||||
|         user = self._auth_users.find_auth_user_by_email(update_user_dto.auth_user.email) |         user = self._auth_users.find_auth_user_by_email(update_user_dto.auth_user.email) | ||||||
|         if user is None: |         if user is None: | ||||||
|             raise ServiceException(ServiceErrorCode.InvalidUser, "User not found") |             raise ServiceException(ServiceErrorCode.InvalidUser, "User not found") | ||||||
| 
 | 
 | ||||||
|         if user.confirmation_id is not None and update_user_dto.new_auth_user.is_confirmed: |         if ( | ||||||
|  |             user.confirmation_id is not None | ||||||
|  |             and update_user_dto.new_auth_user.is_confirmed | ||||||
|  |         ): | ||||||
|             user.confirmation_id = None |             user.confirmation_id = None | ||||||
|         elif user.confirmation_id is None and not update_user_dto.new_auth_user.is_confirmed: |         elif ( | ||||||
|  |             user.confirmation_id is None | ||||||
|  |             and not update_user_dto.new_auth_user.is_confirmed | ||||||
|  |         ): | ||||||
|             user.confirmation_id = uuid.uuid4() |             user.confirmation_id = uuid.uuid4() | ||||||
|         # else |         # else | ||||||
|         #     raise ServiceException(ServiceErrorCode.InvalidUser, 'E-Mail not confirmed') |         #     raise ServiceException(ServiceErrorCode.InvalidUser, 'E-Mail not confirmed') | ||||||
| @@ -367,7 +421,8 @@ class AuthService(AuthServiceABC): | |||||||
|         # update first name |         # update first name | ||||||
|         if ( |         if ( | ||||||
|             update_user_dto.new_auth_user.first_name is not None |             update_user_dto.new_auth_user.first_name is not None | ||||||
|             and update_user_dto.auth_user.first_name != update_user_dto.new_auth_user.first_name |             and update_user_dto.auth_user.first_name | ||||||
|  |             != update_user_dto.new_auth_user.first_name | ||||||
|         ): |         ): | ||||||
|             user.first_name = update_user_dto.new_auth_user.first_name |             user.first_name = update_user_dto.new_auth_user.first_name | ||||||
| 
 | 
 | ||||||
| @@ -375,7 +430,8 @@ class AuthService(AuthServiceABC): | |||||||
|         if ( |         if ( | ||||||
|             update_user_dto.new_auth_user.last_name is not None |             update_user_dto.new_auth_user.last_name is not None | ||||||
|             and update_user_dto.new_auth_user.last_name != "" |             and update_user_dto.new_auth_user.last_name != "" | ||||||
|             and update_user_dto.auth_user.last_name != update_user_dto.new_auth_user.last_name |             and update_user_dto.auth_user.last_name | ||||||
|  |             != update_user_dto.new_auth_user.last_name | ||||||
|         ): |         ): | ||||||
|             user.last_name = update_user_dto.new_auth_user.last_name |             user.last_name = update_user_dto.new_auth_user.last_name | ||||||
| 
 | 
 | ||||||
| @@ -385,19 +441,28 @@ class AuthService(AuthServiceABC): | |||||||
|             and update_user_dto.new_auth_user.email != "" |             and update_user_dto.new_auth_user.email != "" | ||||||
|             and update_user_dto.auth_user.email != update_user_dto.new_auth_user.email |             and update_user_dto.auth_user.email != update_user_dto.new_auth_user.email | ||||||
|         ): |         ): | ||||||
|             user_by_new_e_mail = self._auth_users.find_auth_user_by_email(update_user_dto.new_auth_user.email) |             user_by_new_e_mail = self._auth_users.find_auth_user_by_email( | ||||||
|  |                 update_user_dto.new_auth_user.email | ||||||
|  |             ) | ||||||
|             if user_by_new_e_mail is not None: |             if user_by_new_e_mail is not None: | ||||||
|                 raise ServiceException(ServiceErrorCode.InvalidUser, "User already exists") |                 raise ServiceException( | ||||||
|  |                     ServiceErrorCode.InvalidUser, "User already exists" | ||||||
|  |                 ) | ||||||
|             user.email = update_user_dto.new_auth_user.email |             user.email = update_user_dto.new_auth_user.email | ||||||
| 
 | 
 | ||||||
|         # update password |         # update password | ||||||
|         if ( |         if ( | ||||||
|             update_user_dto.new_auth_user.password is not None |             update_user_dto.new_auth_user.password is not None | ||||||
|             and update_user_dto.change_password |             and update_user_dto.change_password | ||||||
|             and user.password != self._hash_sha256(update_user_dto.new_auth_user.password, user.password_salt) |             and user.password | ||||||
|  |             != self._hash_sha256( | ||||||
|  |                 update_user_dto.new_auth_user.password, user.password_salt | ||||||
|  |             ) | ||||||
|         ): |         ): | ||||||
|             user.password_salt = uuid.uuid4() |             user.password_salt = uuid.uuid4() | ||||||
|             user.password = self._hash_sha256(update_user_dto.new_auth_user.password, user.password_salt) |             user.password = self._hash_sha256( | ||||||
|  |                 update_user_dto.new_auth_user.password, user.password_salt | ||||||
|  |             ) | ||||||
| 
 | 
 | ||||||
|         # update role |         # update role | ||||||
|         if ( |         if ( | ||||||
| @@ -416,7 +481,9 @@ class AuthService(AuthServiceABC): | |||||||
|             self._db.save_changes() |             self._db.save_changes() | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             self._logger.error(__name__, f"Cannot delete user", e) |             self._logger.error(__name__, f"Cannot delete user", e) | ||||||
|             raise ServiceException(ServiceErrorCode.UnableToDelete, f"Cannot delete user by mail {email}") |             raise ServiceException( | ||||||
|  |                 ServiceErrorCode.UnableToDelete, f"Cannot delete user by mail {email}" | ||||||
|  |             ) | ||||||
| 
 | 
 | ||||||
|     async def delete_auth_user_async(self, user_dto: AuthUser): |     async def delete_auth_user_async(self, user_dto: AuthUser): | ||||||
|         try: |         try: | ||||||
| @@ -500,7 +567,9 @@ class AuthService(AuthServiceABC): | |||||||
|             if user.id in user_ids: |             if user.id in user_ids: | ||||||
|                 continue |                 continue | ||||||
| 
 | 
 | ||||||
|             self._auth_users.add_auth_user_user_rel(AuthUserUsersRelation(db_user, user)) |             self._auth_users.add_auth_user_user_rel( | ||||||
|  |                 AuthUserUsersRelation(db_user, user) | ||||||
|  |             ) | ||||||
| 
 | 
 | ||||||
|         if db_user.confirmation_id is not None and not added_user: |         if db_user.confirmation_id is not None and not added_user: | ||||||
|             raise ServiceException(ServiceErrorCode.Forbidden, "E-Mail not verified") |             raise ServiceException(ServiceErrorCode.Forbidden, "E-Mail not verified") | ||||||
| @@ -530,13 +599,19 @@ class AuthService(AuthServiceABC): | |||||||
|             ): |             ): | ||||||
|                 raise ServiceException(ServiceErrorCode.InvalidData, "Token expired") |                 raise ServiceException(ServiceErrorCode.InvalidData, "Token expired") | ||||||
| 
 | 
 | ||||||
|             return TokenDTO(self.generate_token(user), self._create_and_save_refresh_token(user)) |             return TokenDTO( | ||||||
|  |                 self.generate_token(user), self._create_and_save_refresh_token(user) | ||||||
|  |             ) | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             self._logger.error(__name__, f"Refreshing token failed", e) |             self._logger.error(__name__, f"Refreshing token failed", e) | ||||||
|             return TokenDTO("", "") |             return TokenDTO("", "") | ||||||
| 
 | 
 | ||||||
|     async def revoke_async(self, token_dto: TokenDTO): |     async def revoke_async(self, token_dto: TokenDTO): | ||||||
|         if token_dto is None or token_dto.token is None or token_dto.refresh_token is None: |         if ( | ||||||
|  |             token_dto is None | ||||||
|  |             or token_dto.token is None | ||||||
|  |             or token_dto.refresh_token is None | ||||||
|  |         ): | ||||||
|             raise ServiceException(ServiceErrorCode.InvalidData, "Token not set") |             raise ServiceException(ServiceErrorCode.InvalidData, "Token not set") | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
| @@ -589,7 +664,9 @@ class AuthService(AuthServiceABC): | |||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
|         if user.confirmation_id is not None: |         if user.confirmation_id is not None: | ||||||
|             raise ServiceException(ServiceErrorCode.InvalidUser, f"E-Mail not confirmed") |             raise ServiceException( | ||||||
|  |                 ServiceErrorCode.InvalidUser, f"E-Mail not confirmed" | ||||||
|  |             ) | ||||||
| 
 | 
 | ||||||
|         if user.password is None or rp_dto.password == "": |         if user.password is None or rp_dto.password == "": | ||||||
|             raise ServiceException(ServiceErrorCode.InvalidData, f"Password not set") |             raise ServiceException(ServiceErrorCode.InvalidData, f"Password not set") | ||||||
| @@ -53,13 +53,17 @@ class DiscordService: | |||||||
|         if role != AuthRoleEnum.admin: |         if role != AuthRoleEnum.admin: | ||||||
|             auth_user = self._auth_users.find_auth_user_by_email(token["email"]) |             auth_user = self._auth_users.find_auth_user_by_email(token["email"]) | ||||||
|             if auth_user is not None: |             if auth_user is not None: | ||||||
|                 user_ids = auth_user.users.select(lambda x: x.server is not None and x.server.id) |                 user_ids = auth_user.users.select( | ||||||
|  |                     lambda x: x.server is not None and x.server.id | ||||||
|  |                 ) | ||||||
|                 servers = servers.where(lambda x: x.id in user_ids) |                 servers = servers.where(lambda x: x.id in user_ids) | ||||||
| 
 | 
 | ||||||
|         servers = List(ServerDTO, servers) |         servers = List(ServerDTO, servers) | ||||||
|         return servers.select(self._to_dto).where(lambda x: x.name != "") |         return servers.select(self._to_dto).where(lambda x: x.name != "") | ||||||
| 
 | 
 | ||||||
|     async def get_filtered_servers_async(self, criteria: ServerSelectCriteria) -> ServerFilteredResultDTO: |     async def get_filtered_servers_async( | ||||||
|  |         self, criteria: ServerSelectCriteria | ||||||
|  |     ) -> ServerFilteredResultDTO: | ||||||
|         token = self._auth.get_decoded_token_from_request() |         token = self._auth.get_decoded_token_from_request() | ||||||
|         if token is None or "email" not in token or "role" not in token: |         if token is None or "email" not in token or "role" not in token: | ||||||
|             raise ServiceException(ServiceErrorCode.InvalidData, "Token invalid") |             raise ServiceException(ServiceErrorCode.InvalidData, "Token invalid") | ||||||
| @@ -70,15 +74,22 @@ class DiscordService: | |||||||
|         if role != AuthRoleEnum.admin: |         if role != AuthRoleEnum.admin: | ||||||
|             auth_user = self._auth_users.find_auth_user_by_email(token["email"]) |             auth_user = self._auth_users.find_auth_user_by_email(token["email"]) | ||||||
|             if auth_user is not None: |             if auth_user is not None: | ||||||
|                 user_ids = auth_user.users.select(lambda x: x.server is not None and x.server.id) |                 user_ids = auth_user.users.select( | ||||||
|                 filtered_result.result = filtered_result.result.where(lambda x: x.id in user_ids) |                     lambda x: x.server is not None and x.server.id | ||||||
|  |                 ) | ||||||
|  |                 filtered_result.result = filtered_result.result.where( | ||||||
|  |                     lambda x: x.id in user_ids | ||||||
|  |                 ) | ||||||
| 
 | 
 | ||||||
|         servers: List = filtered_result.result.select(self._to_dto).where(lambda x: x.name != "") |         servers: List = filtered_result.result.select(self._to_dto).where( | ||||||
|  |             lambda x: x.name != "" | ||||||
|  |         ) | ||||||
|         result = List(ServerDTO, servers) |         result = List(ServerDTO, servers) | ||||||
| 
 | 
 | ||||||
|         if criteria.name is not None and criteria.name != "": |         if criteria.name is not None and criteria.name != "": | ||||||
|             result = result.where( |             result = result.where( | ||||||
|                 lambda x: criteria.name.lower() in x.name.lower() or x.name.lower() == criteria.name.lower() |                 lambda x: criteria.name.lower() in x.name.lower() | ||||||
|  |                 or x.name.lower() == criteria.name.lower() | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
|         return ServerFilteredResultDTO(List(ServerDTO, result), servers.count()) |         return ServerFilteredResultDTO(List(ServerDTO, result), servers.count()) | ||||||
| @@ -87,5 +98,7 @@ class DiscordService: | |||||||
|         server = self._servers.get_server_by_id(id) |         server = self._servers.get_server_by_id(id) | ||||||
|         guild = self._bot.get_guild(server.discord_id) |         guild = self._bot.get_guild(server.discord_id) | ||||||
| 
 | 
 | ||||||
|         server_dto = ServerTransformer.to_dto(server, guild.name, guild.member_count, guild.icon) |         server_dto = ServerTransformer.to_dto( | ||||||
|  |             server, guild.name, guild.member_count, guild.icon | ||||||
|  |         ) | ||||||
|         return server_dto |         return server_dto | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.transformer" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -27,27 +27,35 @@ class AuthUserTransformer(TransformerABC): | |||||||
|             None, |             None, | ||||||
|             None, |             None, | ||||||
|             datetime.now(), |             datetime.now(), | ||||||
|             AuthRoleEnum.normal if dto.auth_role is None else AuthRoleEnum(dto.auth_role), |             AuthRoleEnum.normal | ||||||
|  |             if dto.auth_role is None | ||||||
|  |             else AuthRoleEnum(dto.auth_role), | ||||||
|             auth_user_id=0 if dto.id is None else dto.id, |             auth_user_id=0 if dto.id is None else dto.id, | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     @ServiceProviderABC.inject |     @ServiceProviderABC.inject | ||||||
|     def _is_technician(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC): |     def _is_technician( | ||||||
|  |         user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC | ||||||
|  |     ): | ||||||
|         guild = bot.get_guild(user.server.discord_id) |         guild = bot.get_guild(user.server.discord_id) | ||||||
|         member = guild.get_member(user.discord_id) |         member = guild.get_member(user.discord_id) | ||||||
|         return permissions.is_member_technician(member) |         return permissions.is_member_technician(member) | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     @ServiceProviderABC.inject |     @ServiceProviderABC.inject | ||||||
|     def _is_admin(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC): |     def _is_admin( | ||||||
|  |         user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC | ||||||
|  |     ): | ||||||
|         guild = bot.get_guild(user.server.discord_id) |         guild = bot.get_guild(user.server.discord_id) | ||||||
|         member = guild.get_member(user.discord_id) |         member = guild.get_member(user.discord_id) | ||||||
|         return permissions.is_member_admin(member) |         return permissions.is_member_admin(member) | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     @ServiceProviderABC.inject |     @ServiceProviderABC.inject | ||||||
|     def _is_moderator(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC): |     def _is_moderator( | ||||||
|  |         user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC | ||||||
|  |     ): | ||||||
|         guild = bot.get_guild(user.server.discord_id) |         guild = bot.get_guild(user.server.discord_id) | ||||||
|         member = guild.get_member(user.discord_id) |         member = guild.get_member(user.discord_id) | ||||||
|         return permissions.is_member_moderator(member) |         return permissions.is_member_moderator(member) | ||||||
| @@ -13,7 +13,9 @@ class ServerTransformer(TransformerABC): | |||||||
|         return Server(dto.discord_id) |         return Server(dto.discord_id) | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def to_dto(db: Server, name: str, member_count: int, icon_url: Optional[discord.Asset]) -> ServerDTO: |     def to_dto( | ||||||
|  |         db: Server, name: str, member_count: int, icon_url: Optional[discord.Asset] | ||||||
|  |     ) -> ServerDTO: | ||||||
|         return ServerDTO( |         return ServerDTO( | ||||||
|             db.id, |             db.id, | ||||||
|             db.discord_id, |             db.discord_id, | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports | # imports | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.abc" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -45,7 +45,9 @@ class ClientUtilsABC(ABC): | |||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
|     def get_auto_complete_list(self, _l: List, current: str, select: Callable = None) -> List: |     def get_auto_complete_list( | ||||||
|  |         self, _l: List, current: str, select: Callable = None | ||||||
|  |     ) -> List: | ||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
| @@ -64,7 +66,11 @@ class ClientUtilsABC(ABC): | |||||||
| 
 | 
 | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
|     async def react_to_message_by_auto_role_rule( |     async def react_to_message_by_auto_role_rule( | ||||||
|         self, discord_channel_id: int, discord_message_id: int, rule: AutoRoleRule, guild: discord.Guild |         self, | ||||||
|  |         discord_channel_id: int, | ||||||
|  |         discord_message_id: int, | ||||||
|  |         rule: AutoRoleRule, | ||||||
|  |         guild: discord.Guild, | ||||||
|     ): |     ): | ||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
| @@ -18,7 +18,9 @@ class CustomFileLoggerABC(Logger, ABC): | |||||||
|         env: ApplicationEnvironmentABC, |         env: ApplicationEnvironmentABC, | ||||||
|     ): |     ): | ||||||
|         self._key = key |         self._key = key | ||||||
|         self._settings: LoggingSettings = config.get_configuration(f"{FileLoggingSettings.__name__}_{key}") |         self._settings: LoggingSettings = config.get_configuration( | ||||||
|  |             f"{FileLoggingSettings.__name__}_{key}" | ||||||
|  |         ) | ||||||
|         Logger.__init__(self, self._settings, time_format, env) |         Logger.__init__(self, self._settings, time_format, env) | ||||||
|         self._begin_log() |         self._begin_log() | ||||||
| 
 | 
 | ||||||
| @@ -32,7 +34,9 @@ class CustomFileLoggerABC(Logger, ABC): | |||||||
|         self.info(__name__, f"Starting...") |         self.info(__name__, f"Starting...") | ||||||
|         self._console = LoggingLevelEnum(console_level) |         self._console = LoggingLevelEnum(console_level) | ||||||
| 
 | 
 | ||||||
|     def _get_string(self, name_list_as_str: str, level: LoggingLevelEnum, message: str) -> str: |     def _get_string( | ||||||
|  |         self, name_list_as_str: str, level: LoggingLevelEnum, message: str | ||||||
|  |     ) -> str: | ||||||
|         names = name_list_as_str.split(" ") |         names = name_list_as_str.split(" ") | ||||||
|         log_level = level.name |         log_level = level.name | ||||||
|         string = f"<{self._get_datetime_now()}> [ {log_level} ]" |         string = f"<{self._get_datetime_now()}> [ {log_level} ]" | ||||||
| @@ -13,7 +13,9 @@ class MessageServiceABC(ABC): | |||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
|     async def delete_messages(self, messages: List[discord.Message], guild_id: int, without_tracking=False): |     async def delete_messages( | ||||||
|  |         self, messages: List[discord.Message], guild_id: int, without_tracking=False | ||||||
|  |     ): | ||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
							
								
								
									
										30
									
								
								bot/src/bot_core/abc/task_abc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								bot/src/bot_core/abc/task_abc.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | import asyncio | ||||||
|  | from abc import abstractmethod | ||||||
|  |  | ||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
|  | from cpl_core.dependency_injection import ServiceProviderABC | ||||||
|  | from cpl_discord.service import DiscordBotServiceABC | ||||||
|  | from discord.ext import commands | ||||||
|  |  | ||||||
|  | from bot_core.logging.task_logger import TaskLogger | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TaskABC(commands.Cog): | ||||||
|  |     @abstractmethod | ||||||
|  |     def __init__(self): | ||||||
|  |         commands.Cog.__init__(self) | ||||||
|  |  | ||||||
|  |     @ServiceProviderABC.inject | ||||||
|  |     async def _wait_until_ready( | ||||||
|  |         self, config: ConfigurationABC, logger: TaskLogger, bot: DiscordBotServiceABC | ||||||
|  |     ): | ||||||
|  |         logger.debug(__name__, f"Waiting before {type(self).__name__}") | ||||||
|  |         await bot.wait_until_ready() | ||||||
|  |  | ||||||
|  |         async def wait(): | ||||||
|  |             is_ready = config.get_configuration("IS_READY") | ||||||
|  |             if is_ready != "true": | ||||||
|  |                 await asyncio.sleep(1) | ||||||
|  |                 await wait() | ||||||
|  |  | ||||||
|  |         await wait() | ||||||
| @@ -3,8 +3,8 @@ | |||||||
|     "Name": "bot-core", |     "Name": "bot-core", | ||||||
|     "Version": { |     "Version": { | ||||||
|       "Major": "1", |       "Major": "1", | ||||||
|       "Minor": "1", |       "Minor": "2", | ||||||
|       "Micro": "8" |       "Micro": "0" | ||||||
|     }, |     }, | ||||||
|     "Author": "Sven Heidemann", |     "Author": "Sven Heidemann", | ||||||
|     "AuthorEmail": "sven.heidemann@sh-edraft.de", |     "AuthorEmail": "sven.heidemann@sh-edraft.de", | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.configuration" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -17,6 +17,7 @@ class FeatureFlagsEnum(Enum): | |||||||
|     moderator_module = "ModeratorModule" |     moderator_module = "ModeratorModule" | ||||||
|     permission_module = "PermissionModule" |     permission_module = "PermissionModule" | ||||||
|     short_role_name_module = "ShortRoleNameModule" |     short_role_name_module = "ShortRoleNameModule" | ||||||
|  |     steam_special_offers_module = "SteamSpecialOffersModule" | ||||||
|     # features |     # features | ||||||
|     api_only = "ApiOnly" |     api_only = "ApiOnly" | ||||||
|     presence = "Presence" |     presence = "Presence" | ||||||
| @@ -24,3 +25,5 @@ class FeatureFlagsEnum(Enum): | |||||||
|     game_server = "GameServer" |     game_server = "GameServer" | ||||||
|     sync_xp = "SyncXp" |     sync_xp = "SyncXp" | ||||||
|     short_role_name = "ShortRoleName" |     short_role_name = "ShortRoleName" | ||||||
|  |     technician_full_access = "TechnicianFullAccess" | ||||||
|  |     steam_special_offers = "SteamSpecialOffers" | ||||||
| @@ -19,6 +19,7 @@ class FeatureFlagsSettings(ConfigurationModelABC): | |||||||
|         FeatureFlagsEnum.permission_module.value: True,  # 02.10.2022 #48 |         FeatureFlagsEnum.permission_module.value: True,  # 02.10.2022 #48 | ||||||
|         FeatureFlagsEnum.config_module.value: True,  # 19.07.2023 #127 |         FeatureFlagsEnum.config_module.value: True,  # 19.07.2023 #127 | ||||||
|         FeatureFlagsEnum.short_role_name_module.value: True,  # 28.09.2023 #378 |         FeatureFlagsEnum.short_role_name_module.value: True,  # 28.09.2023 #378 | ||||||
|  |         FeatureFlagsEnum.steam_special_offers_module.value: True,  # 11.10.2023 #188 | ||||||
|         # features |         # features | ||||||
|         FeatureFlagsEnum.api_only.value: False,  # 13.10.2022 #70 |         FeatureFlagsEnum.api_only.value: False,  # 13.10.2022 #70 | ||||||
|         FeatureFlagsEnum.presence.value: True,  # 03.10.2022 #56 |         FeatureFlagsEnum.presence.value: True,  # 03.10.2022 #56 | ||||||
| @@ -26,6 +27,8 @@ class FeatureFlagsSettings(ConfigurationModelABC): | |||||||
|         FeatureFlagsEnum.game_server.value: False,  # 25.09.2023 #366 |         FeatureFlagsEnum.game_server.value: False,  # 25.09.2023 #366 | ||||||
|         FeatureFlagsEnum.sync_xp.value: False,  # 25.09.2023 #366 |         FeatureFlagsEnum.sync_xp.value: False,  # 25.09.2023 #366 | ||||||
|         FeatureFlagsEnum.short_role_name.value: False,  # 28.09.2023 #378 |         FeatureFlagsEnum.short_role_name.value: False,  # 28.09.2023 #378 | ||||||
|  |         FeatureFlagsEnum.technician_full_access.value: False,  # 03.10.2023 #393 | ||||||
|  |         FeatureFlagsEnum.steam_special_offers.value: False,  # 11.10.2023 #188 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     def __init__(self, **kwargs: dict): |     def __init__(self, **kwargs: dict): | ||||||
| @@ -10,7 +10,9 @@ class FileLoggingSettings(LoggingSettings): | |||||||
|         console_log_level: LoggingLevelEnum = None, |         console_log_level: LoggingLevelEnum = None, | ||||||
|         file_log_level: LoggingLevelEnum = None, |         file_log_level: LoggingLevelEnum = None, | ||||||
|     ): |     ): | ||||||
|         LoggingSettings.__init__(self, path, filename, console_log_level, file_log_level) |         LoggingSettings.__init__( | ||||||
|  |             self, path, filename, console_log_level, file_log_level | ||||||
|  |         ) | ||||||
| 
 | 
 | ||||||
|         self._key = key |         self._key = key | ||||||
| 
 | 
 | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.core_extension" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -17,7 +17,9 @@ class CoreExtension(ApplicationExtensionABC): | |||||||
|         ApplicationExtensionABC.__init__(self) |         ApplicationExtensionABC.__init__(self) | ||||||
| 
 | 
 | ||||||
|     async def run(self, config: ConfigurationABC, services: ServiceProviderABC): |     async def run(self, config: ConfigurationABC, services: ServiceProviderABC): | ||||||
|         feature_flags: FeatureFlagsSettings = config.get_configuration(FeatureFlagsSettings) |         feature_flags: FeatureFlagsSettings = config.get_configuration( | ||||||
|  |             FeatureFlagsSettings | ||||||
|  |         ) | ||||||
|         if not feature_flags.get_flag(FeatureFlagsEnum.core_module): |         if not feature_flags.get_flag(FeatureFlagsEnum.core_module): | ||||||
|             return |             return | ||||||
| 
 | 
 | ||||||
| @@ -15,8 +15,14 @@ class CoreExtensionModule(ModuleABC): | |||||||
|     def __init__(self, dc: DiscordCollectionABC): |     def __init__(self, dc: DiscordCollectionABC): | ||||||
|         ModuleABC.__init__(self, dc, FeatureFlagsEnum.core_extension_module) |         ModuleABC.__init__(self, dc, FeatureFlagsEnum.core_extension_module) | ||||||
| 
 | 
 | ||||||
|     def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): |     def configure_configuration( | ||||||
|  |         self, config: ConfigurationABC, env: ApplicationEnvironmentABC | ||||||
|  |     ): | ||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
|     def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): |     def configure_services( | ||||||
|         self._dc.add_event(DiscordEventTypesEnum.on_ready.value, CoreExtensionOnReadyEvent) |         self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC | ||||||
|  |     ): | ||||||
|  |         services.add_transient( | ||||||
|  |             DiscordEventTypesEnum.on_ready.value, CoreExtensionOnReadyEvent | ||||||
|  |         ) | ||||||
| @@ -20,10 +20,14 @@ class CoreModule(ModuleABC): | |||||||
|     def __init__(self, dc: DiscordCollectionABC): |     def __init__(self, dc: DiscordCollectionABC): | ||||||
|         ModuleABC.__init__(self, dc, FeatureFlagsEnum.core_module) |         ModuleABC.__init__(self, dc, FeatureFlagsEnum.core_module) | ||||||
| 
 | 
 | ||||||
|     def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): |     def configure_configuration( | ||||||
|  |         self, config: ConfigurationABC, env: ApplicationEnvironmentABC | ||||||
|  |     ): | ||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
|     def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): |     def configure_services( | ||||||
|  |         self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC | ||||||
|  |     ): | ||||||
|         services.add_transient(ConfigService) |         services.add_transient(ConfigService) | ||||||
|         services.add_transient(MessageServiceABC, MessageService) |         services.add_transient(MessageServiceABC, MessageService) | ||||||
|         services.add_transient(ClientUtilsABC, ClientUtilsService) |         services.add_transient(ClientUtilsABC, ClientUtilsService) | ||||||
| @@ -32,4 +36,4 @@ class CoreModule(ModuleABC): | |||||||
|         # pipes |         # pipes | ||||||
|         services.add_transient(DateTimeOffsetPipe) |         services.add_transient(DateTimeOffsetPipe) | ||||||
| 
 | 
 | ||||||
|         self._dc.add_event(DiscordEventTypesEnum.on_ready.value, CoreOnReadyEvent) |         services.add_transient(DiscordEventTypesEnum.on_ready.value, CoreOnReadyEvent) | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.events" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.exception" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.1.8" | __version__ = "1.2.0" | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | |||||||
| # imports: | # imports: | ||||||
| 
 | 
 | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||||
| version_info = VersionInfo(major="1", minor="1", micro="8") | version_info = VersionInfo(major="1", minor="2", micro="0") | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user