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