From 6b22d786e399c1df181cac42467a1fcaa1efe66e Mon Sep 17 00:00:00 2001 From: adator85 <> Date: Fri, 15 Aug 2025 15:47:01 +0200 Subject: [PATCH] Adding some comments, editing methods names --- .idea/.gitignore | 8 ++ .idea/DEFENDER.iml | 14 +++ .../inspectionProfiles/profiles_settings.xml | 7 ++ .idea/misc.xml | 7 ++ .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 ++ core/base.py | 101 ++++++++---------- core/classes/channel.py | 93 +++++++++++----- core/classes/protocols/inspircd.py | 9 +- core/classes/protocols/unreal6.py | 21 ++-- core/classes/settings.py | 3 +- core/definition.py | 15 --- core/installation.py | 16 +-- core/irc.py | 19 ++-- core/loader.py | 17 +-- core/utils.py | 42 +++++--- mods/clone/clone_manager.py | 31 ++---- mods/clone/mod_clone.py | 44 ++++---- mods/clone/threads.py | 7 +- mods/command/mod_command.py | 32 +++--- mods/defender/mod_defender.py | 56 +++++++--- mods/defender/threads.py | 2 +- mods/defender/utils.py | 6 +- mods/jsonrpc/mod_jsonrpc.py | 7 +- mods/votekick/mod_votekick.py | 6 +- 25 files changed, 344 insertions(+), 233 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/DEFENDER.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/DEFENDER.iml b/.idea/DEFENDER.iml new file mode 100644 index 0000000..c299fe3 --- /dev/null +++ b/.idea/DEFENDER.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..dd4c951 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..4ab2f6a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..12174db --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/core/base.py b/core/base.py index a39915b..fe4d47d 100644 --- a/core/base.py +++ b/core/base.py @@ -11,40 +11,42 @@ import logging import threading import ipaddress import ast +import requests from pathlib import Path from types import ModuleType -import requests from dataclasses import fields -from typing import Union, TYPE_CHECKING +from typing import Any, Optional, TYPE_CHECKING from base64 import b64decode, b64encode from datetime import datetime, timedelta, timezone from sqlalchemy import create_engine, Engine, Connection, CursorResult from sqlalchemy.sql import text -from core.definition import MConfig if TYPE_CHECKING: - from core.classes.settings import Settings + from core.loader import Loader class Base: - def __init__(self, Config: MConfig, settings: 'Settings') -> None: + def __init__(self, loader: 'Loader') -> None: + + self.Loader = loader + self.Config = loader.Config + self.Settings = loader.Settings + self.Utils = loader.Utils - self.Config = Config # Assigner l'objet de configuration - self.Settings: Settings = settings self.init_log_system() # Demarrer le systeme de log self.check_for_new_version(True) # Verifier si une nouvelle version est disponible # Liste des timers en cours - self.running_timers:list[threading.Timer] = self.Settings.RUNNING_TIMERS + self.running_timers: list[threading.Timer] = self.Settings.RUNNING_TIMERS # Liste des threads en cours - self.running_threads:list[threading.Thread] = self.Settings.RUNNING_THREADS + self.running_threads: list[threading.Thread] = self.Settings.RUNNING_THREADS # Les sockets ouvert self.running_sockets: list[socket.socket] = self.Settings.RUNNING_SOCKETS # Liste des fonctions en attentes - self.periodic_func:dict[object] = self.Settings.PERIODIC_FUNC + self.periodic_func: dict[object] = self.Settings.PERIODIC_FUNC # Création du lock self.lock = self.Settings.LOCK @@ -150,13 +152,6 @@ class Base: return unixtime - def get_datetime(self) -> str: - """ - Retourne une date au format string (24-12-2023 20:50:59) - """ - currentdate = datetime.now().strftime('%d-%m-%Y %H:%M:%S') - return currentdate - def get_all_modules(self) -> list[str]: """Get list of all main modules using this pattern mod_*.py @@ -190,20 +185,20 @@ class Base: importlib.reload(module) self.logs.debug(f'[LOAD_MODULE] Module {module} success') - except Exception: - self.logs.error(f'[LOAD_MODULE] Module {module} failed [!]') + except Exception as err: + self.logs.error(f'[LOAD_MODULE] Module {module} failed [!] - {err}') def create_log(self, log_message: str) -> None: """Enregiste les logs Args: - string (str): Le message a enregistrer + log_message (str): Le message a enregistrer Returns: None: Aucun retour """ sql_insert = f"INSERT INTO {self.Config.TABLE_LOG} (datetime, server_msg) VALUES (:datetime, :server_msg)" - mes_donnees = {'datetime': str(self.get_datetime()),'server_msg': f'{log_message}'} + mes_donnees = {'datetime': str(self.Utils.get_sdatetime()),'server_msg': f'{log_message}'} self.db_execute_query(sql_insert, mes_donnees) return None @@ -247,13 +242,14 @@ class Base: def replace_filter(self, record: logging.LogRecord) -> bool: response = True - filter: list[str] = ['PING', f":{self.Config.SERVICE_PREFIX}auth"] + filters: list[str] = ['PING', + f':{self.Config.SERVICE_PREFIX}auth'] # record.msg = record.getMessage().replace("PING", "[REDACTED]") if self.Settings.CONSOLE: print(record.getMessage()) - for f in filter: + for f in filters: if f in record.getMessage(): response = False @@ -274,10 +270,11 @@ class Base: return None - def log_cmd(self, user_cmd:str, cmd:str) -> None: + def log_cmd(self, user_cmd: str, cmd: str) -> None: """Enregistre les commandes envoyées par les utilisateurs Args: + user_cmd (str): The user who performed the command cmd (str): la commande a enregistrer """ cmd_list = cmd.split() @@ -288,10 +285,10 @@ class Base: cmd = ' '.join(cmd_list) insert_cmd_query = f"INSERT INTO {self.Config.TABLE_COMMAND} (datetime, user, commande) VALUES (:datetime, :user, :commande)" - mes_donnees = {'datetime': self.get_datetime(), 'user': user_cmd, 'commande': cmd} + mes_donnees = {'datetime': self.Utils.get_sdatetime(), 'user': user_cmd, 'commande': cmd} self.db_execute_query(insert_cmd_query, mes_donnees) - return False + return None def db_isModuleExist(self, module_name:str) -> bool: """Teste si un module existe déja dans la base de données @@ -311,22 +308,24 @@ class Base: else: return False - def db_record_module(self, user_cmd:str, module_name:str, isdefault:int = 0) -> None: + def db_record_module(self, user_cmd: str, module_name: str, isdefault: int = 0) -> None: """Enregistre les modules dans la base de données Args: - cmd (str): le module a enregistrer + user_cmd (str): The user who performed the command + module_name (str): The module name + isdefault (int): Is this a default module. Default 0 """ if not self.db_isModuleExist(module_name): self.logs.debug(f"Le module {module_name} n'existe pas alors ont le créer") insert_cmd_query = f"INSERT INTO {self.Config.TABLE_MODULE} (datetime, user, module_name, isdefault) VALUES (:datetime, :user, :module_name, :isdefault)" - mes_donnees = {'datetime': self.get_datetime(), 'user': user_cmd, 'module_name': module_name, 'isdefault': isdefault} + mes_donnees = {'datetime': self.Utils.get_sdatetime(), 'user': user_cmd, 'module_name': module_name, 'isdefault': isdefault} self.db_execute_query(insert_cmd_query, mes_donnees) else: self.logs.debug(f"Le module {module_name} existe déja dans la base de données") - return False + return None def db_update_module(self, user_cmd: str, module_name: str) -> None: """Modifie la date et le user qui a rechargé le module @@ -336,22 +335,22 @@ class Base: module_name (str): le module a rechargé """ update_cmd_query = f"UPDATE {self.Config.TABLE_MODULE} SET datetime = :datetime, user = :user WHERE module_name = :module_name" - mes_donnees = {'datetime': self.get_datetime(), 'user': user_cmd, 'module_name': module_name} + mes_donnees = {'datetime': self.Utils.get_sdatetime(), 'user': user_cmd, 'module_name': module_name} self.db_execute_query(update_cmd_query, mes_donnees) - return False + return None def db_delete_module(self, module_name:str) -> None: """Supprime les modules de la base de données Args: - cmd (str): le module a supprimer + module_name (str): The module name you want to delete """ insert_cmd_query = f"DELETE FROM {self.Config.TABLE_MODULE} WHERE module_name = :module_name" mes_donnees = {'module_name': module_name} self.db_execute_query(insert_cmd_query, mes_donnees) - return False + return None def db_sync_core_config(self, module_name: str, dataclassObj: object) -> bool: """Sync module local parameters with the database @@ -369,7 +368,7 @@ class Base: """ try: response = True - current_date = self.get_datetime() + current_date = self.Utils.get_sdatetime() core_table = self.Config.TABLE_CONFIG # Add local parameters to DB @@ -446,7 +445,7 @@ class Base: isParamExist = result.fetchone() if not isParamExist is None: - mes_donnees = {'datetime': self.get_datetime(), + mes_donnees = {'datetime': self.Utils.get_sdatetime(), 'module_name': module_name, 'param_key': param_key, 'param_value': param_value @@ -471,9 +470,9 @@ class Base: user = self.db_execute_query(f"SELECT id FROM {self.Config.TABLE_ADMIN}") if not user.fetchall(): admin = self.Config.OWNER - password = self.crypt_password(self.Config.PASSWORD) + password = self.Utils.hash_password(self.Config.PASSWORD) - mes_donnees = {'createdOn': self.get_datetime(), + mes_donnees = {'createdOn': self.Utils.get_sdatetime(), 'user': admin, 'password': password, 'hostname': '*', @@ -500,8 +499,11 @@ class Base: self.logs.debug(f"-- Timer ID : {str(t.ident)} | Running Threads : {len(threading.enumerate())}") + return None + except AssertionError as ae: self.logs.error(f'Assertion Error -> {ae}') + return None def create_thread(self, func:object, func_args: tuple = (), run_once:bool = False, daemon: bool = True) -> None: """Create a new thread and store it into running_threads variable @@ -737,19 +739,6 @@ class Base: except AttributeError as ae: self.logs.error(f"Attribute Error : {ae}") - def crypt_password(self, password:str) -> str: - """Retourne un mot de passe chiffré en MD5 - - Args: - password (str): Le password en clair - - Returns: - str: Le password en MD5 - """ - md5_password = hashlib.md5(password.encode()).hexdigest() - - return md5_password - def int_if_possible(self, value): """Convertit la valeur reçue en entier, si possible. Sinon elle retourne la valeur initiale. @@ -768,14 +757,14 @@ class Base: except TypeError: return value - def convert_to_int(self, value: any) -> Union[int, None]: + def convert_to_int(self, value: Any) -> Optional[int]: """Convert a value to int Args: value (any): Value to convert to int if possible Returns: - Union[int, None]: Return the int value or None if not possible + int: Return the int value or None if not possible """ try: response = int(value) @@ -816,7 +805,7 @@ class Base: self.logs.error(f'General Error: {err}') return False - def decode_ip(self, ip_b64encoded: str) -> Union[str, None]: + def decode_ip(self, ip_b64encoded: str) -> Optional[str]: binary_ip = b64decode(ip_b64encoded) try: @@ -827,7 +816,7 @@ class Base: self.logs.critical(f'This remote ip is not valid : {ve}') return None - def encode_ip(self, remote_ip_address: str) -> Union[str, None]: + def encode_ip(self, remote_ip_address: str) -> Optional[str]: binary_ip = socket.inet_aton(remote_ip_address) try: @@ -890,7 +879,7 @@ class Base: self.logs.debug(f'Method to execute : {str(self.periodic_func)}') return None - def clean_uid(self, uid:str) -> Union[str, None]: + def clean_uid(self, uid:str) -> Optional[str]: """Clean UID by removing @ / % / + / ~ / * / : Args: diff --git a/core/classes/channel.py b/core/classes/channel.py index 6d4380f..f628394 100644 --- a/core/classes/channel.py +++ b/core/classes/channel.py @@ -3,7 +3,7 @@ from typing import Any, Optional, Literal, TYPE_CHECKING if TYPE_CHECKING: from core.definition import MChannel - from core.base import Base + from core.loader import Loader class Channel: @@ -11,10 +11,11 @@ class Channel: """List that contains all the Channels objects (ChannelModel) """ - def __init__(self, base: 'Base') -> None: + def __init__(self, loader: 'Loader') -> None: - self.Logs = base.logs - self.Base = base + self.Logs = loader.Base.logs + self.Base = loader.Base + self.Utils = loader.Utils return None @@ -22,7 +23,7 @@ class Channel: """This method will insert a new channel and if the channel exist it will update the user list (uids) Args: - newChan (ChannelModel): The channel model object + new_channel (MChannel): The channel model object Returns: bool: True if new channel, False if channel exist (However UID could be updated) @@ -30,7 +31,7 @@ class Channel: result = False exist = False - if not self.Is_Channel(new_channel.name): + if not self.is_valid_channel(new_channel.name): self.Logs.error(f"The channel {new_channel.name} is not valid, channel must start with #") return False @@ -64,8 +65,16 @@ class Channel: return result def delete(self, channel_name: str) -> bool: + """Delete channel from the UID_CHANNEL_DB - chan_obj = self.get_Channel(channel_name) + Args: + channel_name (str): The Channel name + + Returns: + bool: True if it was deleted + """ + + chan_obj = self.get_channel(channel_name) if chan_obj is None: return False @@ -75,10 +84,19 @@ class Channel: return True def delete_user_from_channel(self, channel_name: str, uid:str) -> bool: + """Delete a user from a channel + + Args: + channel_name (str): The channel name + uid (str): The Client UID + + Returns: + bool: True if the client has been deleted from the channel + """ try: result = False - chan_obj = self.get_Channel(channel_name.lower()) + chan_obj = self.get_channel(channel_name.lower()) if chan_obj is None: return result @@ -95,6 +113,14 @@ class Channel: self.Logs.error(f'{ve}') def delete_user_from_all_channel(self, uid:str) -> bool: + """Delete a client from all channels + + Args: + uid (str): The client UID + + Returns: + bool: True if the client has been deleted from all channels + """ try: result = False @@ -111,14 +137,22 @@ class Channel: self.Logs.error(f'{ve}') def add_user_to_a_channel(self, channel_name: str, uid: str) -> bool: + """Add a client to a channel + + Args: + channel_name (str): The channel name + uid (str): The client UID + + Returns: + bool: True is the clien has been added + """ try: - result = False - chan_obj = self.get_Channel(channel_name) - self.Logs.debug(f"** {__name__}") + chan_obj = self.get_channel(channel_name) if chan_obj is None: - result = self.insert(MChannel(channel_name, uids=[uid])) - return result + # Create a new channel if the channel don't exist + self.Logs.debug(f"New channel will be created ({channel_name} - {uid})") + return self.insert(MChannel(channel_name, uids=[uid])) chan_obj.uids.append(uid) del_duplicates = list(set(chan_obj.uids)) @@ -127,18 +161,19 @@ class Channel: return True except Exception as err: self.Logs.error(f'{err}') + return False def is_user_present_in_channel(self, channel_name: str, uid: str) -> bool: """Check if a user is present in the channel Args: - channel_name (str): The channel to check - uid (str): The UID + channel_name (str): The channel name to check + uid (str): The client UID Returns: bool: True if the user is present in the channel """ - chan = self.get_Channel(channel_name=channel_name) + chan = self.get_channel(channel_name=channel_name) if chan is None: return False @@ -150,7 +185,7 @@ class Channel: return False def clean_channel(self) -> None: - """Remove Channels if empty + """If channel doesn't contain any client this method will remove the channel """ try: for record in self.UID_CHANNEL_DB: @@ -161,25 +196,33 @@ class Channel: except Exception as err: self.Logs.error(f'{err}') - def get_Channel(self, channel_name: str) -> Optional['MChannel']: + def get_channel(self, channel_name: str) -> Optional['MChannel']: + """Get the channel object + + Args: + channel_name (str): The Channel name + + Returns: + MChannel: The channel object model if exist else None + """ for record in self.UID_CHANNEL_DB: - if record.name == channel_name: + if record.name.lower() == channel_name.lower(): return record return None - def get_channel_asdict(self, chan_name: str) -> Optional[dict[str, Any]]: + def get_channel_asdict(self, channel_name: str) -> Optional[dict[str, Any]]: - channel_obj: Optional['MChannel'] = self.get_Channel(chan_name) + channel_obj: Optional['MChannel'] = self.get_channel(channel_name) if channel_obj is None: return None return channel_obj.to_dict() - def Is_Channel(self, channel_to_check: str) -> bool: - """Check if the string has the # caractere and return True if this is a channel + def is_valid_channel(self, channel_to_check: str) -> bool: + """Check if the string has the # caractere and return True if this is a valid channel Args: channel_to_check (str): The string to test if it is a channel or not @@ -216,7 +259,7 @@ class Channel: bool: True if action done """ try: - channel_name = channel_name.lower() if self.Is_Channel(channel_name) else None + channel_name = channel_name.lower() if self.is_valid_channel(channel_name) else None core_table = self.Base.Config.TABLE_CHANNEL if not channel_name: @@ -231,7 +274,7 @@ class Channel: is_channel_exist = response.fetchone() if is_channel_exist is None: - mes_donnees = {'datetime': self.Base.get_datetime(), 'channel_name': channel_name, 'module_name': module_name} + mes_donnees = {'datetime': self.Utils.get_sdatetime(), 'channel_name': channel_name, 'module_name': module_name} insert = self.Base.db_execute_query(f"INSERT INTO {core_table} (datetime, channel_name, module_name) VALUES (:datetime, :channel_name, :module_name)", mes_donnees) if insert.rowcount: self.Logs.debug(f'New channel added: channel={channel_name} / module_name={module_name}') diff --git a/core/classes/protocols/inspircd.py b/core/classes/protocols/inspircd.py index c33eaf6..81bc9c8 100644 --- a/core/classes/protocols/inspircd.py +++ b/core/classes/protocols/inspircd.py @@ -14,6 +14,7 @@ class Inspircd: self.__Irc = ircInstance self.__Config = ircInstance.Config self.__Base = ircInstance.Base + self.__Utils = ircInstance.Loader.Utils self.__Base.logs.info(f"** Loading protocol [{__name__}]") @@ -169,7 +170,7 @@ class Inspircd: def sjoin(self, channel: str) -> None: - if not self.__Irc.Channel.Is_Channel(channel): + if not self.__Irc.Channel.is_valid_channel(channel): self.__Base.logs.error(f"The channel [{channel}] is not valid") return None @@ -259,7 +260,7 @@ class Inspircd: if userObj is None: return None - if not self.__Irc.Channel.Is_Channel(channel): + if not self.__Irc.Channel.is_valid_channel(channel): self.__Base.logs.error(f"The channel [{channel}] is not valid") return None @@ -284,7 +285,7 @@ class Inspircd: self.__Base.logs.error(f"The user [{uidornickname}] is not valid") return None - if not self.__Irc.Channel.Is_Channel(channel): + if not self.__Irc.Channel.is_valid_channel(channel): self.__Base.logs.error(f"The channel [{channel}] is not valid") return None @@ -600,7 +601,7 @@ class Inspircd: nickname = self.__Irc.User.get_nickname(self.__Base.clean_uid(serverMsg[1])) dnickname = self.__Config.SERVICE_NICKNAME arg = serverMsg[4].replace(':', '') - current_datetime = self.__Base.get_datetime() + current_datetime = self.__Utils.get_sdatetime() if nickname is None: return None diff --git a/core/classes/protocols/unreal6.py b/core/classes/protocols/unreal6.py index 6a47350..f6166e5 100644 --- a/core/classes/protocols/unreal6.py +++ b/core/classes/protocols/unreal6.py @@ -16,6 +16,7 @@ class Unrealircd6: self.__Config = ircInstance.Config self.__Base = ircInstance.Base self.__Settings = ircInstance.Base.Settings + self.__Utils = ircInstance.Loader.Utils self.known_protocol: set[str] = {'SJOIN', 'UID', 'MD', 'QUIT', 'SQUIT', 'EOS', 'PRIVMSG', 'MODE', 'UMODE2', @@ -242,7 +243,7 @@ class Unrealircd6: Args: channel (str): Channel to join """ - if not self.__Irc.Channel.Is_Channel(channel): + if not self.__Irc.Channel.is_valid_channel(channel): self.__Base.logs.error(f"The channel [{channel}] is not valid") return None @@ -264,7 +265,7 @@ class Unrealircd6: try: userObj = self.__Irc.User.get_User(uidornickname=nick_to_sapart) - chanObj = self.__Irc.Channel.get_Channel(channel_name) + chanObj = self.__Irc.Channel.get_channel(channel_name) service_uid = self.__Config.SERVICE_ID if userObj is None or chanObj is None: @@ -288,7 +289,7 @@ class Unrealircd6: try: userObj = self.__Irc.User.get_User(uidornickname=nick_to_sajoin) - chanObj = self.__Irc.Channel.get_Channel(channel_name) + chanObj = self.__Irc.Channel.get_channel(channel_name) service_uid = self.__Config.SERVICE_ID if userObj is None: @@ -297,7 +298,7 @@ class Unrealircd6: if chanObj is None: # Channel not exist - if not self.__Irc.Channel.Is_Channel(channel_name): + if not self.__Irc.Channel.is_valid_channel(channel_name): # Incorrect channel: leave return None @@ -412,7 +413,7 @@ class Unrealircd6: if userObj is None: return None - if not self.__Irc.Channel.Is_Channel(channel): + if not self.__Irc.Channel.is_valid_channel(channel): self.__Base.logs.error(f"The channel [{channel}] is not valid") return None @@ -452,7 +453,7 @@ class Unrealircd6: self.__Base.logs.error(f"The user [{uidornickname}] is not valid") return None - if not self.__Irc.Channel.Is_Channel(channel): + if not self.__Irc.Channel.is_valid_channel(channel): self.__Base.logs.error(f"The channel [{channel}] is not valid") return None @@ -464,7 +465,7 @@ class Unrealircd6: def send_mode_chan(self, channel_name: str, channel_mode: str) -> None: - channel = self.__Irc.Channel.Is_Channel(channel_name) + channel = self.__Irc.Channel.is_valid_channel(channel_name) if not channel: self.__Base.logs.error(f'The channel [{channel_name}] is not correct') return None @@ -939,7 +940,7 @@ class Unrealircd6: cmd_to_send = convert_to_string.replace(':','') self.__Base.log_cmd(user_trigger, cmd_to_send) - fromchannel = str(cmd[2]).lower() if self.__Irc.Channel.Is_Channel(cmd[2]) else None + fromchannel = str(cmd[2]).lower() if self.__Irc.Channel.is_valid_channel(cmd[2]) else None self.__Irc.hcmds(user_trigger, fromchannel, arg, cmd) if cmd[2] == self.__Config.SERVICE_ID: @@ -975,7 +976,7 @@ class Unrealircd6: fromchannel = None if len(arg) >= 2: - fromchannel = str(arg[1]).lower() if self.__Irc.Channel.Is_Channel(arg[1]) else None + fromchannel = str(arg[1]).lower() if self.__Irc.Channel.is_valid_channel(arg[1]) else None self.__Irc.hcmds(user_trigger, fromchannel, arg, cmd) return None @@ -1039,7 +1040,7 @@ class Unrealircd6: nickname = self.__Irc.User.get_nickname(self.__Base.clean_uid(serverMsg[1])) dnickname = self.__Config.SERVICE_NICKNAME arg = serverMsg[4].replace(':', '') - current_datetime = self.__Base.get_datetime() + current_datetime = self.__Utils.get_sdatetime() if nickname is None: return None diff --git a/core/classes/settings.py b/core/classes/settings.py index 46350df..c37a37b 100644 --- a/core/classes/settings.py +++ b/core/classes/settings.py @@ -26,7 +26,8 @@ class Settings: def set_cache(self, key: str, value_to_cache: Any): """When you want to store a variable - Ex. + + Ex. ```python set_cache('MY_KEY', {'key1': 'value1', 'key2', 'value2'}) ``` diff --git a/core/definition.py b/core/definition.py index af8f262..0398c50 100644 --- a/core/definition.py +++ b/core/definition.py @@ -320,21 +320,6 @@ class MConfig(MainModel): self.SERVEUR_CHARSET: list = ["utf-8", "iso-8859-1"] """0: utf-8 | 1: iso-8859-1""" -@dataclass -class MClone(MainModel): - """Model Clone""" - connected: bool = False - uid: str = None - nickname: str = None - username: str = None - realname: str = None - channels: list = field(default_factory=list) - vhost: str = None - hostname: str = 'localhost' - umodes: str = None - remote_ip: str = '127.0.0.1' - group: str = 'Default' - @dataclass class MCommand(MainModel): module_name: str = None diff --git a/core/installation.py b/core/installation.py index c7ae319..f0c14b2 100644 --- a/core/installation.py +++ b/core/installation.py @@ -261,21 +261,21 @@ class Install: if not do_install: return None - print("===> Vider le cache de pip") + print("===> Clean pip cache") self.run_subprocess([self.config.venv_pip_executable, 'cache', 'purge']) - print("===> Verifier si pip est a jour") + print("===> Check if pip is up to date") self.run_subprocess([self.config.venv_python_executable, '-m', 'pip', 'install', '--upgrade', 'pip']) if not self.check_package('greenlet'): self.run_subprocess([self.config.venv_pip_executable, 'install', '--only-binary', ':all:', 'greenlet']) - print('====> Module Greenlet installé') + print('====> Greenlet installed') for module in self.config.venv_cmd_requirements: if not self.check_package(module): print("### Trying to install missing python packages ###") self.run_subprocess([self.config.venv_pip_executable, 'install', module]) - print(f"====> Module {module} installé") + print(f"====> Module {module} installed!") else: print(f"==> {module} already installed") @@ -307,8 +307,8 @@ WantedBy=default.target with open(full_service_file_path, 'w+') as servicefile: servicefile.write(contain) servicefile.close() - print(f'Service file generated with current configuration') - print(f'Running Defender IRC Service ...') + print('Service file generated with current configuration') + print('Running IRC Service ...') self.run_subprocess(self.config.service_cmd_daemon_reload) self.run_subprocess(self.config.service_cmd_executable) @@ -316,8 +316,8 @@ WantedBy=default.target with open(full_service_file_path, 'w+') as servicefile: servicefile.write(contain) servicefile.close() - print(f'Service file generated with current configuration') - print(f'Running Defender IRC Service ...') + print('Service file generated with current configuration') + print('Running IRC Service ...') self.run_subprocess(self.config.service_cmd_daemon_reload) self.run_subprocess(self.config.service_cmd_executable) diff --git a/core/irc.py b/core/irc.py index df33bcf..f8b88fa 100644 --- a/core/irc.py +++ b/core/irc.py @@ -31,6 +31,9 @@ class Irc: # Load the configuration self.Config = self.Loader.Config + # Load Main utils functions + self.Utils = self.Loader.Utils + # Date et heure de la premiere connexion de Defender self.defender_connexion_datetime = self.Config.DEFENDER_CONNEXION_DATETIME @@ -802,7 +805,7 @@ class Irc: hostname = get_user.hostname vhost = get_user.vhost - spassword = self.Base.crypt_password(password) + spassword = self.Loader.Utils.hash_password(password) mes_donnees = {'admin': nickname} query_search_user = f"SELECT id FROM {self.Config.TABLE_ADMIN} WHERE user=:admin" @@ -811,7 +814,7 @@ class Irc: # On verifie si le user exist dans la base if not exist_user: - mes_donnees = {'datetime': self.Base.get_datetime(), 'user': nickname, 'password': spassword, 'hostname': hostname, 'vhost': vhost, 'level': level} + mes_donnees = {'datetime': self.Utils.get_sdatetime(), 'user': nickname, 'password': spassword, 'hostname': hostname, 'vhost': vhost, 'level': level} self.Base.db_execute_query(f'''INSERT INTO {self.Config.TABLE_ADMIN} (createdOn, user, password, hostname, vhost, level) VALUES (:datetime, :user, :password, :hostname, :vhost, :level) @@ -833,7 +836,7 @@ class Irc: log_msg (str): the message to log """ try: - mes_donnees = {'datetime': self.Base.get_datetime(), 'server_msg': log_msg} + mes_donnees = {'datetime': self.Utils.get_sdatetime(), 'server_msg': log_msg} self.Base.db_execute_query(f'INSERT INTO {self.Config.TABLE_LOG} (datetime, server_msg) VALUES (:datetime, :server_msg)', mes_donnees) return None @@ -1151,7 +1154,7 @@ class Irc: return False if not user_to_log is None: - mes_donnees = {'user': user_to_log, 'password': self.Base.crypt_password(password)} + mes_donnees = {'user': user_to_log, 'password': self.Loader.Utils.hash_password(password)} query = f"SELECT id, level FROM {self.Config.TABLE_ADMIN} WHERE user = :user AND password = :password" result = self.Base.db_execute_query(query, mes_donnees) user_from_db = result.fetchone() @@ -1204,7 +1207,7 @@ class Irc: return None user_to_edit = cmd[1] - user_password = self.Base.crypt_password(cmd[2]) + user_password = self.Loader.Utils.hash_password(cmd[2]) get_admin = self.Admin.get_Admin(fromuser) if get_admin is None: @@ -1343,9 +1346,9 @@ class Irc: # If the account doesn't exist then insert into database data_to_record = { - 'createdOn': self.Base.get_datetime(), 'account': fromuser, + 'createdOn': self.Utils.get_sdatetime(), 'account': fromuser, 'nickname': user_obj.nickname, 'hostname': user_obj.hostname, 'vhost': user_obj.vhost, 'realname': user_obj.realname, 'email': email, - 'password': self.Base.crypt_password(password=password), 'level': 0 + 'password': self.Loader.Utils.hash_password(password=password), 'level': 0 } insert_to_db = self.Base.db_execute_query(f""" @@ -1380,7 +1383,7 @@ class Irc: return None account = str(cmd[1]) # account - encrypted_password = self.Base.crypt_password(cmd[2]) + encrypted_password = self.Loader.Utils.hash_password(cmd[2]) user_obj = self.User.get_User(fromuser) client_obj = self.Client.get_Client(user_obj.uid) diff --git a/core/loader.py b/core/loader.py index d9ebdf5..b45183f 100644 --- a/core/loader.py +++ b/core/loader.py @@ -1,25 +1,28 @@ from core.classes import user, admin, client, channel, reputation, settings, commands import core.definition as df -import core.base as baseModule -import core.classes.config as confModule +import core.utils as utils +import core.base as base_module +import core.classes.config as conf_module class Loader: def __init__(self): - # Load Modules - self.Definition: df = df + # Load Main Modules + self.Definition: df = df - self.ConfModule: confModule = confModule + self.ConfModule: conf_module = conf_module - self.BaseModule: baseModule = baseModule + self.BaseModule: base_module = base_module + + self.Utils: utils = utils # Load Classes self.Settings: settings.Settings = settings.Settings() self.Config: df.MConfig = self.ConfModule.Configuration().ConfigObject - self.Base: baseModule.Base = self.BaseModule.Base(self.Config, self.Settings) + self.Base: base_module.Base = self.BaseModule.Base(self) self.User: user.User = user.User(self.Base) diff --git a/core/utils.py b/core/utils.py index 10bb365..93188b1 100644 --- a/core/utils.py +++ b/core/utils.py @@ -1,28 +1,24 @@ -import sys -import importlib -from types import ModuleType -from typing import Literal, Union +from pathlib import Path +from typing import Literal, Optional, Any from datetime import datetime from time import time from random import choice from hashlib import md5, sha3_512 -def convert_to_int(value: any) -> Union[int, None]: +def convert_to_int(value: Any) -> Optional[int]: """Convert a value to int Args: - value (any): Value to convert to int if possible + value (Any): Value to convert to int if possible Returns: - Union[int, None]: Return the int value or None if not possible + int: Return the int value or None if not possible """ try: value_to_int = int(value) return value_to_int except ValueError: return None - except Exception: - return None def get_unixtime() -> int: """Cette fonction retourne un UNIXTIME de type 12365456 @@ -32,7 +28,7 @@ def get_unixtime() -> int: """ return int(time()) -def get_datetime() -> str: +def get_sdatetime() -> str: """Retourne une date au format string (24-12-2023 20:50:59) Returns: @@ -41,6 +37,12 @@ def get_datetime() -> str: currentdate = datetime.now().strftime('%d-%m-%Y %H:%M:%S') return currentdate +def get_datetime() -> datetime: + """ + Return the current datetime in a datetime object + """ + return datetime.now() + def generate_random_string(lenght: int) -> str: """Retourn une chaîne aléatoire en fonction de la longueur spécifiée. @@ -52,15 +54,15 @@ def generate_random_string(lenght: int) -> str: return randomize -def hash(password: str, algorithm: Literal["md5, sha3_512"] = 'md5') -> str: - """Retourne un mot de passe chiffré en fonction de l'algorithme utilisé +def hash_password(password: str, algorithm: Literal["md5, sha3_512"] = 'md5') -> str: + """Return the crypted password following the selected algorithm Args: - password (str): Le password en clair - algorithm (str): L'algorithm a utilisé + password (str): The plain text password + algorithm (str): The algorithm to use Returns: - str: Le password haché + str: The crypted password, default md5 """ match algorithm: @@ -75,3 +77,13 @@ def hash(password: str, algorithm: Literal["md5, sha3_512"] = 'md5') -> str: case _: password = md5(password.encode()).hexdigest() return password + +def get_all_modules() -> list[str]: + """Get list of all main modules + using this pattern mod_*.py + + Returns: + list[str]: List of module names. + """ + base_path = Path('mods') + return [file.name.replace('.py', '') for file in base_path.rglob('mod_*.py')] \ No newline at end of file diff --git a/mods/clone/clone_manager.py b/mods/clone/clone_manager.py index 9b53a69..486795b 100644 --- a/mods/clone/clone_manager.py +++ b/mods/clone/clone_manager.py @@ -1,5 +1,5 @@ from typing import Optional, TYPE_CHECKING -from core.definition import MClone +from mods.clone.schemas import MClone if TYPE_CHECKING: from mods.clone.mod_clone import Clone @@ -16,33 +16,24 @@ class CloneManager: """Create new Clone object Args: - newCloneObject (CloneModel): New CloneModel object + new_clone_object (MClone): New Clone object Returns: bool: True if inserted """ - result = False - exist = False + if new_clone_object is None: + self.Logs.debug('New Clone object must not be None') + return False for record in self.UID_CLONE_DB: - if record.nickname == new_clone_object.nickname: + if record.nickname == new_clone_object.nickname or record.uid == new_clone_object.uid: # If the user exist then return False and do not go further - exist = True - self.Logs.warning(f'Nickname {record.nickname} already exist') - return result - if record.uid == new_clone_object.uid: - exist = True - self.Logs.warning(f'UID: {record.uid} already exist') - return result + self.Logs.debug(f'Nickname/UID {record.nickname}/{record.uid} already exist') + return False - if not exist: - self.UID_CLONE_DB.append(new_clone_object) - result = True - - if not result: - self.Logs.critical(f'The Clone Object was not inserted {new_clone_object}') - - return result + self.UID_CLONE_DB.append(new_clone_object) + self.Logs.debug(f'New Clone object created: {new_clone_object}') + return True def delete(self, uidornickname: str) -> bool: """Delete the Clone Object starting from the nickname or the UID diff --git a/mods/clone/mod_clone.py b/mods/clone/mod_clone.py index d87706e..40e2ff2 100644 --- a/mods/clone/mod_clone.py +++ b/mods/clone/mod_clone.py @@ -1,6 +1,4 @@ -import time, logging -from typing import TYPE_CHECKING, Optional -from faker import Faker +from typing import TYPE_CHECKING, Optional, Any import mods.clone.utils as utils import mods.clone.threads as thds import mods.clone.schemas as schemas @@ -8,40 +6,41 @@ from mods.clone.clone_manager import CloneManager if TYPE_CHECKING: from core.irc import Irc + from faker import Faker -class Clone(): +class Clone: - def __init__(self, ircInstance: 'Irc') -> None: + def __init__(self, irc_instance: 'Irc') -> None: # Module name (Mandatory) self.module_name = 'mod_' + str(self.__class__.__name__).lower() # Add Irc Object to the module (Mandatory) - self.Irc = ircInstance + self.Irc = irc_instance # Add Irc Protocol Object to the module (Mandatory) - self.Protocol = ircInstance.Protocol + self.Protocol = irc_instance.Protocol # Add Global Configuration to the module (Mandatory) - self.Config = ircInstance.Config + self.Config = irc_instance.Config # Add Base object to the module (Mandatory) - self.Base = ircInstance.Base + self.Base = irc_instance.Base # Add logs object to the module (Mandatory) - self.Logs = ircInstance.Base.logs + self.Logs = irc_instance.Base.logs # Add User object to the module (Mandatory) - self.User = ircInstance.User + self.User = irc_instance.User # Add Channel object to the module (Mandatory) - self.Channel = ircInstance.Channel + self.Channel = irc_instance.Channel # Add global definitions - self.Definition = ircInstance.Loader.Definition + self.Definition = irc_instance.Loader.Definition # The Global Settings - self.Settings = ircInstance.Loader.Settings + self.Settings = irc_instance.Loader.Settings self.Schemas = schemas @@ -88,8 +87,6 @@ class Clone(): def __create_tables(self) -> None: """Methode qui va créer la base de donnée si elle n'existe pas. Une Session unique pour cette classe sera crée, qui sera utilisé dans cette classe / module - Args: - database_name (str): Nom de la base de données ( pas d'espace dans le nom ) Returns: None: Aucun retour n'es attendu @@ -136,15 +133,15 @@ class Clone(): return None - def cmd(self, data:list): + def cmd(self, data:list) -> None: try: if not data or len(data) < 2: - return + return None cmd = data.copy() if isinstance(data, list) else list(data).copy() index, command = self.Irc.Protocol.get_ircd_protocol_poisition(cmd) if index == -1: - return + return None match command: @@ -152,15 +149,16 @@ class Clone(): return self.Utils.handle_on_privmsg(self, cmd) case 'QUIT': - return + return None case _: - return + return None except Exception as err: self.Logs.error(f'General Error: {err}', exc_info=True) + return None - def hcmds(self, user: str, channel: any, cmd: list, fullcmd: list = []) -> None: + def hcmds(self, user: str, channel: Any, cmd: list, fullcmd: list = []) -> None: try: @@ -310,7 +308,7 @@ class Clone(): try: # clone say clone_nickname #channel message clone_name = str(cmd[2]) - clone_channel = str(cmd[3]) if self.Channel.Is_Channel(str(cmd[3])) else None + clone_channel = str(cmd[3]) if self.Channel.is_valid_channel(str(cmd[3])) else None final_message = ' '.join(cmd[4:]) diff --git a/mods/clone/threads.py b/mods/clone/threads.py index 60e40e4..c8c216a 100644 --- a/mods/clone/threads.py +++ b/mods/clone/threads.py @@ -12,7 +12,12 @@ def thread_connect_clones(uplink: 'Clone', ): for i in range(0, number_of_clones): - uplink.Utils.create_new_clone(uplink, uplink.Faker, group=group, auto_remote_ip=auto_remote_ip) + uplink.Utils.create_new_clone( + uplink=uplink, + faker_instance=uplink.Faker, + group=group, + auto_remote_ip=auto_remote_ip + ) for clone in uplink.Clone.UID_CLONE_DB: diff --git a/mods/command/mod_command.py b/mods/command/mod_command.py index f3b8874..3f5d9d3 100644 --- a/mods/command/mod_command.py +++ b/mods/command/mod_command.py @@ -1,4 +1,4 @@ -from typing import Union, TYPE_CHECKING +from typing import Optional, TYPE_CHECKING from dataclasses import dataclass if TYPE_CHECKING: @@ -271,7 +271,7 @@ class Command: user_uid = self.User.clean_uid(cmd[5]) userObj: MUser = self.User.get_User(user_uid) - channel_name = cmd[4] if self.Channel.Is_Channel(cmd[4]) else None + channel_name = cmd[4] if self.Channel.is_valid_channel(cmd[4]) else None client_obj = self.Client.get_Client(user_uid) nickname = userObj.nickname if userObj is not None else None @@ -296,7 +296,7 @@ class Command: except Exception as err: self.Logs.error(f"General Error: {err}") - def hcmds(self, uidornickname: str, channel_name: Union[str, None], cmd: list, fullcmd: list = []) -> None: + def hcmds(self, uidornickname: str, channel_name: Optional[str], cmd: list, fullcmd: list = []) -> None: command = str(cmd[0]).lower() dnickname = self.Config.SERVICE_NICKNAME @@ -324,7 +324,7 @@ class Command: # userObj: MUser = self.User.get_User(str(cmd[2])) nickname = str(cmd[2]) mode = str(cmd[3]) - chan: str = str(cmd[4]).lower() if self.Channel.Is_Channel(cmd[4]) else None + chan: str = str(cmd[4]).lower() if self.Channel.is_valid_channel(cmd[4]) else None sign = mode[0] if mode.startswith( ('+', '-')) else None clean_mode = mode[1:] if len(mode) > 0 else None @@ -422,7 +422,7 @@ class Command: case 'voiceall': try: - chan_info = self.Channel.get_Channel(fromchannel) + chan_info = self.Channel.get_channel(fromchannel) set_mode = 'v' mode:str = '' users:str = '' @@ -444,7 +444,7 @@ class Command: case 'opall': try: - chan_info = self.Channel.get_Channel(fromchannel) + chan_info = self.Channel.get_channel(fromchannel) set_mode = 'o' mode:str = '' users:str = '' @@ -739,7 +739,7 @@ class Command: case 'ban': # .ban #channel nickname try: - sentchannel = str(cmd[1]) if self.Channel.Is_Channel(cmd[1]) else None + sentchannel = str(cmd[1]) if self.Channel.is_valid_channel(cmd[1]) else None if sentchannel is None: self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME]") return False @@ -757,7 +757,7 @@ class Command: case 'unban': # .unban #channel nickname try: - sentchannel = str(cmd[1]) if self.Channel.Is_Channel(cmd[1]) else None + sentchannel = str(cmd[1]) if self.Channel.is_valid_channel(cmd[1]) else None if sentchannel is None: self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} ban [#SALON] [NICKNAME]") return False @@ -775,7 +775,7 @@ class Command: case 'kick': # .kick #channel nickname reason try: - sentchannel = str(cmd[1]) if self.Channel.Is_Channel(cmd[1]) else None + sentchannel = str(cmd[1]) if self.Channel.is_valid_channel(cmd[1]) else None if sentchannel is None: self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} ban [#SALON] [NICKNAME]") return False @@ -794,7 +794,7 @@ class Command: case 'kickban': # .kickban #channel nickname reason try: - sentchannel = str(cmd[1]) if self.Channel.Is_Channel(cmd[1]) else None + sentchannel = str(cmd[1]) if self.Channel.is_valid_channel(cmd[1]) else None if sentchannel is None: self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} ban [#SALON] [NICKNAME]") return False @@ -814,7 +814,7 @@ class Command: case 'join' | 'assign': try: - sent_channel = str(cmd[1]) if self.Channel.Is_Channel(cmd[1]) else None + sent_channel = str(cmd[1]) if self.Channel.is_valid_channel(cmd[1]) else None if sent_channel is None: self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"{self.Config.SERVICE_PREFIX}JOIN #channel") return False @@ -832,7 +832,7 @@ class Command: case 'part' | 'unassign': try: - sent_channel = str(cmd[1]) if self.Channel.Is_Channel(cmd[1]) else None + sent_channel = str(cmd[1]) if self.Channel.is_valid_channel(cmd[1]) else None if sent_channel is None: self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"{self.Config.SERVICE_PREFIX}PART #channel") return False @@ -859,7 +859,7 @@ class Command: return None chan = str(cmd[1]) - if not self.Channel.Is_Channel(chan): + if not self.Channel.is_valid_channel(chan): self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="The channel must start with #") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} TOPIC #channel THE_TOPIC_MESSAGE") return None @@ -959,7 +959,7 @@ class Command: chan = str(cmd[1]) - if not self.Channel.Is_Channel(chan): + if not self.Channel.is_valid_channel(chan): self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="The channel must start with #") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} #channel") return None @@ -980,7 +980,7 @@ class Command: nickname = str(cmd[1]) chan = str(cmd[2]) - if not self.Channel.Is_Channel(chan): + if not self.Channel.is_valid_channel(chan): self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="The channel must start with #") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME #CHANNEL") return None @@ -1051,7 +1051,7 @@ class Command: if len(cmd) == 2: channel_mode = cmd[1] - if self.Channel.Is_Channel(fromchannel): + if self.Channel.is_valid_channel(fromchannel): self.Protocol.send2socket(f":{dnickname} MODE {fromchannel} {channel_mode}") else: self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : Channel [{fromchannel}] is not correct should start with #") diff --git a/mods/defender/mod_defender.py b/mods/defender/mod_defender.py index 250864f..dae03a1 100644 --- a/mods/defender/mod_defender.py +++ b/mods/defender/mod_defender.py @@ -7,39 +7,42 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: from core.irc import Irc -class Defender(): +class Defender: - def __init__(self, ircInstance: 'Irc') -> None: + def __init__(self, irc_instance: 'Irc') -> None: # Module name (Mandatory) self.module_name = 'mod_' + str(self.__class__.__name__).lower() # Add Irc Object to the module (Mandatory) - self.Irc = ircInstance + self.Irc = irc_instance # Add Loader Object to the module (Mandatory) - self.Loader = ircInstance.Loader + self.Loader = irc_instance.Loader # Add server protocol Object to the module (Mandatory) - self.Protocol = ircInstance.Protocol + self.Protocol = irc_instance.Protocol # Add Global Configuration to the module (Mandatory) - self.Config = ircInstance.Config + self.Config = irc_instance.Config # Add Base object to the module (Mandatory) - self.Base = ircInstance.Base + self.Base = irc_instance.Base # Add logs object to the module (Mandatory) - self.Logs = ircInstance.Base.logs + self.Logs = irc_instance.Base.logs # Add User object to the module (Mandatory) - self.User = ircInstance.User + self.User = irc_instance.User # Add Channel object to the module (Mandatory) - self.Channel = ircInstance.Channel + self.Channel = irc_instance.Channel + + # Add Settings object to save objects when reloading modules (Mandatory) + self.Settings = irc_instance.Settings # Add Reputation object to the module (Optional) - self.Reputation = ircInstance.Reputation + self.Reputation = irc_instance.Reputation # Add module schemas self.Schemas = schemas @@ -158,10 +161,39 @@ class Defender(): self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value) + def __onload(self): + + abuseipdb = self.Settings.get_cache('ABUSEIPDB') + freeipapi = self.Settings.get_cache('FREEIPAPI') + cloudfilt = self.Settings.get_cache('CLOUDFILT') + psutils = self.Settings.get_cache('PSUTIL') + localscan = self.Settings.get_cache('LOCALSCAN') + + if abuseipdb: + self.Schemas.DB_ABUSEIPDB_USERS = abuseipdb + + if freeipapi: + self.Schemas.DB_FREEIPAPI_USERS = freeipapi + + if cloudfilt: + self.Schemas.DB_CLOUD_FILT_USERS = cloudfilt + + if psutils: + self.Schemas.DB_PSUTIL_USERS = psutils + + if localscan: + self.Schemas.DB_LOCALSCAN_USERS = localscan + def unload(self) -> None: """Cette methode sera executée a chaque désactivation ou rechargement de module """ + self.Settings.set_cache('ABUSEIPDB', self.Schemas.DB_ABUSEIPDB_USERS) + self.Settings.set_cache('FREEIPAPI', self.Schemas.DB_FREEIPAPI_USERS) + self.Settings.set_cache('CLOUDFILT', self.Schemas.DB_CLOUDFILT_USERS) + self.Settings.set_cache('PSUTIL', self.Schemas.DB_PSUTIL_USERS) + self.Settings.set_cache('LOCALSCAN', self.Schemas.DB_LOCALSCAN_USERS) + self.Schemas.DB_ABUSEIPDB_USERS = [] self.Schemas.DB_FREEIPAPI_USERS = [] self.Schemas.DB_CLOUDFILT_USERS = [] @@ -300,7 +332,7 @@ class Defender(): command = str(cmd[0]).lower() fromuser = user - channel = fromchannel = channel if self.Channel.Is_Channel(channel) else None + channel = fromchannel = channel if self.Channel.is_valid_channel(channel) else None dnickname = self.Config.SERVICE_NICKNAME # Defender nickname dchanlog = self.Config.SERVICE_CHANLOG # Defender chan log diff --git a/mods/defender/threads.py b/mods/defender/threads.py index eacaa49..9f00077 100644 --- a/mods/defender/threads.py +++ b/mods/defender/threads.py @@ -155,7 +155,7 @@ def timer_release_mode_mute(uplink: 'Defender', action: str, channel: str): """ service_id = uplink.Config.SERVICE_ID - if not uplink.Channel.Is_Channel(channel): + if not uplink.Channel.is_valid_channel(channel): uplink.Logs.debug(f"Channel is not valid {channel}") return diff --git a/mods/defender/utils.py b/mods/defender/utils.py index c5fc6e7..08cc470 100644 --- a/mods/defender/utils.py +++ b/mods/defender/utils.py @@ -52,7 +52,7 @@ def handle_on_mode(uplink: 'Defender', srvmsg: list[str]): if confmodel.autolimit == 1: if mode == '+l' or mode == '-l': - chan = irc.Channel.get_Channel(channel) + chan = irc.Channel.get_channel(channel) p.send2socket(f":{gconfig.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + confmodel.autolimit_amount}") if gconfig.SALON_JAIL == channel: @@ -80,7 +80,7 @@ def handle_on_sjoin(uplink: 'Defender', srvmsg: list[str]): gconfig = uplink.Config confmodel = uplink.ModConfig - parsed_chan = srvmsg[4] if irc.Channel.Is_Channel(srvmsg[4]) else None + parsed_chan = srvmsg[4] if irc.Channel.is_valid_channel(srvmsg[4]) else None parsed_UID = irc.User.clean_uid(srvmsg[5]) if parsed_chan is None or parsed_UID is None: @@ -265,7 +265,7 @@ def action_on_flood(uplink: 'Defender', srvmsg: list[str]): channel = srvmsg[3] User = irc.User.get_User(user_trigger) - if User is None or not irc.Channel.Is_Channel(channel_to_check=channel): + if User is None or not irc.Channel.is_valid_channel(channel_to_check=channel): return flood_time = confmodel.flood_time diff --git a/mods/jsonrpc/mod_jsonrpc.py b/mods/jsonrpc/mod_jsonrpc.py index 08d13c3..5ed288a 100644 --- a/mods/jsonrpc/mod_jsonrpc.py +++ b/mods/jsonrpc/mod_jsonrpc.py @@ -190,7 +190,7 @@ class Jsonrpc(): self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value) def unload(self) -> None: - if self.UnrealIrcdRpcLive.Error.code != -1: + if self.UnrealIrcdRpcLive.get_error.code != -1: self.UnrealIrcdRpcLive.unsubscribe() return None @@ -271,16 +271,13 @@ class Jsonrpc(): self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'{rpc.get_error.message}') return None - chan_list = [] - for chan in UserInfo.user.channels: - chan_list.append(chan.name) self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'UID : {UserInfo.id}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'NICKNAME : {UserInfo.name}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'USERNAME : {UserInfo.user.username}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'REALNAME : {UserInfo.user.realname}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'MODES : {UserInfo.user.modes}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'CHANNELS : {chan_list}') + self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'CHANNELS : {[chan.name for chan in UserInfo.user.channels]}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'SECURITY GROUP : {UserInfo.user.security_groups}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'REPUTATION : {UserInfo.user.reputation}') diff --git a/mods/votekick/mod_votekick.py b/mods/votekick/mod_votekick.py index 54b7d03..4b67727 100644 --- a/mods/votekick/mod_votekick.py +++ b/mods/votekick/mod_votekick.py @@ -291,7 +291,7 @@ class Votekick(): self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' :Your are not allowed to execute this command') return None - sentchannel = str(cmd[2]).lower() if self.Channel.Is_Channel(str(cmd[2]).lower()) else None + sentchannel = str(cmd[2]).lower() if self.Channel.is_valid_channel(str(cmd[2]).lower()) else None if sentchannel is None: self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f" The correct command is {self.Config.SERVICE_PREFIX}{command} {option} #CHANNEL") @@ -325,7 +325,7 @@ class Votekick(): self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f" Your are not allowed to execute this command") return None - sentchannel = str(cmd[2]).lower() if self.Channel.Is_Channel(str(cmd[2]).lower()) else None + sentchannel = str(cmd[2]).lower() if self.Channel.is_valid_channel(str(cmd[2]).lower()) else None if sentchannel is None: self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f" The correct command is {self.Config.SERVICE_PREFIX}{command} {option} #CHANNEL") @@ -459,7 +459,7 @@ class Votekick(): return False uid_cleaned = self.Base.clean_uid(uid_submitted) - ChannelInfo = self.Channel.get_Channel(channel) + ChannelInfo = self.Channel.get_channel(channel) if ChannelInfo is None: self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' This channel [{channel}] do not exist in the Channel Object') return False