mirror of
https://github.com/iio612/DEFENDER.git
synced 2026-02-13 11:14:23 +00:00
Adding some comments, editing methods names
This commit is contained in:
101
core/base.py
101
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:
|
||||
|
||||
@@ -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}')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'})
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
19
core/irc.py
19
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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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')]
|
||||
Reference in New Issue
Block a user