#334_feature_flags_in_wi #335
| @@ -9,6 +9,7 @@ from cpl_query.extension import List | ||||
| from bot_api.exception.service_error_code_enum import ServiceErrorCode | ||||
| from bot_api.exception.service_exception import ServiceException | ||||
| from bot_api.route.route import Route | ||||
| from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||
| from bot_data.model.auth_role_enum import AuthRoleEnum | ||||
| from bot_data.model.auth_user import AuthUser | ||||
| from bot_data.model.auto_role import AutoRole | ||||
| @@ -17,6 +18,7 @@ from bot_data.model.client import Client | ||||
| from bot_data.model.known_user import KnownUser | ||||
| from bot_data.model.level import Level | ||||
| from bot_data.model.server import Server | ||||
| from bot_data.model.server_config import ServerConfig | ||||
| from bot_data.model.user import User | ||||
| from bot_data.model.user_joined_game_server import UserJoinedGameServer | ||||
| from bot_data.model.user_joined_server import UserJoinedServer | ||||
| @@ -66,8 +68,12 @@ class QueryABC(ObjectType): | ||||
|         self.set_field(f"{name}s", wrapper) | ||||
|         self.set_field(f"{name}Count", lambda *args: wrapper(*args).count()) | ||||
|  | ||||
|     @ServiceProviderABC.inject | ||||
|     def _can_user_see_element(self, user: AuthUser, element: T, services: ServiceProviderABC) -> bool: | ||||
|     def _can_user_see_element(self, user: AuthUser, element: T) -> bool: | ||||
|         @ServiceProviderABC.inject | ||||
|         def get_services(services: ServiceProviderABC) -> ServiceProviderABC: | ||||
|             return services | ||||
|  | ||||
|         services = get_services() | ||||
|         permissions: PermissionService = services.get_service(PermissionService) | ||||
|         bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC) | ||||
|  | ||||
| @@ -158,6 +164,24 @@ class QueryABC(ObjectType): | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
|         elif type(element) == ServerConfig: | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if permissions.is_member_technician(member): | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
|         elif type(element) == dict and "key" in element and element["key"] in [e.value for e in FeatureFlagsEnum]: | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if permissions.is_member_technician(member): | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
|         return access | ||||
|  | ||||
|     @ServiceProviderABC.inject | ||||
|   | ||||
| @@ -13,6 +13,7 @@ type ServerConfig implements TableWithHistoryQuery { | ||||
|     helpVoiceChannelId: String | ||||
|     teamChannelId: String | ||||
|     loginMessageChannelId: String | ||||
|     featureFlagCount: Int | ||||
|     featureFlags: [FeatureFlag] | ||||
|  | ||||
|     afkChannelIds: [String] | ||||
| @@ -42,6 +43,7 @@ type ServerConfigHistory implements HistoryTableQuery { | ||||
|     helpVoiceChannelId: String | ||||
|     teamChannelId: String | ||||
|     loginMessageChannelId: String | ||||
|     featureFlagCount: Int | ||||
|     featureFlags: [FeatureFlag] | ||||
|  | ||||
|     serverId: ID | ||||
|   | ||||
| @@ -4,6 +4,7 @@ type TechnicianConfig implements TableWithHistoryQuery { | ||||
|     waitForRestart: Int | ||||
|     waitForShutdown: Int | ||||
|     cacheMaxMessages: Int | ||||
|     featureFlagCount: Int | ||||
|     featureFlags: [FeatureFlag] | ||||
|     pingURLs: [String] | ||||
|     technicianIds: [String] | ||||
| @@ -22,6 +23,7 @@ type TechnicianConfigHistory implements HistoryTableQuery { | ||||
|     waitForRestart: Int | ||||
|     waitForShutdown: Int | ||||
|     cacheMaxMessages: Int | ||||
|     featureFlagCount: Int | ||||
|     featureFlags: [FeatureFlag] | ||||
|  | ||||
|     deleted: Boolean | ||||
|   | ||||
| @@ -3,6 +3,7 @@ from cpl_discord.service import DiscordBotServiceABC | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_api.logging.api_logger import ApiLogger | ||||
| from bot_api.route.route import Route | ||||
| from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC | ||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||
| from bot_data.model.server_afk_channel_ids_config import ServerAFKChannelIdsConfig | ||||
| @@ -37,7 +38,7 @@ class ServerConfigMutation(QueryABC): | ||||
|             raise ValueError("Id not set") | ||||
|  | ||||
|         server_config = self._server_configs.get_server_config_by_server(input["id"]) | ||||
|         self._can_user_mutate_data(server_config, UserRoleEnum.admin) | ||||
|         self._can_user_mutate_data(Route.get_user().users[0].server, UserRoleEnum.technician) | ||||
|  | ||||
|         server_config.message_delete_timer = ( | ||||
|             input["messageDeleteTimer"] if "messageDeleteTimer" in input else server_config.message_delete_timer | ||||
| @@ -166,3 +167,6 @@ class ServerConfigMutation(QueryABC): | ||||
|                 continue | ||||
|  | ||||
|             self._server_configs.add_server_team_role_id_config(role_id) | ||||
|  | ||||
|         # todo reload config | ||||
|         # reload permissions | ||||
|   | ||||
| @@ -3,6 +3,7 @@ from cpl_discord.service import DiscordBotServiceABC | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_api.logging.api_logger import ApiLogger | ||||
| from bot_api.route.route import Route | ||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||
| from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC | ||||
| from bot_data.model.technician_config import TechnicianConfig | ||||
| @@ -10,6 +11,7 @@ from bot_data.model.technician_id_config import TechnicianIdConfig | ||||
| from bot_data.model.technician_ping_url_config import TechnicianPingUrlConfig | ||||
| from bot_data.model.user_role_enum import UserRoleEnum | ||||
| from bot_graphql.abc.query_abc import QueryABC | ||||
| from modules.permission.abc.permission_service_abc import PermissionServiceABC | ||||
|  | ||||
|  | ||||
| class TechnicianConfigMutation(QueryABC): | ||||
| @@ -20,6 +22,7 @@ class TechnicianConfigMutation(QueryABC): | ||||
|         servers: ServerRepositoryABC, | ||||
|         technician_configs: TechnicianConfigRepositoryABC, | ||||
|         db: DatabaseContextABC, | ||||
|         permissions: PermissionServiceABC, | ||||
|     ): | ||||
|         QueryABC.__init__(self, "TechnicianConfigMutation") | ||||
|  | ||||
| @@ -28,12 +31,13 @@ class TechnicianConfigMutation(QueryABC): | ||||
|         self._servers = servers | ||||
|         self._technician_configs = technician_configs | ||||
|         self._db = db | ||||
|         self._permissions = permissions | ||||
|  | ||||
|         self.set_field("updateTechnicianConfig", self.resolve_update_technician_config) | ||||
|  | ||||
|     def resolve_update_technician_config(self, *_, input: dict): | ||||
|         technician_config = self._technician_configs.get_technician_config() | ||||
|         self._can_user_mutate_data(technician_config, UserRoleEnum.admin) | ||||
|         self._can_user_mutate_data(Route.get_user().users[0].server, UserRoleEnum.technician) | ||||
|  | ||||
|         technician_config.help_command_reference_url = ( | ||||
|             input["helpCommandReferenceUrl"] | ||||
| @@ -105,3 +109,6 @@ class TechnicianConfigMutation(QueryABC): | ||||
|                 continue | ||||
|  | ||||
|             self._technician_configs.add_technician_id_config(TechnicianIdConfig(technician_id)) | ||||
|  | ||||
|         # todo reload config | ||||
|         self._permissions.on_ready() | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| from cpl_core.database.context import DatabaseContextABC | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_data.model.server_config_history import ServerConfigHistory | ||||
| from bot_data.model.team_member_type_enum import TeamMemberTypeEnum | ||||
| @@ -23,9 +24,9 @@ class ServerConfigQuery(DataQueryWithHistoryABC): | ||||
|         self.set_field("helpVoiceChannelId", lambda config, *_: config.help_voice_channel_id) | ||||
|         self.set_field("teamChannelId", lambda config, *_: config.team_channel_id) | ||||
|         self.set_field("loginMessageChannelId", lambda config, *_: config.login_message_channel_id) | ||||
|         self.set_field( | ||||
|             "featureFlags", | ||||
|             lambda config, *_: [{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags], | ||||
|         self.add_collection( | ||||
|             "featureFlag", | ||||
|             lambda config, *_: List(any, [{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags]), | ||||
|         ) | ||||
|         self.set_field("afkChannelIds", lambda config, *_: config.afk_channel_ids) | ||||
|         self.set_field( | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_graphql.abc.history_query_abc import HistoryQueryABC | ||||
|  | ||||
|  | ||||
| @@ -9,7 +11,7 @@ class TechnicianConfigHistoryQuery(HistoryQueryABC): | ||||
|         self.set_field("waitForRestart", lambda config, *_: config.wait_for_restart) | ||||
|         self.set_field("waitForShutdown", lambda config, *_: config.wait_for_shutdown) | ||||
|         self.set_field("cacheMaxMessages", lambda config, *_: config.cache_max_messages) | ||||
|         self.set_field( | ||||
|             "featureFlags", | ||||
|             lambda config, *_: [{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags], | ||||
|         self.add_collection( | ||||
|             "featureFlag", | ||||
|             lambda config, *_: List(any, [{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags]), | ||||
|         ) | ||||
|   | ||||
| @@ -16,9 +16,9 @@ class TechnicianConfigQuery(DataQueryWithHistoryABC): | ||||
|         self.set_field("waitForRestart", lambda config, *_: config.wait_for_restart) | ||||
|         self.set_field("waitForShutdown", lambda config, *_: config.wait_for_shutdown) | ||||
|         self.set_field("cacheMaxMessages", lambda config, *_: config.cache_max_messages) | ||||
|         self.set_field( | ||||
|             "featureFlags", | ||||
|             lambda config, *_: [{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags], | ||||
|         self.add_collection( | ||||
|             "featureFlag", | ||||
|             lambda config, *_: List(any, [{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags]), | ||||
|         ) | ||||
|         self.set_field("pingURLs", lambda config, *_: config.ping_urls) | ||||
|         self.set_field("technicianIds", lambda config, *_: config.technician_ids) | ||||
|   | ||||
| @@ -28,8 +28,11 @@ export class AuthGuard implements CanActivate { | ||||
|  | ||||
|     const role = route.data['role']; | ||||
|     if (role) { | ||||
|       this.authService.hasUserPermission(role).then(hasPermission => { | ||||
|         if (!hasPermission) { | ||||
|       this.authService.hasUserPermission(role).then(async hasPermission => { | ||||
|         let authUser = await this.authService.getLoggedInUser(); | ||||
|         let isTechnician = authUser?.users?.map(u => u.isTechnician).filter(u => u) ?? []; | ||||
|  | ||||
|         if (!hasPermission && !isTechnician) { | ||||
|           this.router.navigate(['/dashboard']); | ||||
|           return false; | ||||
|         } | ||||
|   | ||||
| @@ -67,7 +67,7 @@ export class SidebarService { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async buildMenu(user: UserDTO | null, hasPermission: boolean) { | ||||
|   async buildMenu(user: UserDTO | null, hasPermission: boolean, isTechnician: boolean = false) { | ||||
|     this.dashboard = { | ||||
|       label: this.isSidebarOpen ? this.translateService.instant("sidebar.dashboard") : "", | ||||
|       icon: "pi pi-th-large", | ||||
| @@ -127,18 +127,20 @@ export class SidebarService { | ||||
|     }; | ||||
|     this.adminConfig = { | ||||
|       label: this.isSidebarOpen ? this.translateService.instant("sidebar.config") : "", | ||||
|       visible: hasPermission || isTechnician, | ||||
|       icon: "pi pi-cog", | ||||
|       routerLink: "/admin/settings" | ||||
|     }; | ||||
|     this.adminUsers = { | ||||
|       label: this.isSidebarOpen ? this.translateService.instant("sidebar.auth_user_list") : "", | ||||
|       visible: hasPermission, | ||||
|       icon: "pi pi-user-edit", | ||||
|       routerLink: "/admin/users" | ||||
|     }; | ||||
|     this.adminMenu = { | ||||
|       label: this.isSidebarOpen ? this.translateService.instant("sidebar.administration") : "", | ||||
|       icon: "pi pi-cog", | ||||
|       visible: hasPermission, | ||||
|       visible: hasPermission || isTechnician, | ||||
|       expanded: true, | ||||
|       items: [this.adminConfig, this.adminUsers] | ||||
|     }; | ||||
| @@ -148,9 +150,10 @@ export class SidebarService { | ||||
|     this.authService.hasUserPermission(AuthRoles.Admin).then(async hasPermission => { | ||||
|       let authUser = await this.authService.getLoggedInUser(); | ||||
|       let user: UserDTO | null = authUser?.users?.find(u => u.server == this.server$.value?.id) ?? null; | ||||
|       let isTechnician = authUser?.users?.map(u => u.isTechnician).filter(u => u) ?? []; | ||||
|  | ||||
|       if (build || this.menuItems$.value.length == 0) { | ||||
|         await this.buildMenu(user, hasPermission); | ||||
|         await this.buildMenu(user, hasPermission, isTechnician.length > 0); | ||||
|       } | ||||
|  | ||||
|       if (this.server$.value) { | ||||
| @@ -159,7 +162,7 @@ export class SidebarService { | ||||
|         this.serverAutoRoles.visible = !!user?.isModerator; | ||||
|         this.serverLevels.visible = !!user?.isModerator; | ||||
|         this.serverAchievements.visible = !!user?.isModerator; | ||||
|         this.serverConfig.visible = !!user?.isAdmin; | ||||
|         this.serverConfig.visible = !!user?.isAdmin || isTechnician.length > 0; | ||||
|       } else { | ||||
|         this.serverMenu.visible = false; | ||||
|       } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user