Improved permission handling
This commit is contained in:
parent
ff247bcec3
commit
a8663b8d54
@ -71,12 +71,10 @@ class Startup(StartupABC):
|
|||||||
|
|
||||||
services.add_db_context(DBContext, self._config.get_configuration(DatabaseSettings))
|
services.add_db_context(DBContext, self._config.get_configuration(DatabaseSettings))
|
||||||
|
|
||||||
# modules
|
# general services
|
||||||
services.add_singleton(ModuleServiceABC, ModuleService)
|
services.add_singleton(ModuleServiceABC, ModuleService)
|
||||||
services.add_singleton(BotServiceABC, BotService)
|
services.add_singleton(BotServiceABC, BotService)
|
||||||
services.add_transient(MessageServiceABC, MessageService)
|
services.add_transient(MessageServiceABC, MessageService)
|
||||||
|
|
||||||
# general services
|
|
||||||
services.add_transient(MigrationService)
|
services.add_transient(MigrationService)
|
||||||
|
|
||||||
# data services
|
# data services
|
||||||
@ -87,14 +85,15 @@ class Startup(StartupABC):
|
|||||||
services.add_transient(UserJoinedServerRepositoryABC, UserJoinedServerRepositoryService)
|
services.add_transient(UserJoinedServerRepositoryABC, UserJoinedServerRepositoryService)
|
||||||
services.add_transient(UserJoinedVoiceChannelRepositoryABC, UserJoinedVoiceChannelRepositoryService)
|
services.add_transient(UserJoinedVoiceChannelRepositoryABC, UserJoinedVoiceChannelRepositoryService)
|
||||||
|
|
||||||
# modules
|
# module services
|
||||||
services.add_transient(ModuleABC, Permission)
|
services.add_singleton(PermissionServiceABC, PermissionService)
|
||||||
services.add_transient(ModuleABC, Database)
|
|
||||||
services.add_transient(ModuleABC, Base)
|
# modules
|
||||||
services.add_transient(ModuleABC, BootLog)
|
services.add_transient(ModuleABC, Database)
|
||||||
|
services.add_transient(ModuleABC, BootLog)
|
||||||
|
services.add_singleton(ModuleABC, Permission)
|
||||||
|
services.add_singleton(ModuleABC, Base)
|
||||||
|
|
||||||
# permission module services
|
|
||||||
services.add_transient(PermissionServiceABC, PermissionService)
|
|
||||||
|
|
||||||
# migrations
|
# migrations
|
||||||
services.add_transient(MigrationABC, InitialMigration)
|
services.add_transient(MigrationABC, InitialMigration)
|
||||||
|
@ -20,6 +20,7 @@ from gismo_data.model.user import User
|
|||||||
from gismo_data.model.user_joined_server import UserJoinedServer
|
from gismo_data.model.user_joined_server import UserJoinedServer
|
||||||
from gismo_data.model.user_joined_voice_channel import UserJoinedVoiceChannel
|
from gismo_data.model.user_joined_voice_channel import UserJoinedVoiceChannel
|
||||||
from modules.base.base_settings import BaseSettings
|
from modules.base.base_settings import BaseSettings
|
||||||
|
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
||||||
from modules_core.abc.events.on_member_join_abc import OnMemberJoinABC
|
from modules_core.abc.events.on_member_join_abc import OnMemberJoinABC
|
||||||
from modules_core.abc.events.on_member_remove_abc import OnMemberRemoveABC
|
from modules_core.abc.events.on_member_remove_abc import OnMemberRemoveABC
|
||||||
from modules_core.abc.events.on_message_abc import OnMessageABC
|
from modules_core.abc.events.on_message_abc import OnMessageABC
|
||||||
@ -42,7 +43,8 @@ class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceS
|
|||||||
user_joins_vc: UserJoinedVoiceChannelRepositoryABC,
|
user_joins_vc: UserJoinedVoiceChannelRepositoryABC,
|
||||||
bot: BotServiceABC,
|
bot: BotServiceABC,
|
||||||
db: DatabaseContextABC,
|
db: DatabaseContextABC,
|
||||||
messenger: MessageServiceABC
|
messenger: MessageServiceABC,
|
||||||
|
permission_service: PermissionServiceABC
|
||||||
):
|
):
|
||||||
self._config = config
|
self._config = config
|
||||||
self._logger = logger
|
self._logger = logger
|
||||||
@ -55,6 +57,7 @@ class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceS
|
|||||||
self._bot = bot
|
self._bot = bot
|
||||||
self._db = db
|
self._db = db
|
||||||
self._messenger = messenger
|
self._messenger = messenger
|
||||||
|
self._permission_service = permission_service
|
||||||
|
|
||||||
ModuleABC.__init__(
|
ModuleABC.__init__(
|
||||||
self,
|
self,
|
||||||
@ -66,7 +69,7 @@ class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceS
|
|||||||
},
|
},
|
||||||
BaseSettings
|
BaseSettings
|
||||||
)
|
)
|
||||||
self._logger.trace(__name__, f'Module {type(self)} loaded')
|
self._logger.info(__name__, f'Module {type(self)} loaded')
|
||||||
|
|
||||||
def _get_config(self, g_id: int) -> BaseSettings:
|
def _get_config(self, g_id: int) -> BaseSettings:
|
||||||
return self._config.get_configuration(f'{type(self).__name__}_{g_id}')
|
return self._config.get_configuration(f'{type(self).__name__}_{g_id}')
|
||||||
@ -100,21 +103,14 @@ class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceS
|
|||||||
|
|
||||||
async def _add_if_not_exists_user(self, member: Union[discord.User, discord.Member]):
|
async def _add_if_not_exists_user(self, member: Union[discord.User, discord.Member]):
|
||||||
self._logger.debug(__name__, f'Check if user exists {member}')
|
self._logger.debug(__name__, f'Check if user exists {member}')
|
||||||
# todo: user permission service
|
|
||||||
settings: BaseSettings = self._get_config()
|
settings: BaseSettings = self._get_config()
|
||||||
await self._messenger.send_dm_message(settings.welcome_message.format(member.guild.name), member)
|
await self._messenger.send_dm_message(settings.welcome_message.format(member.guild.name), member)
|
||||||
|
|
||||||
for roleId in settings.admin_roles:
|
for admin in self._permission_service.get_admins():
|
||||||
g: discord.Guild = member.guild
|
await self._messenger.send_dm_message(settings.welcome_message_for_team.format(member.name), admin)
|
||||||
role: discord.Role = g.get_role(roleId)
|
|
||||||
for admin in role.members:
|
|
||||||
await self._messenger.send_dm_message(settings.welcome_message_for_team.format(member.name), admin)
|
|
||||||
|
|
||||||
for roleId in settings.moderator_roles:
|
for moderator in self._permission_service.get_moderators():
|
||||||
g: discord.Guild = member.guild
|
await self._messenger.send_dm_message(settings.welcome_message_for_team.format(member.name), moderator)
|
||||||
role: discord.Role = g.get_role(roleId)
|
|
||||||
for mod in role.members:
|
|
||||||
await self._messenger.send_dm_message(settings.welcome_message_for_team.format(member.name), mod)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
server = self._servers.get_server_by_discord_id(member.guild.id)
|
server = self._servers.get_server_by_discord_id(member.guild.id)
|
||||||
|
@ -35,7 +35,7 @@ class BootLog(ModuleABC, OnReadyABC):
|
|||||||
},
|
},
|
||||||
BootLogSettings
|
BootLogSettings
|
||||||
)
|
)
|
||||||
self._logger.trace(__name__, f'Module {type(self)} loaded')
|
self._logger.info(__name__, f'Module {type(self)} loaded')
|
||||||
|
|
||||||
async def on_ready(self):
|
async def on_ready(self):
|
||||||
self._logger.debug(__name__, f'Module {type(self)} started')
|
self._logger.debug(__name__, f'Module {type(self)} started')
|
||||||
|
@ -57,7 +57,7 @@ class Database(ModuleABC, OnReadyABC):
|
|||||||
{ OnReadyABC: 0 },
|
{ OnReadyABC: 0 },
|
||||||
None
|
None
|
||||||
)
|
)
|
||||||
self._logger.trace(__name__, f'Module {type(self)} loaded')
|
self._logger.info(__name__, f'Module {type(self)} loaded')
|
||||||
|
|
||||||
def _validate_init_time(self):
|
def _validate_init_time(self):
|
||||||
try:
|
try:
|
||||||
|
@ -1,7 +1,32 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
import discord
|
||||||
|
|
||||||
class PermissionServiceABC(ABC):
|
class PermissionServiceABC(ABC):
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def __init__(self): pass
|
def __init__(self): pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def on_ready(self): pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def on_member_update(self, before: discord.Member, after: discord.Member): pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_admin_role_ids(self, g_id: int) -> list[int]: pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_admin_roles(self, g_id: int) -> list[discord.Role]: pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_admins(self, g_id: int) -> list[discord.Member]: pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_moderator_role_ids(self, g_id: int) -> list[int]: pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_moderator_roles(self, g_id: int) -> list[discord.Role]: pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_moderators(self, g_id: int) -> list[discord.Member]: pass
|
||||||
|
@ -12,7 +12,6 @@ class PermissionSettings(ConfigurationModelABC):
|
|||||||
self._admin_roles: list[int] = []
|
self._admin_roles: list[int] = []
|
||||||
self._moderator_roles: list[int] = []
|
self._moderator_roles: list[int] = []
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def admin_roles(self) -> list[int]:
|
def admin_roles(self) -> list[int]:
|
||||||
return self._admin_roles
|
return self._admin_roles
|
||||||
|
@ -1,41 +1,37 @@
|
|||||||
from ctypes import Union
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.database.context import DatabaseContextABC
|
|
||||||
from cpl_core.logging import LoggerABC
|
|
||||||
|
|
||||||
from gismo_core.abc.bot_service_abc import BotServiceABC
|
from cpl_core.logging import LoggerABC
|
||||||
from gismo_core.configuration.server_settings import ServerSettings
|
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
||||||
from gismo_data.abc.client_repository_abc import ClientRepositoryABC
|
from modules.permission.configuration.permission_settings import \
|
||||||
from gismo_data.abc.known_user_repository_abc import KnownUserRepositoryABC
|
PermissionSettings
|
||||||
from gismo_data.abc.user_joined_server_repository_abc import \
|
from modules_core.abc.events.on_member_update_abc import OnMemberUpdateABC
|
||||||
UserJoinedServerRepositoryABC
|
|
||||||
from gismo_data.abc.user_joined_voice_channel_abc import UserJoinedVoiceChannelRepositoryABC
|
|
||||||
from gismo_data.abc.user_repository_abc import UserRepositoryABC
|
|
||||||
from gismo_data.model.client import Client
|
|
||||||
from gismo_data.model.known_user import KnownUser
|
|
||||||
from gismo_data.model.server import Server
|
|
||||||
from gismo_data.model.user import User
|
|
||||||
from gismo_data.model.user_joined_server import UserJoinedServer
|
|
||||||
from gismo_data.model.user_joined_voice_channel import UserJoinedVoiceChannel
|
|
||||||
from gismo_data.service.user_repository_service import ServerRepositoryABC
|
|
||||||
from modules.permission.configuration.permission_settings import PermissionSettings
|
|
||||||
from modules_core.abc.events.on_ready_abc import OnReadyABC
|
from modules_core.abc.events.on_ready_abc import OnReadyABC
|
||||||
from modules_core.abc.module_abc import ModuleABC
|
from modules_core.abc.module_abc import ModuleABC
|
||||||
|
|
||||||
|
|
||||||
class Permission(ModuleABC):
|
class Permission(ModuleABC, OnReadyABC, OnMemberUpdateABC):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
logger: LoggerABC,
|
logger: LoggerABC,
|
||||||
|
permission_service: PermissionServiceABC
|
||||||
):
|
):
|
||||||
self._logger = logger
|
self._logger = logger
|
||||||
|
self._permission_service = permission_service
|
||||||
|
|
||||||
ModuleABC.__init__(
|
ModuleABC.__init__(
|
||||||
self,
|
self,
|
||||||
{ OnReadyABC: 0 },
|
{ OnReadyABC: 1, OnMemberUpdateABC: 0 },
|
||||||
PermissionSettings
|
PermissionSettings
|
||||||
)
|
)
|
||||||
self._logger.trace(__name__, f'Module {type(self)} loaded')
|
self._logger.info(__name__, f'Module {type(self)} loaded')
|
||||||
|
|
||||||
|
async def on_ready(self):
|
||||||
|
self._logger.debug(__name__, f'Module {type(self)} started')
|
||||||
|
self._permission_service.on_ready()
|
||||||
|
|
||||||
|
async def on_member_update(self, before: discord.Member, after: discord.Member):
|
||||||
|
self._logger.debug(__name__, f'Module {type(self)} started')
|
||||||
|
|
||||||
|
if before.roles != after.roles:
|
||||||
|
self._permission_service.on_member_update(before, after)
|
@ -1,4 +1,88 @@
|
|||||||
class PermissionService:
|
import discord
|
||||||
|
from cpl_core.logging import LoggerABC
|
||||||
|
from cpl_core.configuration import ConfigurationABC
|
||||||
|
from gismo_core.abc.bot_service_abc import BotServiceABC
|
||||||
|
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
||||||
|
from modules.permission.configuration.permission_settings import PermissionSettings
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
class PermissionService(PermissionServiceABC):
|
||||||
|
|
||||||
|
def __init__(self, logger: LoggerABC, bot: BotServiceABC, config: ConfigurationABC):
|
||||||
|
PermissionServiceABC.__init__(self)
|
||||||
|
self._logger = logger
|
||||||
|
self._bot = bot
|
||||||
|
self._config = config
|
||||||
|
|
||||||
|
self._admin_role_ids: dict[str, list[int]] = {}
|
||||||
|
self._admin_roles: dict[list[discord.Role]] = {}
|
||||||
|
self._admins: dict[list[discord.Member]] = {}
|
||||||
|
|
||||||
|
self._moderator_role_ids: dict[list[int]] = {}
|
||||||
|
self._moderator_roles: dict[list[discord.Role]] = {}
|
||||||
|
self._moderators: dict[list[discord.Member]] = {}
|
||||||
|
|
||||||
|
def on_ready(self):
|
||||||
|
for guild in self._bot.guilds:
|
||||||
|
guild: discord.Guild = guild
|
||||||
|
|
||||||
|
settings: PermissionSettings = self._config.get_configuration(f'Permission_{guild.id}')
|
||||||
|
if settings is None:
|
||||||
|
self._logger.error(__name__, 'Permission settings not found')
|
||||||
|
return
|
||||||
|
|
||||||
|
self._admin_role_ids[guild.id] = settings.admin_roles
|
||||||
|
self._admin_roles[guild.id] = []
|
||||||
|
self._admins[guild.id] = []
|
||||||
|
|
||||||
|
self._moderator_role_ids[guild.id] = settings.moderator_roles
|
||||||
|
self._moderator_roles[guild.id] = []
|
||||||
|
self._moderators[guild.id] = []
|
||||||
|
|
||||||
|
for role in guild.roles:
|
||||||
|
role: discord.Role = role
|
||||||
|
|
||||||
|
if role.id in self._admin_role_ids:
|
||||||
|
self._admin_roles[guild.id].append(role)
|
||||||
|
|
||||||
|
for member in role.members:
|
||||||
|
self._admins[guild.id].append(member)
|
||||||
|
|
||||||
|
if role.id in self._moderator_role_ids:
|
||||||
|
self._moderator_roles[guild.id].append(role)
|
||||||
|
|
||||||
|
for member in role.members:
|
||||||
|
self._moderators[guild.id].append(member)
|
||||||
|
|
||||||
|
def on_member_update(self, before: discord.Member, after: discord.Member):
|
||||||
|
g_id = after.guild.id
|
||||||
|
|
||||||
|
if before in self._admin_roles[g_id] and after not in self._admin_roles[g_id]:
|
||||||
|
self._admins[g_id].remove(after)
|
||||||
|
|
||||||
|
elif before not in self._admin_roles[g_id] and after in self._admin_roles[g_id]:
|
||||||
|
self._admins[g_id].append(after)
|
||||||
|
|
||||||
|
if before in self._moderator_roles[g_id] and after not in self._moderator_roles[g_id]:
|
||||||
|
self._moderators[g_id].remove(after)
|
||||||
|
|
||||||
|
elif before not in self._moderator_roles[g_id] and after in self._moderator_roles[g_id]:
|
||||||
|
self._moderators[g_id].append(after)
|
||||||
|
|
||||||
|
def get_admin_role_ids(self, g_id: int) -> list[int]:
|
||||||
|
return self._admin_role_ids[g_id]
|
||||||
|
|
||||||
|
def get_admin_roles(self, g_id: int) -> list[discord.Role]:
|
||||||
|
return self._admin_roles[g_id]
|
||||||
|
|
||||||
|
def get_admins(self, g_id: int) -> list[discord.Member]:
|
||||||
|
return self._admins[g_id]
|
||||||
|
|
||||||
|
def get_moderator_role_ids(self, g_id: int) -> list[int]:
|
||||||
|
return self._moderator_role_ids[g_id]
|
||||||
|
|
||||||
|
def get_moderator_roles(self, g_id: int) -> list[discord.Role]:
|
||||||
|
return self._moderator_roles[g_id]
|
||||||
|
|
||||||
|
def get_moderators(self, g_id: int) -> list[discord.Member]:
|
||||||
|
return self._moderators[g_id]
|
||||||
|
@ -90,7 +90,7 @@ class ModuleService(ModuleServiceABC, commands.Cog, metaclass=_MetaCogABC):
|
|||||||
settings: ConfigurationModelABC = module.settings_type()
|
settings: ConfigurationModelABC = module.settings_type()
|
||||||
settings.from_dict(json_cfg[id])
|
settings.from_dict(json_cfg[id])
|
||||||
self._config.add_configuration(f'{type(module).__name__}_{id}', settings)
|
self._config.add_configuration(f'{type(module).__name__}_{id}', settings)
|
||||||
self._logger.debug(__name__, f'Added config: {type(module).__name__}_{id}')
|
self._logger.info(__name__, f'Added config: {type(module).__name__}_{id}')
|
||||||
|
|
||||||
modules.append(module)
|
modules.append(module)
|
||||||
|
|
||||||
@ -104,13 +104,17 @@ class ModuleService(ModuleServiceABC, commands.Cog, metaclass=_MetaCogABC):
|
|||||||
self._logger.debug(__name__, f'Stopped {event} modules')
|
self._logger.debug(__name__, f'Stopped {event} modules')
|
||||||
return
|
return
|
||||||
|
|
||||||
func_name = String.convert_to_snake_case(event.__name__.split('ABC')[0])
|
try:
|
||||||
for module in modules:
|
func_name = String.convert_to_snake_case(event.__name__.split('ABC')[0])
|
||||||
func = getattr(module, func_name)
|
for module in modules:
|
||||||
await func(*args)
|
self._logger.trace(__name__, f'Start {type(module)} module')
|
||||||
if not module.success:
|
func = getattr(module, func_name)
|
||||||
self._logger.debug(__name__, f'Stopped propagation for {event} from {type(module)}')
|
await func(*args)
|
||||||
break
|
if not module.success:
|
||||||
|
self._logger.debug(__name__, f'Stopped propagation for {event} from {type(module)}')
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
self._logger.error(__name__, f'Start {event} modules failed', e)
|
||||||
|
|
||||||
self._logger.debug(__name__, f'Stopped {event} modules')
|
self._logger.debug(__name__, f'Stopped {event} modules')
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user