mirror of
https://github.com/iio612/DEFENDER.git
synced 2026-02-13 11:14:23 +00:00
Introduce full asyncio version (still some module to migrate). Defender JSONRPC Server ready and using with uvcorn
This commit is contained in:
103
core/base.py
103
core/base.py
@@ -45,9 +45,6 @@ class Base:
|
||||
# Liste des fonctions en attentes
|
||||
self.periodic_func: dict[object] = self.Settings.PERIODIC_FUNC
|
||||
|
||||
# Création du lock
|
||||
self.lock = self.Settings.LOCK
|
||||
|
||||
# Init install variable
|
||||
self.install: bool = False
|
||||
|
||||
@@ -57,8 +54,8 @@ class Base:
|
||||
# Create the database
|
||||
# self.__create_db()
|
||||
|
||||
def init(self) -> None:
|
||||
self.__create_db()
|
||||
async def init(self) -> None:
|
||||
await self.__create_db()
|
||||
|
||||
def __set_current_defender_version(self) -> None:
|
||||
"""This will put the current version of Defender
|
||||
@@ -145,7 +142,7 @@ class Base:
|
||||
except Exception as err:
|
||||
self.logs.error(f'General Error: {err}')
|
||||
|
||||
def create_log(self, log_message: str) -> None:
|
||||
async def create_log(self, log_message: str) -> None:
|
||||
"""Enregiste les logs
|
||||
|
||||
Args:
|
||||
@@ -156,11 +153,11 @@ class Base:
|
||||
"""
|
||||
sql_insert = f"INSERT INTO {self.Config.TABLE_LOG} (datetime, server_msg) VALUES (:datetime, :server_msg)"
|
||||
mes_donnees = {'datetime': str(self.Utils.get_sdatetime()),'server_msg': f'{log_message}'}
|
||||
self.db_execute_query(sql_insert, mes_donnees)
|
||||
await self.db_execute_query(sql_insert, mes_donnees)
|
||||
|
||||
return None
|
||||
|
||||
def log_cmd(self, user_cmd: str, cmd: str) -> None:
|
||||
async def log_cmd(self, user_cmd: str, cmd: str) -> None:
|
||||
"""Enregistre les commandes envoyées par les utilisateurs
|
||||
|
||||
Args:
|
||||
@@ -176,11 +173,11 @@ class Base:
|
||||
|
||||
insert_cmd_query = f"INSERT INTO {self.Config.TABLE_COMMAND} (datetime, user, commande) VALUES (:datetime, :user, :commande)"
|
||||
mes_donnees = {'datetime': self.Utils.get_sdatetime(), 'user': user_cmd, 'commande': cmd}
|
||||
self.db_execute_query(insert_cmd_query, mes_donnees)
|
||||
await self.db_execute_query(insert_cmd_query, mes_donnees)
|
||||
|
||||
return None
|
||||
|
||||
def db_sync_core_config(self, module_name: str, dataclassObj: object) -> bool:
|
||||
async def db_sync_core_config(self, module_name: str, dataclassObj: object) -> bool:
|
||||
"""Sync module local parameters with the database
|
||||
if new module then local param will be stored in the database
|
||||
if old module then db param will be moved to the local dataclassObj
|
||||
@@ -207,7 +204,7 @@ class Base:
|
||||
param_to_search = {'module_name': module_name, 'param_key': param_key}
|
||||
|
||||
search_query = f'''SELECT id FROM {core_table} WHERE module_name = :module_name AND param_key = :param_key'''
|
||||
excecute_search_query = self.db_execute_query(search_query, param_to_search)
|
||||
excecute_search_query = await self.db_execute_query(search_query, param_to_search)
|
||||
result_search_query = excecute_search_query.fetchone()
|
||||
|
||||
if result_search_query is None:
|
||||
@@ -219,7 +216,7 @@ class Base:
|
||||
insert_query = f'''INSERT INTO {core_table} (datetime, module_name, param_key, param_value)
|
||||
VALUES (:datetime, :module_name, :param_key, :param_value)
|
||||
'''
|
||||
execution = self.db_execute_query(insert_query, param_to_insert)
|
||||
execution = await self.db_execute_query(insert_query, param_to_insert)
|
||||
|
||||
if execution.rowcount > 0:
|
||||
self.logs.debug(f'New parameter added to the database: {param_key} --> {param_value}')
|
||||
@@ -227,14 +224,14 @@ class Base:
|
||||
# Delete from DB unused parameter
|
||||
query_select = f"SELECT module_name, param_key, param_value FROM {core_table} WHERE module_name = :module_name"
|
||||
parameter = {'module_name': module_name}
|
||||
execute_query_select = self.db_execute_query(query_select, parameter)
|
||||
execute_query_select = await self.db_execute_query(query_select, parameter)
|
||||
result_query_select = execute_query_select.fetchall()
|
||||
|
||||
for result in result_query_select:
|
||||
db_mod_name, db_param_key, db_param_value = result
|
||||
if not hasattr(dataclassObj, db_param_key):
|
||||
mes_donnees = {'param_key': db_param_key, 'module_name': db_mod_name}
|
||||
execute_delete = self.db_execute_query(f'DELETE FROM {core_table} WHERE module_name = :module_name and param_key = :param_key', mes_donnees)
|
||||
execute_delete = await self.db_execute_query(f'DELETE FROM {core_table} WHERE module_name = :module_name and param_key = :param_key', mes_donnees)
|
||||
row_affected = execute_delete.rowcount
|
||||
if row_affected > 0:
|
||||
self.logs.debug(f'A parameter has been deleted from the database: {db_param_key} --> {db_param_value} | Mod: {db_mod_name}')
|
||||
@@ -242,7 +239,7 @@ class Base:
|
||||
# Sync local variable with Database
|
||||
query = f"SELECT param_key, param_value FROM {core_table} WHERE module_name = :module_name"
|
||||
parameter = {'module_name': module_name}
|
||||
response = self.db_execute_query(query, parameter)
|
||||
response = await self.db_execute_query(query, parameter)
|
||||
result = response.fetchall()
|
||||
|
||||
for param, value in result:
|
||||
@@ -259,7 +256,7 @@ class Base:
|
||||
self.logs.error(err)
|
||||
return False
|
||||
|
||||
def db_update_core_config(self, module_name:str, dataclass_obj: object, param_key:str, param_value: str) -> bool:
|
||||
async def db_update_core_config(self, module_name:str, dataclass_obj: object, param_key:str, param_value: str) -> bool:
|
||||
|
||||
core_table = self.Config.TABLE_CONFIG
|
||||
# Check if the param exist
|
||||
@@ -269,7 +266,7 @@ class Base:
|
||||
|
||||
mes_donnees = {'module_name': module_name, 'param_key': param_key, 'param_value': param_value}
|
||||
search_param_query = f"SELECT id FROM {core_table} WHERE module_name = :module_name AND param_key = :param_key"
|
||||
result = self.db_execute_query(search_param_query, mes_donnees)
|
||||
result = await self.db_execute_query(search_param_query, mes_donnees)
|
||||
is_param_exist = result.fetchone()
|
||||
|
||||
if not is_param_exist is None:
|
||||
@@ -279,7 +276,7 @@ class Base:
|
||||
'param_value': param_value
|
||||
}
|
||||
query = f'''UPDATE {core_table} SET datetime = :datetime, param_value = :param_value WHERE module_name = :module_name AND param_key = :param_key'''
|
||||
update = self.db_execute_query(query, mes_donnees)
|
||||
update = await self.db_execute_query(query, mes_donnees)
|
||||
updated_rows = update.rowcount
|
||||
if updated_rows > 0:
|
||||
setattr(dataclass_obj, param_key, self.int_if_possible(param_value))
|
||||
@@ -293,9 +290,9 @@ class Base:
|
||||
|
||||
return True
|
||||
|
||||
def db_create_first_admin(self) -> None:
|
||||
async def db_create_first_admin(self) -> None:
|
||||
|
||||
user = self.db_execute_query(f"SELECT id FROM {self.Config.TABLE_ADMIN}")
|
||||
user = await self.db_execute_query(f"SELECT id FROM {self.Config.TABLE_ADMIN}")
|
||||
if not user.fetchall():
|
||||
admin = self.Config.OWNER
|
||||
password = self.Utils.hash_password(self.Config.PASSWORD)
|
||||
@@ -308,7 +305,7 @@ class Base:
|
||||
'language': 'EN',
|
||||
'level': 5
|
||||
}
|
||||
self.db_execute_query(f"""
|
||||
await self.db_execute_query(f"""
|
||||
INSERT INTO {self.Config.TABLE_ADMIN}
|
||||
(createdOn, user, password, hostname, vhost, language, level)
|
||||
VALUES
|
||||
@@ -381,11 +378,28 @@ class Base:
|
||||
return None
|
||||
|
||||
task = asyncio.create_task(func, name=name)
|
||||
task.add_done_callback(self.asynctask_done)
|
||||
self.running_asynctasks.append(task)
|
||||
|
||||
self.logs.debug(f"++ New asynchrone task created as: {task.get_name()}")
|
||||
return task
|
||||
|
||||
def asynctask_done(self, task: asyncio.Task):
|
||||
"""Log task when done
|
||||
|
||||
Args:
|
||||
task (asyncio.Task): The Asyncio Task callback
|
||||
"""
|
||||
try:
|
||||
if task.exception():
|
||||
self.logs.error(f"[ASYNCIO] Task {task.get_name()} failed with exception: {task.exception()}")
|
||||
else:
|
||||
self.logs.debug(f"[ASYNCIO] Task {task.get_name()} completed successfully.")
|
||||
except asyncio.CancelledError as ce:
|
||||
self.logs.debug(f"[ASYNCIO] Task {task.get_name()} terminated with cancelled error.")
|
||||
except asyncio.InvalidStateError as ie:
|
||||
self.logs.debug(f"[ASYNCIO] Task {task.get_name()} terminated with invalid state error.")
|
||||
|
||||
def is_thread_alive(self, thread_name: str) -> bool:
|
||||
"""Check if the thread is still running! using the is_alive method of Threads.
|
||||
|
||||
@@ -429,7 +443,7 @@ class Base:
|
||||
Returns:
|
||||
int: Number of threads
|
||||
"""
|
||||
with self.lock:
|
||||
with self.Settings.LOCK:
|
||||
count = 0
|
||||
|
||||
for thr in self.running_threads:
|
||||
@@ -478,7 +492,7 @@ class Base:
|
||||
self.running_sockets.remove(soc)
|
||||
self.logs.debug(f"-- Socket ==> closed {str(soc.fileno())}")
|
||||
|
||||
def shutdown(self) -> None:
|
||||
async def shutdown(self) -> None:
|
||||
"""Methode qui va préparer l'arrêt complêt du service
|
||||
"""
|
||||
# Nettoyage des timers
|
||||
@@ -507,6 +521,9 @@ class Base:
|
||||
|
||||
self.running_sockets.remove(soc)
|
||||
self.logs.debug(f"> Socket ==> closed {str(soc.fileno())}")
|
||||
|
||||
await self.Loader.RpcServer.stop_server()
|
||||
self.db_close()
|
||||
|
||||
return None
|
||||
|
||||
@@ -524,7 +541,7 @@ class Base:
|
||||
self.logs.info("-- Database connexion has been initiated")
|
||||
return engine, cursor
|
||||
|
||||
def __create_db(self) -> None:
|
||||
async def __create_db(self) -> None:
|
||||
|
||||
table_core_log = f'''CREATE TABLE IF NOT EXISTS {self.Config.TABLE_LOG} (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
@@ -594,27 +611,27 @@ class Base:
|
||||
)
|
||||
'''
|
||||
|
||||
self.db_execute_query(table_core_log)
|
||||
self.db_execute_query(table_core_log_command)
|
||||
self.db_execute_query(table_core_module)
|
||||
self.db_execute_query(table_core_admin)
|
||||
self.db_execute_query(table_core_client)
|
||||
self.db_execute_query(table_core_channel)
|
||||
self.db_execute_query(table_core_config)
|
||||
await self.db_execute_query(table_core_log)
|
||||
await self.db_execute_query(table_core_log_command)
|
||||
await self.db_execute_query(table_core_module)
|
||||
await self.db_execute_query(table_core_admin)
|
||||
await self.db_execute_query(table_core_client)
|
||||
await self.db_execute_query(table_core_channel)
|
||||
await self.db_execute_query(table_core_config)
|
||||
|
||||
# Patch database
|
||||
self.db_patch(self.Config.TABLE_ADMIN, "language", "TEXT")
|
||||
await self.db_patch(self.Config.TABLE_ADMIN, "language", "TEXT")
|
||||
|
||||
if self.install:
|
||||
self.Loader.ModuleUtils.db_register_module('mod_command', 'sys', True)
|
||||
self.Loader.ModuleUtils.db_register_module('mod_defender', 'sys', True)
|
||||
await self.Loader.ModuleUtils.db_register_module('mod_command', 'sys', True)
|
||||
await self.Loader.ModuleUtils.db_register_module('mod_defender', 'sys', True)
|
||||
self.install = False
|
||||
|
||||
return None
|
||||
|
||||
def db_execute_query(self, query:str, params:dict = {}) -> CursorResult:
|
||||
async def db_execute_query(self, query:str, params:dict = {}) -> CursorResult:
|
||||
|
||||
with self.lock:
|
||||
async with self.Loader.Settings.AILOCK:
|
||||
insert_query = text(query)
|
||||
if not params:
|
||||
response = self.cursor.execute(insert_query)
|
||||
@@ -625,8 +642,8 @@ class Base:
|
||||
|
||||
return response
|
||||
|
||||
def db_is_column_exist(self, table_name: str, column_name: str) -> bool:
|
||||
q = self.db_execute_query(f"PRAGMA table_info({table_name})")
|
||||
async def db_is_column_exist(self, table_name: str, column_name: str) -> bool:
|
||||
q = await self.db_execute_query(f"PRAGMA table_info({table_name})")
|
||||
existing_columns = [col[1] for col in q.fetchall()]
|
||||
|
||||
if column_name in existing_columns:
|
||||
@@ -634,12 +651,12 @@ class Base:
|
||||
else:
|
||||
return False
|
||||
|
||||
def db_patch(self, table_name: str, column_name: str, column_type: str) -> bool:
|
||||
if not self.db_is_column_exist(table_name, column_name):
|
||||
async def db_patch(self, table_name: str, column_name: str, column_type: str) -> bool:
|
||||
if not await self.db_is_column_exist(table_name, column_name):
|
||||
patch = f"ALTER TABLE {table_name} ADD COLUMN {column_name} {column_type}"
|
||||
update_row = f"UPDATE {table_name} SET language = 'EN' WHERE language is null"
|
||||
self.db_execute_query(patch)
|
||||
self.db_execute_query(update_row)
|
||||
await self.db_execute_query(patch)
|
||||
await self.db_execute_query(update_row)
|
||||
self.logs.debug(f"The patch has been applied")
|
||||
self.logs.debug(f"Table name: {table_name}, Column name: {column_name}, Column type: {column_type}")
|
||||
return True
|
||||
@@ -647,9 +664,9 @@ class Base:
|
||||
return False
|
||||
|
||||
def db_close(self) -> None:
|
||||
|
||||
try:
|
||||
self.cursor.close()
|
||||
self.logs.debug("Database engine closed!")
|
||||
except AttributeError as ae:
|
||||
self.logs.error(f"Attribute Error : {ae}")
|
||||
|
||||
|
||||
@@ -24,22 +24,19 @@ class IModule(ABC):
|
||||
# Log the module
|
||||
self.ctx.Logs.debug(f'Loading Module {self.module_name} ...')
|
||||
|
||||
def init(self) -> None:
|
||||
self.load()
|
||||
self.create_tables()
|
||||
|
||||
async def sync_db(self) -> None:
|
||||
# Sync the configuration with core configuration (Mandatory)
|
||||
self.ctx.Base.db_sync_core_config(self.module_name, self.mod_config)
|
||||
await self.ctx.Base.db_sync_core_config(self.module_name, self.mod_config)
|
||||
return None
|
||||
|
||||
def update_configuration(self, param_key: str, param_value: Union[str, int]) -> None:
|
||||
async def update_configuration(self, param_key: str, param_value: Union[str, int]) -> None:
|
||||
"""Update the local and core configuration
|
||||
|
||||
Args:
|
||||
param_key (str): The parameter key
|
||||
param_value (str): The parameter value
|
||||
"""
|
||||
self.ctx.Base.db_update_core_config(self.module_name, self.mod_config, param_key, param_value)
|
||||
await self.ctx.Base.db_update_core_config(self.module_name, self.mod_config, param_key, param_value)
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
@@ -58,17 +55,17 @@ class IModule(ABC):
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def load(self) -> None:
|
||||
async def load(self) -> None:
|
||||
"""This method is executed when the module is loaded or reloaded.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def unload(self) -> None:
|
||||
async def unload(self) -> None:
|
||||
"""This method is executed when the module is unloaded or reloaded.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def cmd(self, data: list) -> None:
|
||||
async def cmd(self, data: list) -> None:
|
||||
"""When recieving server messages.
|
||||
|
||||
Args:
|
||||
@@ -76,7 +73,7 @@ class IModule(ABC):
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def hcmds(self, user: str, channel: Optional[str], cmd: list[str], fullcmd: Optional[list[str]] = None) -> None:
|
||||
async def hcmds(self, user: str, channel: Optional[str], cmd: list[str], fullcmd: Optional[list[str]] = None) -> None:
|
||||
"""These are the commands recieved from a client
|
||||
|
||||
Args:
|
||||
|
||||
@@ -4,31 +4,20 @@ from core.classes.protocols.command_handler import CommandHandler
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.definition import MClient, MSasl, MUser, MChannel
|
||||
from core.irc import Irc
|
||||
from core.loader import Loader
|
||||
|
||||
class IProtocol(ABC):
|
||||
|
||||
Handler: Optional[CommandHandler] = None
|
||||
|
||||
def __init__(self, uplink: 'Irc'):
|
||||
def __init__(self, context: 'Loader'):
|
||||
self.name: Optional[str] = None
|
||||
self.protocol_version: int = -1
|
||||
self.known_protocol: set[str] = set()
|
||||
|
||||
self._Irc = uplink
|
||||
self._Config = uplink.Config
|
||||
self._Base = uplink.Base
|
||||
self._Settings = uplink.Base.Settings
|
||||
self._Utils = uplink.Loader.Utils
|
||||
self._Logs = uplink.Loader.Logs
|
||||
self._User = uplink.User
|
||||
self._Channel = uplink.Channel
|
||||
|
||||
self.Handler = CommandHandler(uplink.Loader)
|
||||
|
||||
self._ctx = context
|
||||
self.Handler = CommandHandler(context)
|
||||
self.init_protocol()
|
||||
|
||||
self._Logs.info(f"[PROTOCOL] Protocol [{self.__class__.__name__}] loaded!")
|
||||
self._ctx.Logs.info(f"[PROTOCOL] Protocol [{self.__class__.__name__}] loaded!")
|
||||
|
||||
@abstractmethod
|
||||
def init_protocol(self):
|
||||
@@ -313,7 +302,7 @@ class IProtocol(ABC):
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
@abstractmethod
|
||||
async def parse_uid(self, server_msg: list[str]) -> Optional['MUser']:
|
||||
def parse_uid(self, server_msg: list[str]) -> Optional['MUser']:
|
||||
"""Parse UID and return dictionary.
|
||||
|
||||
Args:
|
||||
@@ -324,7 +313,7 @@ class IProtocol(ABC):
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
async def parse_quit(self, server_msg: list[str]) -> tuple[Optional['MUser'], str]:
|
||||
def parse_quit(self, server_msg: list[str]) -> tuple[Optional['MUser'], str]:
|
||||
"""Parse quit and return dictionary.
|
||||
>>> [':97KAAAAAB', 'QUIT', ':Quit:', 'this', 'is', 'my', 'reason', 'to', 'quit']
|
||||
Args:
|
||||
@@ -335,7 +324,7 @@ class IProtocol(ABC):
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
async def parse_nick(self, server_msg: list[str]) -> tuple[Optional['MUser'], str, str]:
|
||||
def parse_nick(self, server_msg: list[str]) -> tuple[Optional['MUser'], str, str]:
|
||||
"""Parse nick changes and return dictionary.
|
||||
>>> [':97KAAAAAC', 'NICK', 'testinspir', '1757360740']
|
||||
|
||||
@@ -349,7 +338,7 @@ class IProtocol(ABC):
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
async def parse_privmsg(self, server_msg: list[str]) -> tuple[Optional['MUser'], Optional['MUser'], Optional['MChannel'], str]:
|
||||
def parse_privmsg(self, server_msg: list[str]) -> tuple[Optional['MUser'], Optional['MUser'], Optional['MChannel'], str]:
|
||||
"""Parse PRIVMSG message.
|
||||
>>> [':97KAAAAAE', 'PRIVMSG', '#welcome', ':This', 'is', 'my', 'public', 'message']
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ class Admin:
|
||||
|
||||
return admin.language
|
||||
|
||||
def db_auth_admin_via_fingerprint(self, fp: str, uidornickname: str) -> bool:
|
||||
async def db_auth_admin_via_fingerprint(self, fp: str, uidornickname: str) -> bool:
|
||||
"""Check the fingerprint
|
||||
|
||||
Args:
|
||||
@@ -188,7 +188,7 @@ class Admin:
|
||||
|
||||
query = f"SELECT user, level, language FROM {self.Config.TABLE_ADMIN} WHERE fingerprint = :fp"
|
||||
data = {'fp': fp}
|
||||
exe = self.Base.db_execute_query(query, data)
|
||||
exe = await self.Base.db_execute_query(query, data)
|
||||
result = exe.fetchone()
|
||||
if result:
|
||||
account = result[0]
|
||||
@@ -204,7 +204,7 @@ class Admin:
|
||||
|
||||
return False
|
||||
|
||||
def db_is_admin_exist(self, admin_nickname: str) -> bool:
|
||||
async def db_is_admin_exist(self, admin_nickname: str) -> bool:
|
||||
"""Verify if the admin exist in the database!
|
||||
|
||||
Args:
|
||||
@@ -216,7 +216,7 @@ class Admin:
|
||||
|
||||
mes_donnees = {'admin': admin_nickname}
|
||||
query_search_user = f"SELECT id FROM {self.Config.TABLE_ADMIN} WHERE user = :admin"
|
||||
r = self.Base.db_execute_query(query_search_user, mes_donnees)
|
||||
r = await self.Base.db_execute_query(query_search_user, mes_donnees)
|
||||
exist_user = r.fetchone()
|
||||
if exist_user:
|
||||
return True
|
||||
|
||||
@@ -17,9 +17,7 @@ class Channel:
|
||||
Args:
|
||||
loader (Loader): The Loader Instance
|
||||
"""
|
||||
self.Logs = loader.Logs
|
||||
self.Base = loader.Base
|
||||
self.Utils = loader.Utils
|
||||
self._ctx = loader
|
||||
|
||||
def insert(self, new_channel: 'MChannel') -> bool:
|
||||
"""This method will insert a new channel and if the channel exist it will update the user list (uids)
|
||||
@@ -34,14 +32,14 @@ class Channel:
|
||||
exist = False
|
||||
|
||||
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 #")
|
||||
self._ctx.Logs.error(f"The channel {new_channel.name} is not valid, channel must start with #")
|
||||
return False
|
||||
|
||||
for record in self.UID_CHANNEL_DB:
|
||||
if record.name.lower() == new_channel.name.lower():
|
||||
# If the channel exist, update the user list and do not go further
|
||||
exist = True
|
||||
# self.Logs.debug(f'{record.name} already exist')
|
||||
# self._ctx.Logs.debug(f'{record.name} already exist')
|
||||
|
||||
for user in new_channel.uids:
|
||||
record.uids.append(user)
|
||||
@@ -49,7 +47,7 @@ class Channel:
|
||||
# Supprimer les doublons
|
||||
del_duplicates = list(set(record.uids))
|
||||
record.uids = del_duplicates
|
||||
# self.Logs.debug(f'Updating a new UID to the channel {record}')
|
||||
# self._ctx.Logs.debug(f'Updating a new UID to the channel {record}')
|
||||
return result
|
||||
|
||||
if not exist:
|
||||
@@ -57,10 +55,10 @@ class Channel:
|
||||
new_channel.name = new_channel.name.lower()
|
||||
self.UID_CHANNEL_DB.append(new_channel)
|
||||
result = True
|
||||
# self.Logs.debug(f'New Channel Created: ({new_channel})')
|
||||
# self._ctx.Logs.debug(f'New Channel Created: ({new_channel})')
|
||||
|
||||
if not result:
|
||||
self.Logs.critical(f'The Channel Object was not inserted {new_channel}')
|
||||
self._ctx.Logs.critical(f'The Channel Object was not inserted {new_channel}')
|
||||
|
||||
self.clean_channel()
|
||||
|
||||
@@ -103,7 +101,7 @@ class Channel:
|
||||
return result
|
||||
|
||||
for userid in chan_obj.uids:
|
||||
if self.Utils.clean_uid(userid) == self.Utils.clean_uid(uid):
|
||||
if self._ctx.Utils.clean_uid(userid) == self._ctx.Utils.clean_uid(uid):
|
||||
chan_obj.uids.remove(userid)
|
||||
result = True
|
||||
|
||||
@@ -111,7 +109,7 @@ class Channel:
|
||||
|
||||
return result
|
||||
except ValueError as ve:
|
||||
self.Logs.error(f'{ve}')
|
||||
self._ctx.Logs.error(f'{ve}')
|
||||
return False
|
||||
|
||||
def delete_user_from_all_channel(self, uid:str) -> bool:
|
||||
@@ -128,7 +126,7 @@ class Channel:
|
||||
|
||||
for record in self.UID_CHANNEL_DB:
|
||||
for user_id in record.uids:
|
||||
if self.Utils.clean_uid(user_id) == self.Utils.clean_uid(uid):
|
||||
if self._ctx.Utils.clean_uid(user_id) == self._ctx.Utils.clean_uid(uid):
|
||||
record.uids.remove(user_id)
|
||||
result = True
|
||||
|
||||
@@ -136,7 +134,7 @@ class Channel:
|
||||
|
||||
return result
|
||||
except ValueError as ve:
|
||||
self.Logs.error(f'{ve}')
|
||||
self._ctx.Logs.error(f'{ve}')
|
||||
return False
|
||||
|
||||
def add_user_to_a_channel(self, channel_name: str, uid: str) -> bool:
|
||||
@@ -154,7 +152,7 @@ class Channel:
|
||||
|
||||
if chan_obj is None:
|
||||
# Create a new channel if the channel don't exist
|
||||
self.Logs.debug(f"New channel will be created ({channel_name} - {uid})")
|
||||
self._ctx.Logs.debug(f"New channel will be created ({channel_name} - {uid})")
|
||||
return self.insert(MChannel(channel_name, uids=[uid]))
|
||||
|
||||
chan_obj.uids.append(uid)
|
||||
@@ -163,7 +161,7 @@ class Channel:
|
||||
|
||||
return True
|
||||
except Exception as err:
|
||||
self.Logs.error(f'{err}')
|
||||
self._ctx.Logs.error(f'{err}')
|
||||
return False
|
||||
|
||||
def is_user_present_in_channel(self, channel_name: str, uid: str) -> bool:
|
||||
@@ -180,9 +178,9 @@ class Channel:
|
||||
if chan is None:
|
||||
return False
|
||||
|
||||
clean_uid = self.Utils.clean_uid(uid=uid)
|
||||
clean_uid = self._ctx.Utils.clean_uid(uid=uid)
|
||||
for chan_uid in chan.uids:
|
||||
if self.Utils.clean_uid(chan_uid) == clean_uid:
|
||||
if self._ctx.Utils.clean_uid(chan_uid) == clean_uid:
|
||||
return True
|
||||
|
||||
return False
|
||||
@@ -197,7 +195,7 @@ class Channel:
|
||||
|
||||
return None
|
||||
except Exception as err:
|
||||
self.Logs.error(f'{err}')
|
||||
self._ctx.Logs.error(f'{err}')
|
||||
|
||||
def get_channel(self, channel_name: str) -> Optional['MChannel']:
|
||||
"""Get the channel object
|
||||
@@ -237,13 +235,13 @@ class Channel:
|
||||
else:
|
||||
return True
|
||||
except TypeError as te:
|
||||
self.Logs.error(f'TypeError: [{channel_to_check}] - {te}')
|
||||
self._ctx.Logs.error(f'TypeError: [{channel_to_check}] - {te}')
|
||||
return False
|
||||
except Exception as err:
|
||||
self.Logs.error(f'Error Not defined: {err}')
|
||||
self._ctx.Logs.error(f'Error Not defined: {err}')
|
||||
return False
|
||||
|
||||
def db_query_channel(self, action: Literal['add','del'], module_name: str, channel_name: str) -> bool:
|
||||
async def db_query_channel(self, action: Literal['add','del'], module_name: str, channel_name: str) -> bool:
|
||||
"""You can add a channel or delete a channel.
|
||||
|
||||
Args:
|
||||
@@ -256,39 +254,49 @@ class Channel:
|
||||
"""
|
||||
try:
|
||||
channel_name = channel_name.lower() if self.is_valid_channel(channel_name) else None
|
||||
core_table = self.Base.Config.TABLE_CHANNEL
|
||||
core_table = self._ctx.Base.Config.TABLE_CHANNEL
|
||||
|
||||
if not channel_name:
|
||||
self.Logs.warning(f'The channel [{channel_name}] is not correct')
|
||||
self._ctx.Logs.warning(f'The channel [{channel_name}] is not correct')
|
||||
return False
|
||||
|
||||
match action:
|
||||
|
||||
case 'add':
|
||||
mes_donnees = {'module_name': module_name, 'channel_name': channel_name}
|
||||
response = self.Base.db_execute_query(f"SELECT id FROM {core_table} WHERE module_name = :module_name AND channel_name = :channel_name", mes_donnees)
|
||||
response = await self._ctx.Base.db_execute_query(f"SELECT id FROM {core_table} WHERE module_name = :module_name AND channel_name = :channel_name", mes_donnees)
|
||||
is_channel_exist = response.fetchone()
|
||||
|
||||
if is_channel_exist is None:
|
||||
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)
|
||||
mes_donnees = {'datetime': self._ctx.Utils.get_sdatetime(), 'channel_name': channel_name, 'module_name': module_name}
|
||||
insert = await self._ctx.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'Channel added to DB: channel={channel_name} / module_name={module_name}')
|
||||
self._ctx.Logs.debug(f'Channel added to DB: channel={channel_name} / module_name={module_name}')
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
case 'del':
|
||||
mes_donnes = {'channel_name': channel_name, 'module_name': module_name}
|
||||
response = self.Base.db_execute_query(f"DELETE FROM {core_table} WHERE channel_name = :channel_name AND module_name = :module_name", mes_donnes)
|
||||
response = await self._ctx.Base.db_execute_query(f"DELETE FROM {core_table} WHERE channel_name = :channel_name AND module_name = :module_name", mes_donnes)
|
||||
|
||||
if response.rowcount > 0:
|
||||
self.Logs.debug(f'Channel deleted from DB: channel={channel_name} / module: {module_name}')
|
||||
self._ctx.Logs.debug(f'Channel deleted from DB: channel={channel_name} / module: {module_name}')
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
except Exception as err:
|
||||
self.Logs.error(err)
|
||||
self._ctx.Logs.error(err)
|
||||
return False
|
||||
|
||||
async def db_join_saved_channels(self) -> None:
|
||||
"""## Joining saved channels"""
|
||||
exec_query = await self._ctx.Base.db_execute_query(f'SELECT distinct channel_name FROM {self._ctx.Config.TABLE_CHANNEL}')
|
||||
result_query = exec_query.fetchall()
|
||||
|
||||
if result_query:
|
||||
for chan_name in result_query:
|
||||
chan = chan_name[0]
|
||||
await self._ctx.Irc.Protocol.send_sjoin(channel=chan)
|
||||
@@ -201,7 +201,7 @@ class Client:
|
||||
|
||||
return True
|
||||
|
||||
def db_is_account_exist(self, account: str) -> bool:
|
||||
async def db_is_account_exist(self, account: str) -> bool:
|
||||
"""Check if the account exist in the database
|
||||
|
||||
Args:
|
||||
@@ -213,7 +213,7 @@ class Client:
|
||||
|
||||
table_client = self.Base.Config.TABLE_CLIENT
|
||||
account_to_check = {'account': account.lower()}
|
||||
account_to_check_query = self.Base.db_execute_query(f"""
|
||||
account_to_check_query = await self.Base.db_execute_query(f"""
|
||||
SELECT id FROM {table_client} WHERE LOWER(account) = :account
|
||||
""", account_to_check)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import TYPE_CHECKING
|
||||
import socket
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.irc import Irc
|
||||
from core.loader import Loader
|
||||
|
||||
# Modules impacted by rehashing!
|
||||
REHASH_MODULES = [
|
||||
@@ -14,7 +14,10 @@ REHASH_MODULES = [
|
||||
'core.classes.modules.config',
|
||||
'core.base',
|
||||
'core.classes.modules.commands',
|
||||
'core.classes.modules.rpc',
|
||||
'core.classes.modules.rpc.rpc_channel',
|
||||
'core.classes.modules.rpc.rpc_command',
|
||||
'core.classes.modules.rpc.rpc_user',
|
||||
'core.classes.modules.rpc.rpc',
|
||||
'core.classes.interfaces.iprotocol',
|
||||
'core.classes.interfaces.imodule',
|
||||
'core.classes.protocols.command_handler',
|
||||
@@ -24,66 +27,62 @@ REHASH_MODULES = [
|
||||
]
|
||||
|
||||
|
||||
def restart_service(uplink: 'Irc', reason: str = "Restarting with no reason!") -> None:
|
||||
async def restart_service(uplink: 'Loader', reason: str = "Restarting with no reason!") -> None:
|
||||
"""
|
||||
|
||||
Args:
|
||||
uplink (Irc): The Irc instance
|
||||
reason (str): The reason of the restart.
|
||||
"""
|
||||
# reload modules.
|
||||
# unload modules.
|
||||
for module in uplink.ModuleUtils.model_get_loaded_modules().copy():
|
||||
uplink.ModuleUtils.unload_one_module(uplink, module.module_name)
|
||||
await uplink.ModuleUtils.unload_one_module(module.module_name)
|
||||
|
||||
uplink.Base.garbage_collector_thread()
|
||||
|
||||
uplink.Logs.debug(f'[{uplink.Config.SERVICE_NICKNAME} RESTART]: Reloading configuration!')
|
||||
uplink.Protocol.send_squit(server_id=uplink.Config.SERVEUR_ID, server_link=uplink.Config.SERVEUR_LINK, reason=reason)
|
||||
await uplink.Irc.Protocol.send_squit(server_id=uplink.Config.SERVEUR_ID, server_link=uplink.Config.SERVEUR_LINK, reason=reason)
|
||||
uplink.Logs.debug('Restarting Defender ...')
|
||||
uplink.IrcSocket.shutdown(socket.SHUT_RDWR)
|
||||
uplink.IrcSocket.close()
|
||||
|
||||
while uplink.IrcSocket.fileno() != -1:
|
||||
time.sleep(0.5)
|
||||
uplink.Logs.warning('-- Waiting for socket to close ...')
|
||||
|
||||
# Reload configuration
|
||||
uplink.Loader.Config = uplink.Loader.ConfModule.Configuration(uplink.Loader).configuration_model
|
||||
uplink.Loader.Base = uplink.Loader.BaseModule.Base(uplink.Loader)
|
||||
|
||||
for mod in REHASH_MODULES:
|
||||
importlib.reload(sys.modules[mod])
|
||||
|
||||
uplink.Protocol = uplink.Loader.PFactory.get()
|
||||
uplink.Protocol.register_command()
|
||||
# Reload configuration
|
||||
uplink.Config = uplink.ConfModule.Configuration(uplink).configuration_model
|
||||
uplink.Base = uplink.BaseModule.Base(uplink)
|
||||
|
||||
uplink.ModuleUtils.model_clear() # Clear loaded modules.
|
||||
uplink.User.UID_DB.clear() # Clear User Object
|
||||
uplink.Channel.UID_CHANNEL_DB.clear() # Clear Channel Object
|
||||
uplink.Client.CLIENT_DB.clear() # Clear Client object
|
||||
uplink.Irc.Protocol.Handler.DB_IRCDCOMMS.clear()
|
||||
|
||||
uplink.init_service_user()
|
||||
uplink.Utils.create_socket(uplink)
|
||||
uplink.Protocol.send_link()
|
||||
# Reload Service modules
|
||||
for module in uplink.ModuleUtils.model_get_loaded_modules().copy():
|
||||
await uplink.ModuleUtils.reload_one_module(module.module_name, uplink.Settings.current_admin)
|
||||
|
||||
uplink.Irc.signal = True
|
||||
await uplink.Irc.run()
|
||||
uplink.Config.DEFENDER_RESTART = 0
|
||||
|
||||
def rehash_service(uplink: 'Irc', nickname: str) -> None:
|
||||
async def rehash_service(uplink: 'Loader', nickname: str) -> None:
|
||||
need_a_restart = ["SERVEUR_ID"]
|
||||
uplink.Settings.set_cache('db_commands', uplink.Commands.DB_COMMANDS)
|
||||
uplink.Loader.RpcServer.stop_server()
|
||||
|
||||
await uplink.RpcServer.stop_server()
|
||||
|
||||
restart_flag = False
|
||||
config_model_bakcup = uplink.Config
|
||||
mods = REHASH_MODULES
|
||||
for mod in mods:
|
||||
importlib.reload(sys.modules[mod])
|
||||
uplink.Protocol.send_priv_msg(
|
||||
await uplink.Irc.Protocol.send_priv_msg(
|
||||
nick_from=uplink.Config.SERVICE_NICKNAME,
|
||||
msg=f'[REHASH] Module [{mod}] reloaded',
|
||||
channel=uplink.Config.SERVICE_CHANLOG
|
||||
)
|
||||
uplink.Utils = sys.modules['core.utils']
|
||||
uplink.Config = uplink.Loader.Config = uplink.Loader.ConfModule.Configuration(uplink.Loader).configuration_model
|
||||
uplink.Config = uplink.ConfModule.Configuration(uplink).configuration_model
|
||||
uplink.Config.HSID = config_model_bakcup.HSID
|
||||
uplink.Config.DEFENDER_INIT = config_model_bakcup.DEFENDER_INIT
|
||||
uplink.Config.DEFENDER_RESTART = config_model_bakcup.DEFENDER_RESTART
|
||||
@@ -96,7 +95,7 @@ def rehash_service(uplink: 'Irc', nickname: str) -> None:
|
||||
|
||||
for key, value in conf_bkp_dict.items():
|
||||
if config_dict[key] != value and key != 'COLORS':
|
||||
uplink.Protocol.send_priv_msg(
|
||||
await uplink.Irc.Protocol.send_priv_msg(
|
||||
nick_from=uplink.Config.SERVICE_NICKNAME,
|
||||
msg=f'[{key}]: {value} ==> {config_dict[key]}',
|
||||
channel=uplink.Config.SERVICE_CHANLOG
|
||||
@@ -105,27 +104,28 @@ def rehash_service(uplink: 'Irc', nickname: str) -> None:
|
||||
restart_flag = True
|
||||
|
||||
if config_model_bakcup.SERVICE_NICKNAME != uplink.Config.SERVICE_NICKNAME:
|
||||
uplink.Protocol.send_set_nick(uplink.Config.SERVICE_NICKNAME)
|
||||
await uplink.Irc.Protocol.send_set_nick(uplink.Config.SERVICE_NICKNAME)
|
||||
|
||||
if restart_flag:
|
||||
uplink.Config.SERVEUR_ID = config_model_bakcup.SERVEUR_ID
|
||||
uplink.Protocol.send_priv_msg(
|
||||
await uplink.Irc.Protocol.send_priv_msg(
|
||||
nick_from=uplink.Config.SERVICE_NICKNAME,
|
||||
channel=uplink.Config.SERVICE_CHANLOG,
|
||||
msg='You need to restart defender !')
|
||||
|
||||
# Reload Main Commands Module
|
||||
uplink.Commands = uplink.Loader.CommandModule.Command(uplink.Loader)
|
||||
uplink.Loader.RpcServer = uplink.Loader.RpcServerModule.JSONRPCServer(uplink.Loader)
|
||||
uplink.Loader.RpcServer.start_server()
|
||||
uplink.Commands = uplink.CommandModule.Command(uplink)
|
||||
uplink.Commands.DB_COMMANDS = uplink.Settings.get_cache('db_commands')
|
||||
|
||||
uplink.Loader.Base = uplink.Loader.BaseModule.Base(uplink.Loader)
|
||||
uplink.Protocol = uplink.Loader.PFactory.get()
|
||||
uplink.Protocol.register_command()
|
||||
uplink.Base = uplink.BaseModule.Base(uplink)
|
||||
uplink.Irc.Protocol = uplink.PFactory.get()
|
||||
uplink.Irc.Protocol.register_command()
|
||||
|
||||
uplink.RpcServer = uplink.RpcServerModule.JSonRpcServer(uplink)
|
||||
uplink.Base.create_asynctask(uplink.RpcServer.start_server())
|
||||
|
||||
# Reload Service modules
|
||||
for module in uplink.ModuleUtils.model_get_loaded_modules().copy():
|
||||
uplink.ModuleUtils.reload_one_module(uplink, module.module_name, nickname)
|
||||
await uplink.ModuleUtils.reload_one_module(module.module_name, nickname)
|
||||
|
||||
return None
|
||||
1
core/classes/modules/rpc/__init__.py
Normal file
1
core/classes/modules/rpc/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
__version__ = '1.0.0'
|
||||
@@ -1,8 +1,11 @@
|
||||
import base64
|
||||
import json
|
||||
import logging
|
||||
from starlette.applications import Starlette
|
||||
from starlette.responses import JSONResponse
|
||||
from starlette.requests import Request
|
||||
from starlette.routing import Route
|
||||
import uvicorn
|
||||
from enum import Enum
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
from core.classes.modules.rpc.rpc_user import RPCUser
|
||||
from core.classes.modules.rpc.rpc_channel import RPCChannel
|
||||
@@ -11,120 +14,101 @@ from core.classes.modules.rpc.rpc_command import RPCCommand
|
||||
if TYPE_CHECKING:
|
||||
from core.loader import Loader
|
||||
|
||||
ProxyLoader: Optional['Loader'] = None
|
||||
class JSonRpcServer:
|
||||
|
||||
class RPCRequestHandler(BaseHTTPRequestHandler):
|
||||
def __init__(self, context: 'Loader', *, hostname: str = 'localhost', port: int = 5000):
|
||||
self._ctx = context
|
||||
self.live: bool = False
|
||||
self.host = hostname
|
||||
self.port = port
|
||||
self.routes: list[Route] = []
|
||||
self.server: Optional[uvicorn.Server] = None
|
||||
|
||||
def log_message(self, format, *args):
|
||||
pass
|
||||
|
||||
def do_POST(self):
|
||||
logs = ProxyLoader.Logs
|
||||
self.server_version = 'Defender6'
|
||||
self.sys_version = ProxyLoader.Config.CURRENT_VERSION
|
||||
content_length = int(self.headers['Content-Length'])
|
||||
body = self.rfile.read(content_length)
|
||||
request_data: dict = json.loads(body)
|
||||
rip, rport = self.client_address
|
||||
|
||||
if not self.authenticate(request_data):
|
||||
return None
|
||||
|
||||
response_data = {
|
||||
'jsonrpc': '2.0',
|
||||
'id': request_data.get('id', 123)
|
||||
self.methods: dict = {
|
||||
'user.list': RPCUser(context).user_list,
|
||||
'user.get': RPCUser(context).user_get,
|
||||
'channel.list': RPCChannel(context).channel_list,
|
||||
'command.list': RPCCommand(context).command_list,
|
||||
'command.get.by.name': RPCCommand(context).command_get_by_name,
|
||||
'command.get.by.module': RPCCommand(context).command_get_by_module
|
||||
}
|
||||
|
||||
method = request_data.get("method")
|
||||
async def start_server(self):
|
||||
|
||||
if not self.live:
|
||||
self.routes = [Route('/api', self.request_handler, methods=['POST'])]
|
||||
self.app_jsonrpc = Starlette(debug=False, routes=self.routes)
|
||||
config = uvicorn.Config(self.app_jsonrpc, host=self.host, port=self.port, log_level=self._ctx.Config.DEBUG_LEVEL)
|
||||
self.server = uvicorn.Server(config)
|
||||
self.live = True
|
||||
await self._ctx.Irc.Protocol.send_priv_msg(
|
||||
self._ctx.Config.SERVICE_NICKNAME,
|
||||
"[DEFENDER JSONRPC SERVER] RPC Server started!",
|
||||
self._ctx.Config.SERVICE_CHANLOG
|
||||
)
|
||||
await self.server.serve()
|
||||
self._ctx.Logs.debug("Server is going to shutdown!")
|
||||
else:
|
||||
self._ctx.Logs.debug("Server already running")
|
||||
|
||||
async def stop_server(self):
|
||||
|
||||
if self.server:
|
||||
self.server.should_exit = True
|
||||
await self.server.shutdown()
|
||||
self.live = False
|
||||
self._ctx.Logs.debug("JSON-RPC Server off!")
|
||||
await self._ctx.Irc.Protocol.send_priv_msg(
|
||||
self._ctx.Config.SERVICE_NICKNAME,
|
||||
"[DEFENDER JSONRPC SERVER] RPC Server Stopped!",
|
||||
self._ctx.Config.SERVICE_CHANLOG
|
||||
)
|
||||
|
||||
async def request_handler(self, request: Request) -> JSONResponse:
|
||||
|
||||
request_data: dict = await request.json()
|
||||
method = request_data.get("method", None)
|
||||
params: dict[str, Any] = request_data.get("params", {})
|
||||
|
||||
auth: JSONResponse = self.authenticate(request.headers, request_data)
|
||||
if not json.loads(auth.body).get('result', False):
|
||||
return auth
|
||||
|
||||
response_data = {
|
||||
"jsonrpc": "2.0",
|
||||
"id": request_data.get('id', 123)
|
||||
}
|
||||
|
||||
response_data['method'] = method
|
||||
rip = request.client.host
|
||||
rport = request.client.port
|
||||
http_code = 200
|
||||
|
||||
match method:
|
||||
case 'user.list':
|
||||
user = RPCUser(ProxyLoader)
|
||||
response_data['result'] = user.user_list()
|
||||
logs.debug(f'[RPC] {method} recieved from {rip}:{rport}')
|
||||
del user
|
||||
|
||||
case 'user.get':
|
||||
user = RPCUser(ProxyLoader)
|
||||
uid_or_nickname = params.get('uid_or_nickname', None)
|
||||
response_data['result'] = user.user_get(uid_or_nickname)
|
||||
logs.debug(f'[RPC] {method} recieved from {rip}:{rport}')
|
||||
del user
|
||||
if method in self.methods:
|
||||
response_data['result'] = self.methods[method](**params)
|
||||
return JSONResponse(response_data, http_code)
|
||||
|
||||
case 'channel.list':
|
||||
channel = RPCChannel(ProxyLoader)
|
||||
response_data['result'] = channel.channel_list()
|
||||
logs.debug(f'[RPC] {method} recieved from {rip}:{rport}')
|
||||
del channel
|
||||
response_data['error'] = create_error_response(JSONRPCErrorCode.METHOD_NOT_FOUND)
|
||||
self._ctx.Logs.debug(f'[RPC ERROR] {method} recieved from {rip}:{rport}')
|
||||
http_code = 404
|
||||
return JSONResponse(response_data, http_code)
|
||||
|
||||
case 'command.list':
|
||||
command = RPCCommand(ProxyLoader)
|
||||
response_data['result'] = command.command_list()
|
||||
logs.debug(f'[RPC] {method} recieved from {rip}:{rport}')
|
||||
del command
|
||||
def authenticate(self, headers: dict, body: dict) -> JSONResponse:
|
||||
ok_auth = {
|
||||
'jsonrpc': '2.0',
|
||||
'id': body.get('id', 123),
|
||||
'result': True
|
||||
}
|
||||
|
||||
case 'command.get.by.module':
|
||||
command = RPCCommand(ProxyLoader)
|
||||
module_name = params.get('name', None)
|
||||
response_data['result'] = command.command_get_by_module(module_name)
|
||||
logs.debug(f'[RPC] {method} recieved from {rip}:{rport}')
|
||||
del command
|
||||
|
||||
case 'command.get.by.name':
|
||||
command = RPCCommand(ProxyLoader)
|
||||
command_name = params.get('name', None)
|
||||
response_data['result'] = command.command_get_by_name(command_name)
|
||||
logs.debug(f'[RPC] {method} recieved from {rip}:{rport}')
|
||||
del command
|
||||
|
||||
case _:
|
||||
response_data['error'] = create_error_response(JSONRPCErrorCode.METHOD_NOT_FOUND)
|
||||
logs.debug(f'[RPC ERROR] {method} recieved from {rip}:{rport}')
|
||||
http_code = 404
|
||||
|
||||
self.send_response(http_code)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps(response_data).encode('utf-8'))
|
||||
|
||||
return None
|
||||
|
||||
def do_GET(self):
|
||||
self.server_version = 'Defender6'
|
||||
self.sys_version = ProxyLoader.Config.CURRENT_VERSION
|
||||
content_length = int(self.headers['Content-Length'])
|
||||
body = self.rfile.read(content_length)
|
||||
request_data: dict = json.loads(body)
|
||||
|
||||
if not self.authenticate(request_data):
|
||||
return None
|
||||
|
||||
response_data = {'jsonrpc': '2.0', 'id': request_data.get('id', 321),
|
||||
'error': create_error_response(JSONRPCErrorCode.INVALID_REQUEST)}
|
||||
|
||||
self.send_response(404)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps(response_data).encode('utf-8'))
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def authenticate(self, request_data: dict) -> bool:
|
||||
logs = ProxyLoader.Logs
|
||||
auth = self.headers.get('Authorization', None)
|
||||
if auth is None:
|
||||
self.send_auth_error(request_data)
|
||||
return False
|
||||
logs = self._ctx.Logs
|
||||
auth: str = headers.get('Authorization', '')
|
||||
if not auth:
|
||||
return self.send_auth_error(body)
|
||||
|
||||
# Authorization header format: Basic base64(username:password)
|
||||
auth_type, auth_string = auth.split(' ', 1)
|
||||
if auth_type.lower() != 'basic':
|
||||
self.send_auth_error(request_data)
|
||||
return False
|
||||
return self.send_auth_error(body)
|
||||
|
||||
try:
|
||||
# Decode the base64-encoded username:password
|
||||
@@ -132,70 +116,25 @@ class RPCRequestHandler(BaseHTTPRequestHandler):
|
||||
username, password = decoded_credentials.split(":", 1)
|
||||
|
||||
# Check the username and password.
|
||||
for rpcuser in ProxyLoader.Irc.Config.RPC_USERS:
|
||||
for rpcuser in self._ctx.Config.RPC_USERS:
|
||||
if rpcuser.get('USERNAME', None) == username and rpcuser.get('PASSWORD', None) == password:
|
||||
return True
|
||||
return JSONResponse(ok_auth)
|
||||
|
||||
self.send_auth_error(request_data)
|
||||
return False
|
||||
return self.send_auth_error(body)
|
||||
|
||||
except Exception as e:
|
||||
self.send_auth_error(request_data)
|
||||
logs.error(e)
|
||||
return False
|
||||
return self.send_auth_error(body)
|
||||
|
||||
def send_auth_error(self, request_data: dict) -> None:
|
||||
def send_auth_error(self, request_data: dict) -> JSONResponse:
|
||||
|
||||
response_data = {
|
||||
'jsonrpc': '2.0',
|
||||
'id': request_data.get('id', 123),
|
||||
'error': create_error_response(JSONRPCErrorCode.AUTHENTICATION_ERROR)
|
||||
}
|
||||
return JSONResponse(response_data)
|
||||
|
||||
self.send_response(401)
|
||||
self.send_header('WWW-Authenticate', 'Basic realm="Authorization Required"')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps(response_data).encode('utf-8'))
|
||||
|
||||
class JSONRPCServer:
|
||||
def __init__(self, loader: 'Loader'):
|
||||
global ProxyLoader
|
||||
|
||||
ProxyLoader = loader
|
||||
self._Loader = loader
|
||||
self._Base = loader.Base
|
||||
self._Logs = loader.Logs
|
||||
self.rpc_server: Optional[HTTPServer] = None
|
||||
self.connected: bool = False
|
||||
|
||||
def start_server(self, server_class=HTTPServer, handler_class=RPCRequestHandler, *, hostname: str = 'localhost', port: int = 5000):
|
||||
logging.getLogger('http.server').setLevel(logging.CRITICAL)
|
||||
server_address = (hostname, port)
|
||||
self.rpc_server = server_class(server_address, handler_class)
|
||||
self._Logs.debug(f"Server ready on http://{hostname}:{port}...")
|
||||
self._Base.create_thread(self.thread_start_rpc_server, (), True)
|
||||
|
||||
def thread_start_rpc_server(self) -> None:
|
||||
self._Loader.Irc.Protocol.send_priv_msg(
|
||||
self._Loader.Config.SERVICE_NICKNAME, "Defender RPC Server has started successfuly!", self._Loader.Config.SERVICE_CHANLOG
|
||||
)
|
||||
self.connected = True
|
||||
self.rpc_server.serve_forever()
|
||||
ProxyLoader.Logs.debug(f"RPC Server down!")
|
||||
|
||||
def stop_server(self):
|
||||
self._Base.create_thread(self.thread_stop_rpc_server)
|
||||
|
||||
def thread_stop_rpc_server(self):
|
||||
self.rpc_server.shutdown()
|
||||
ProxyLoader.Logs.debug(f"RPC Server shutdown!")
|
||||
self.rpc_server.server_close()
|
||||
ProxyLoader.Logs.debug(f"RPC Server clean-up!")
|
||||
self._Base.garbage_collector_thread()
|
||||
self._Loader.Irc.Protocol.send_priv_msg(
|
||||
self._Loader.Config.SERVICE_NICKNAME, "Defender RPC Server has stopped successfuly!", self._Loader.Config.SERVICE_CHANLOG
|
||||
)
|
||||
self.connected = False
|
||||
|
||||
class JSONRPCErrorCode(Enum):
|
||||
PARSE_ERROR = -32700 # Syntax error in the request (malformed JSON)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.loader import Loader
|
||||
@@ -8,5 +8,5 @@ class RPCChannel:
|
||||
self._Loader = loader
|
||||
self._Channel = loader.Channel
|
||||
|
||||
def channel_list(self) -> list[dict]:
|
||||
def channel_list(self, **kwargs) -> list[dict]:
|
||||
return [chan.to_dict() for chan in self._Channel.UID_CHANNEL_DB]
|
||||
@@ -8,14 +8,22 @@ class RPCCommand:
|
||||
self._Loader = loader
|
||||
self._Command = loader.Commands
|
||||
|
||||
def command_list(self) -> list[dict]:
|
||||
def command_list(self, **kwargs) -> list[dict]:
|
||||
return [command.to_dict() for command in self._Command.DB_COMMANDS]
|
||||
|
||||
def command_get_by_module(self, module_name: str) -> list[dict]:
|
||||
def command_get_by_module(self, **kwargs) -> list[dict]:
|
||||
module_name = kwargs.get('module_name', None)
|
||||
if module_name is None:
|
||||
return []
|
||||
|
||||
return [command.to_dict() for command in self._Command.DB_COMMANDS if command.module_name.lower() == module_name.lower()]
|
||||
|
||||
def command_get_by_name(self, command_name: str) -> dict:
|
||||
def command_get_by_name(self, **kwargs) -> dict:
|
||||
command_name: str = kwargs.get('command_name', '')
|
||||
if not command_name:
|
||||
return dict()
|
||||
|
||||
for command in self._Command.DB_COMMANDS:
|
||||
if command.command_name.lower() == command_name.lower():
|
||||
return command.to_dict()
|
||||
return {}
|
||||
return dict()
|
||||
@@ -6,11 +6,10 @@ if TYPE_CHECKING:
|
||||
|
||||
class RPCUser:
|
||||
def __init__(self, loader: 'Loader'):
|
||||
self._Loader = loader
|
||||
self._User = loader.User
|
||||
self._ctx = loader
|
||||
|
||||
def user_list(self) -> list[dict]:
|
||||
users = self._User.UID_DB.copy()
|
||||
def user_list(self, **kwargs) -> list[dict]:
|
||||
users = self._ctx.User.UID_DB.copy()
|
||||
copy_users: list['MUser'] = []
|
||||
|
||||
for user in users:
|
||||
@@ -20,8 +19,9 @@ class RPCUser:
|
||||
|
||||
return [user.to_dict() for user in copy_users]
|
||||
|
||||
def user_get(self, uidornickname: str) -> Optional[dict]:
|
||||
user = self._User.get_user(uidornickname)
|
||||
def user_get(self, **kwargs) -> Optional[dict]:
|
||||
uidornickname = kwargs.get('uid_or_nickname', None)
|
||||
user = self._ctx.User.get_user(uidornickname)
|
||||
if user:
|
||||
user_copy = user.copy()
|
||||
user_copy.connexion_datetime = user_copy.connexion_datetime.strftime('%d-%m-%Y')
|
||||
|
||||
@@ -4,30 +4,29 @@ from .inspircd import Inspircd
|
||||
from ..interfaces.iprotocol import IProtocol
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.irc import Irc
|
||||
from core.loader import Loader
|
||||
|
||||
class ProtocolFactorty:
|
||||
|
||||
def __init__(self, uplink: 'Irc'):
|
||||
def __init__(self, context: 'Loader'):
|
||||
"""ProtocolFactory init.
|
||||
|
||||
Args:
|
||||
uplink (Irc): The Irc object
|
||||
context (Loader): The Context object
|
||||
"""
|
||||
self.__Config = uplink.Config
|
||||
self.__uplink = uplink
|
||||
self.__ctx = context
|
||||
|
||||
def get(self) -> Optional[IProtocol]:
|
||||
|
||||
protocol = self.__Config.SERVEUR_PROTOCOL
|
||||
protocol = self.__ctx.Config.SERVEUR_PROTOCOL
|
||||
|
||||
match protocol:
|
||||
case 'unreal6':
|
||||
self.__uplink.Logs.debug(f"[PROTOCOL] {protocol} has been loaded")
|
||||
return Unrealircd6(self.__uplink)
|
||||
self.__ctx.Logs.debug(f"[PROTOCOL] {protocol} has been loaded")
|
||||
return Unrealircd6(self.__ctx)
|
||||
case 'inspircd':
|
||||
self.__uplink.Logs.debug(f"[PROTOCOL] {protocol} has been loaded")
|
||||
return Inspircd(self.__uplink)
|
||||
self.__ctx.Logs.debug(f"[PROTOCOL] {protocol} has been loaded")
|
||||
return Inspircd(self.__ctx)
|
||||
case _:
|
||||
self.__uplink.Logs.critical(f"[PROTOCOL ERROR] This protocol name ({protocol} is not valid!)")
|
||||
self.__ctx.Logs.critical(f"[PROTOCOL ERROR] This protocol name ({protocol} is not valid!)")
|
||||
raise Exception("Unknown protocol!")
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,7 @@ from json import dumps
|
||||
from dataclasses import dataclass, field, asdict, fields, replace
|
||||
from typing import Literal, Any, Optional
|
||||
from os import sep
|
||||
from core.classes.interfaces.imodule import IModule
|
||||
|
||||
@dataclass
|
||||
class MainModel:
|
||||
@@ -354,7 +355,7 @@ class MCommand(MainModel):
|
||||
class MModule(MainModel):
|
||||
module_name: str = None
|
||||
class_name: str = None
|
||||
class_instance: Optional[Any] = None
|
||||
class_instance: Optional[IModule] = None
|
||||
|
||||
@dataclass
|
||||
class DefenderModuleHeader(MainModel):
|
||||
|
||||
726
core/irc.py
726
core/irc.py
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,15 @@ import core.classes.protocols.factory as factory
|
||||
|
||||
class Loader:
|
||||
|
||||
_instance = None
|
||||
|
||||
def __new__(cls, *agrs):
|
||||
|
||||
if cls._instance is None:
|
||||
cls._instance = super().__new__(cls)
|
||||
|
||||
return cls._instance
|
||||
|
||||
def __init__(self):
|
||||
|
||||
# Load Main Modules
|
||||
@@ -70,10 +79,11 @@ class Loader:
|
||||
|
||||
self.Irc: irc.Irc = irc.Irc(self)
|
||||
|
||||
self.PFactory: factory.ProtocolFactorty = factory.ProtocolFactorty(self.Irc)
|
||||
self.PFactory: factory.ProtocolFactorty = factory.ProtocolFactorty(self)
|
||||
|
||||
self.RpcServer: rpc_mod.JSONRPCServer = rpc_mod.JSONRPCServer(self)
|
||||
|
||||
self.Base.init()
|
||||
self.RpcServer: rpc_mod.JSonRpcServer = rpc_mod.JSonRpcServer(self)
|
||||
|
||||
self.Logs.debug(self.Utils.tr("Loader %s success", __name__))
|
||||
|
||||
async def start(self):
|
||||
await self.Base.init()
|
||||
|
||||
@@ -15,7 +15,7 @@ class ServiceLogging:
|
||||
self.SERVER_PREFIX = None
|
||||
self.LOGGING_CONSOLE = True
|
||||
|
||||
self.LOG_FILTERS: list[str] = [f":{self.SERVER_PREFIX}auth", "['PASS'"]
|
||||
self.LOG_FILTERS: list[str] = ["PING", f":{self.SERVER_PREFIX}auth", "['PASS'"]
|
||||
|
||||
self.file_handler = None
|
||||
self.stdout_handler = None
|
||||
|
||||
239
core/module.py
239
core/module.py
@@ -1,9 +1,9 @@
|
||||
'''
|
||||
This is the main operational file to handle modules
|
||||
'''
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import importlib
|
||||
from pathlib import Path
|
||||
from types import ModuleType
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
from core.definition import DefenderModuleHeader, MModule
|
||||
@@ -12,6 +12,7 @@ from core.utils import tr
|
||||
if TYPE_CHECKING:
|
||||
from core.loader import Loader
|
||||
from core.irc import Irc
|
||||
from core.classes.interfaces.imodule import IModule
|
||||
|
||||
class Module:
|
||||
|
||||
@@ -19,11 +20,7 @@ class Module:
|
||||
DB_MODULE_HEADERS: list[DefenderModuleHeader] = []
|
||||
|
||||
def __init__(self, loader: 'Loader') -> None:
|
||||
self.__Loader = loader
|
||||
self.__Base = loader.Base
|
||||
self.__Logs = loader.Logs
|
||||
self.__Utils = loader.Utils
|
||||
self.__Config = loader.Config
|
||||
self._ctx = loader
|
||||
|
||||
def get_all_available_modules(self) -> list[str]:
|
||||
"""Get list of all main modules
|
||||
@@ -34,7 +31,7 @@ class Module:
|
||||
"""
|
||||
base_path = Path('mods')
|
||||
modules_available = [file.name.replace('.py', '') for file in base_path.rglob('mod_*.py')]
|
||||
self.__Logs.debug(f"Modules available: {modules_available}")
|
||||
self._ctx.Logs.debug(f"Modules available: {modules_available}")
|
||||
return modules_available
|
||||
|
||||
def get_module_information(self, module_name: str) -> tuple[Optional[str], Optional[str], Optional[str]]:
|
||||
@@ -45,14 +42,14 @@ class Module:
|
||||
module_name = module_name.lower() # --> mod_defender
|
||||
module_folder = module_name.split('_')[1].lower() # --> defender
|
||||
class_name = module_name.split('_')[1].capitalize() # --> Defender
|
||||
self.__Logs.debug(f"Module information Folder: {module_folder}, Name: {module_name}, Class: {class_name}")
|
||||
self._ctx.Logs.debug(f"Module information Folder: {module_folder}, Name: {module_name}, Class: {class_name}")
|
||||
return module_folder, module_name, class_name
|
||||
|
||||
def get_module_header(self, module_name: str) -> Optional[DefenderModuleHeader]:
|
||||
|
||||
for mod_h in self.DB_MODULE_HEADERS:
|
||||
if module_name.lower() == mod_h.name.lower():
|
||||
self.__Logs.debug(f"Module Header found: {mod_h}")
|
||||
self._ctx.Logs.debug(f"Module Header found: {mod_h}")
|
||||
return mod_h
|
||||
|
||||
return None
|
||||
@@ -68,7 +65,7 @@ class Module:
|
||||
"""
|
||||
mod_header = DefenderModuleHeader(**module_header)
|
||||
if self.get_module_header(mod_header.name) is None:
|
||||
self.__Logs.debug(f"[MOD_HEADER] The module header has been created! ({mod_header.name} v{mod_header.version})")
|
||||
self._ctx.Logs.debug(f"[MOD_HEADER] The module header has been created! ({mod_header.name} v{mod_header.version})")
|
||||
self.DB_MODULE_HEADERS.append(mod_header)
|
||||
return True
|
||||
|
||||
@@ -77,73 +74,74 @@ class Module:
|
||||
def delete_module_header(self, module_name: str) -> bool:
|
||||
mod_header = self.get_module_header(module_name)
|
||||
if mod_header is not None:
|
||||
self.__Logs.debug(f"[MOD_HEADER] The module header has been deleted ({mod_header.name} v{mod_header.version})")
|
||||
self._ctx.Logs.debug(f"[MOD_HEADER] The module header has been deleted ({mod_header.name} v{mod_header.version})")
|
||||
self.DB_MODULE_HEADERS.remove(mod_header)
|
||||
return True
|
||||
|
||||
self.__Logs.debug(f"[MOD_HEADER ERROR] Impossible to remove the module header ({module_name})")
|
||||
self._ctx.Logs.debug(f"[MOD_HEADER ERROR] Impossible to remove the module header ({module_name})")
|
||||
return False
|
||||
|
||||
async def load_one_module(self, uplink: 'Irc', module_name: str, nickname: str, is_default: bool = False) -> bool:
|
||||
async def load_one_module(self, module_name: str, nickname: str, is_default: bool = False) -> bool:
|
||||
|
||||
module_folder, module_name, class_name = self.get_module_information(module_name)
|
||||
|
||||
if module_folder is None or module_name is None or class_name is None:
|
||||
self.__Logs.error(f"There is an error with the module name! {module_folder}, {module_name}, {class_name}")
|
||||
self._ctx.Logs.error(f"There is an error with the module name! {module_folder}, {module_name}, {class_name}")
|
||||
return False
|
||||
|
||||
if self.is_module_exist_in_sys_module(module_name):
|
||||
self.__Logs.debug(f"Module [{module_folder}.{module_name}] already loaded!")
|
||||
self._ctx.Logs.debug(f"Module [{module_folder}.{module_name}] already loaded!")
|
||||
if self.model_is_module_exist(module_name):
|
||||
# Si le module existe dans la variable globale retourne False
|
||||
self.__Logs.debug(f"Module [{module_folder}.{module_name}] exist in the local variable!")
|
||||
await uplink.Protocol.send_priv_msg(
|
||||
nick_from=self.__Config.SERVICE_NICKNAME,
|
||||
msg=f"Le module {module_name} est déja chargé ! si vous souhaiter le recharge tapez {self.__Config.SERVICE_PREFIX}reload {module_name}",
|
||||
channel=self.__Config.SERVICE_CHANLOG
|
||||
self._ctx.Logs.debug(f"Module [{module_folder}.{module_name}] exist in the local variable!")
|
||||
await self._ctx.Irc.Protocol.send_priv_msg(
|
||||
nick_from=self._ctx.Config.SERVICE_NICKNAME,
|
||||
msg=f"Le module {module_name} est déja chargé ! si vous souhaiter le recharge tapez {self._ctx.Config.SERVICE_PREFIX}reload {module_name}",
|
||||
channel=self._ctx.Config.SERVICE_CHANLOG
|
||||
)
|
||||
return False
|
||||
|
||||
return self.reload_one_module(uplink, module_name, nickname)
|
||||
return self.reload_one_module(module_name, nickname)
|
||||
|
||||
# Charger le module
|
||||
try:
|
||||
loaded_module = importlib.import_module(f'mods.{module_folder}.{module_name}')
|
||||
my_class = getattr(loaded_module, class_name, None) # Récuperer le nom de classe
|
||||
create_instance_of_the_class = my_class(uplink.Loader) # Créer une nouvelle instance de la classe
|
||||
create_instance_of_the_class: 'IModule' = my_class(self._ctx) # Créer une nouvelle instance de la classe
|
||||
await create_instance_of_the_class.load() if self._ctx.Utils.is_coroutinefunction(create_instance_of_the_class.load) else create_instance_of_the_class.load()
|
||||
self.create_module_header(create_instance_of_the_class.MOD_HEADER)
|
||||
except AttributeError as attr:
|
||||
red = uplink.Config.COLORS.red
|
||||
nogc = uplink.Config.COLORS.nogc
|
||||
await uplink.Protocol.send_priv_msg(
|
||||
nick_from=self.__Config.SERVICE_NICKNAME,
|
||||
red = self._ctx.Config.COLORS.red
|
||||
nogc = self._ctx.Config.COLORS.red
|
||||
await self._ctx.Irc.Protocol.send_priv_msg(
|
||||
nick_from=self._ctx.Config.SERVICE_NICKNAME,
|
||||
msg=tr("[%sMODULE ERROR%s] Module %s is facing issues! %s", red, nogc, module_name, attr),
|
||||
channel=self.__Config.SERVICE_CHANLOG
|
||||
channel=self._ctx.Config.SERVICE_CHANLOG
|
||||
)
|
||||
self.__Logs.error(msg=attr, exc_info=True)
|
||||
self._ctx.Logs.error(msg=attr, exc_info=True)
|
||||
return False
|
||||
|
||||
if not hasattr(create_instance_of_the_class, 'cmd'):
|
||||
await uplink.Protocol.send_priv_msg(
|
||||
nick_from=self.__Config.SERVICE_NICKNAME,
|
||||
await self._ctx.Irc.Protocol.send_priv_msg(
|
||||
nick_from=self._ctx.Config.SERVICE_NICKNAME,
|
||||
msg=tr("cmd method is not available in the module (%s)", module_name),
|
||||
channel=self.__Config.SERVICE_CHANLOG
|
||||
channel=self._ctx.Config.SERVICE_CHANLOG
|
||||
)
|
||||
self.__Logs.critical(f"The Module {module_name} has not been loaded because cmd method is not available")
|
||||
self.db_delete_module(module_name)
|
||||
self._ctx.Logs.critical(f"The Module {module_name} has not been loaded because cmd method is not available")
|
||||
await self.db_delete_module(module_name)
|
||||
return False
|
||||
|
||||
# Charger la nouvelle class dans la variable globale
|
||||
if self.model_insert_module(MModule(module_name, class_name, create_instance_of_the_class)):
|
||||
# Enregistrer le module dans la base de données
|
||||
self.db_register_module(module_name, nickname, is_default)
|
||||
await uplink.Protocol.send_priv_msg(
|
||||
nick_from=self.__Config.SERVICE_NICKNAME,
|
||||
await self.db_register_module(module_name, nickname, is_default)
|
||||
await self._ctx.Irc.Protocol.send_priv_msg(
|
||||
nick_from=self._ctx.Config.SERVICE_NICKNAME,
|
||||
msg=tr("Module %s loaded!", module_name),
|
||||
channel=self.__Config.SERVICE_CHANLOG
|
||||
channel=self._ctx.Config.SERVICE_CHANLOG
|
||||
)
|
||||
|
||||
self.__Logs.debug(f"Module {class_name} has been loaded")
|
||||
self._ctx.Logs.debug(f"Module {class_name} has been loaded")
|
||||
return True
|
||||
|
||||
return False
|
||||
@@ -151,7 +149,7 @@ class Module:
|
||||
def load_all_modules(self) -> bool:
|
||||
...
|
||||
|
||||
async def reload_one_module(self, uplink: 'Irc', module_name: str, nickname: str) -> bool:
|
||||
async def reload_one_module(self, module_name: str, nickname: str) -> bool:
|
||||
"""Reloading one module and insert it into the model as well as the database
|
||||
|
||||
Args:
|
||||
@@ -163,21 +161,21 @@ class Module:
|
||||
bool: True if the module has been reloaded
|
||||
"""
|
||||
module_folder, module_name, class_name = self.get_module_information(module_name)
|
||||
red = self.__Config.COLORS.red
|
||||
nogc = self.__Config.COLORS.nogc
|
||||
red = self._ctx.Config.COLORS.red
|
||||
nogc = self._ctx.Config.COLORS.nogc
|
||||
try:
|
||||
if self.is_module_exist_in_sys_module(module_name):
|
||||
module_model = self.model_get_module(module_name)
|
||||
if module_model:
|
||||
self.delete_module_header(module_model.class_instance.MOD_HEADER['name'])
|
||||
module_model.class_instance.unload()
|
||||
await module_model.class_instance.unload() if self._ctx.Utils.is_coroutinefunction(module_model.class_instance.unload) else module_model.class_instance.unload()
|
||||
else:
|
||||
await uplink.Protocol.send_priv_msg(
|
||||
nick_from=self.__Config.SERVICE_NICKNAME,
|
||||
msg=f"[ {red}RELOAD MODULE ERROR{nogc} ] Module [{module_folder}.{module_name}] hasn't been reloaded! You must use {self.__Config.SERVICE_PREFIX}load {module_name}",
|
||||
channel=self.__Config.SERVICE_CHANLOG
|
||||
await self._ctx.Irc.Protocol.send_priv_msg(
|
||||
nick_from=self._ctx.Config.SERVICE_NICKNAME,
|
||||
msg=f"[ {red}RELOAD MODULE ERROR{nogc} ] Module [{module_folder}.{module_name}] hasn't been reloaded! You must use {self._ctx.Config.SERVICE_PREFIX}load {module_name}",
|
||||
channel=self._ctx.Config.SERVICE_CHANLOG
|
||||
)
|
||||
self.__Logs.debug(f"Module [{module_folder}.{module_name}] not found! Please use {self.__Config.SERVICE_PREFIX}load {module_name}")
|
||||
self._ctx.Logs.debug(f"Module [{module_folder}.{module_name}] not found! Please use {self._ctx.Config.SERVICE_PREFIX}load {module_name}")
|
||||
return False
|
||||
|
||||
# reload module dependencies
|
||||
@@ -186,37 +184,38 @@ class Module:
|
||||
the_module = sys.modules[f'mods.{module_folder}.{module_name}']
|
||||
importlib.reload(the_module)
|
||||
my_class = getattr(the_module, class_name, None)
|
||||
new_instance = my_class(uplink.Loader)
|
||||
new_instance: 'IModule' = my_class(self._ctx)
|
||||
await new_instance.load() if self._ctx.Utils.is_coroutinefunction(new_instance.load) else new_instance.load()
|
||||
self.create_module_header(new_instance.MOD_HEADER)
|
||||
module_model.class_instance = new_instance
|
||||
|
||||
# Créer le module dans la base de données
|
||||
self.db_register_module(module_name, nickname)
|
||||
await uplink.Protocol.send_priv_msg(
|
||||
nick_from=self.__Config.SERVICE_NICKNAME,
|
||||
await self.db_register_module(module_name, nickname)
|
||||
await self._ctx.Irc.Protocol.send_priv_msg(
|
||||
nick_from=self._ctx.Config.SERVICE_NICKNAME,
|
||||
msg=f"Module [{module_folder}.{module_name}] has been reloaded!",
|
||||
channel=self.__Config.SERVICE_CHANLOG
|
||||
channel=self._ctx.Config.SERVICE_CHANLOG
|
||||
)
|
||||
self.__Logs.debug(f"Module [{module_folder}.{module_name}] reloaded!")
|
||||
self._ctx.Logs.debug(f"Module [{module_folder}.{module_name}] reloaded!")
|
||||
return True
|
||||
else:
|
||||
# Module is not loaded! Nothing to reload
|
||||
self.__Logs.debug(f"[RELOAD MODULE ERROR] [{module_folder}.{module_name}] is not loaded! You must use {self.__Config.SERVICE_PREFIX}load {module_name}")
|
||||
await uplink.Protocol.send_priv_msg(
|
||||
nick_from=self.__Config.SERVICE_NICKNAME,
|
||||
msg=f"[ {red}RELOAD MODULE ERROR{nogc} ] Module [{module_folder}.{module_name}] is not loaded! You must use {self.__Config.SERVICE_PREFIX}load {module_name}",
|
||||
channel=self.__Config.SERVICE_CHANLOG
|
||||
self._ctx.Logs.debug(f"[RELOAD MODULE ERROR] [{module_folder}.{module_name}] is not loaded! You must use {self._ctx.Config.SERVICE_PREFIX}load {module_name}")
|
||||
await self._ctx.Irc.Protocol.send_priv_msg(
|
||||
nick_from=self._ctx.Config.SERVICE_NICKNAME,
|
||||
msg=f"[ {red}RELOAD MODULE ERROR{nogc} ] Module [{module_folder}.{module_name}] is not loaded! You must use {self._ctx.Config.SERVICE_PREFIX}load {module_name}",
|
||||
channel=self._ctx.Config.SERVICE_CHANLOG
|
||||
)
|
||||
return False
|
||||
|
||||
except (TypeError, AttributeError, KeyError, Exception) as err:
|
||||
self.__Logs.error(f"[RELOAD MODULE ERROR]: {err}", exc_info=True)
|
||||
await uplink.Protocol.send_priv_msg(
|
||||
nick_from=self.__Config.SERVICE_NICKNAME,
|
||||
self._ctx.Logs.error(f"[RELOAD MODULE ERROR]: {err}", exc_info=True)
|
||||
await self._ctx.Irc.Protocol.send_priv_msg(
|
||||
nick_from=self._ctx.Config.SERVICE_NICKNAME,
|
||||
msg=f"[RELOAD MODULE ERROR]: {err}",
|
||||
channel=self.__Config.SERVICE_CHANLOG
|
||||
channel=self._ctx.Config.SERVICE_CHANLOG
|
||||
)
|
||||
self.db_delete_module(module_name)
|
||||
await self.db_delete_module(module_name)
|
||||
|
||||
def reload_all_modules(self) -> bool:
|
||||
...
|
||||
@@ -242,12 +241,12 @@ class Module:
|
||||
try:
|
||||
if 'mod_' not in name and 'schemas' not in name:
|
||||
importlib.reload(module)
|
||||
self.__Logs.debug(f'[LOAD_MODULE] Module {module} success')
|
||||
self._ctx.Logs.debug(f'[LOAD_MODULE] Module {module} success')
|
||||
|
||||
except Exception as err:
|
||||
self.__Logs.error(f'[LOAD_MODULE] Module {module} failed [!] - {err}')
|
||||
self._ctx.Logs.error(f'[LOAD_MODULE] Module {module} failed [!] - {err}')
|
||||
|
||||
def unload_one_module(self, uplink: 'Irc', module_name: str, keep_in_db: bool = True) -> bool:
|
||||
async def unload_one_module(self, module_name: str, keep_in_db: bool = True) -> bool:
|
||||
"""Unload a module
|
||||
|
||||
Args:
|
||||
@@ -260,23 +259,23 @@ class Module:
|
||||
"""
|
||||
try:
|
||||
# Le nom du module. exemple: mod_defender
|
||||
red = self.__Config.COLORS.red
|
||||
nogc = self.__Config.COLORS.nogc
|
||||
red = self._ctx.Config.COLORS.red
|
||||
nogc = self._ctx.Config.COLORS.nogc
|
||||
module_folder, module_name, class_name = self.get_module_information(module_name)
|
||||
module = self.model_get_module(module_name)
|
||||
if module is None:
|
||||
self.__Logs.debug(f"[ UNLOAD MODULE ERROR ] This module {module_name} is not loaded!")
|
||||
self.db_delete_module(module_name)
|
||||
uplink.Protocol.send_priv_msg(
|
||||
nick_from=self.__Config.SERVICE_NICKNAME,
|
||||
self._ctx.Logs.debug(f"[ UNLOAD MODULE ERROR ] This module {module_name} is not loaded!")
|
||||
await self.db_delete_module(module_name)
|
||||
await self._ctx.Irc.Protocol.send_priv_msg(
|
||||
nick_from=self._ctx.Config.SERVICE_NICKNAME,
|
||||
msg=f"[ {red}UNLOAD MODULE ERROR{nogc} ] This module {module_name} is not loaded!",
|
||||
channel=self.__Config.SERVICE_CHANLOG
|
||||
channel=self._ctx.Config.SERVICE_CHANLOG
|
||||
)
|
||||
return False
|
||||
|
||||
if module:
|
||||
self.delete_module_header(module.class_instance.MOD_HEADER['name'])
|
||||
module.class_instance.unload()
|
||||
await module.class_instance.unload() if self._ctx.Utils.is_coroutinefunction(module.class_instance.unload) else module.class_instance.unload()
|
||||
self.DB_MODULES.remove(module)
|
||||
|
||||
# Delete from the sys.modules.
|
||||
@@ -284,25 +283,25 @@ class Module:
|
||||
del sys.modules[f"mods.{module_folder}.{module_name}"]
|
||||
|
||||
if sys.modules.get(f'mods.{module_folder}.{module_name}'):
|
||||
self.__Logs.debug(f"Module mods.{module_folder}.{module_name} still in the sys.modules")
|
||||
self._ctx.Logs.debug(f"Module mods.{module_folder}.{module_name} still in the sys.modules")
|
||||
|
||||
# Supprimer le module de la base de données
|
||||
if not keep_in_db:
|
||||
self.db_delete_module(module_name)
|
||||
await self.db_delete_module(module_name)
|
||||
|
||||
uplink.Protocol.send_priv_msg(
|
||||
nick_from=self.__Config.SERVICE_NICKNAME,
|
||||
await self._ctx.Irc.Protocol.send_priv_msg(
|
||||
nick_from=self._ctx.Config.SERVICE_NICKNAME,
|
||||
msg=f"[ UNLOAD MODULE INFO ] Module {module_name} has been unloaded!",
|
||||
channel=self.__Config.SERVICE_CHANLOG
|
||||
channel=self._ctx.Config.SERVICE_CHANLOG
|
||||
)
|
||||
self.__Logs.debug(f"[ UNLOAD MODULE ] {module_name} has been unloaded!")
|
||||
self._ctx.Logs.debug(f"[ UNLOAD MODULE ] {module_name} has been unloaded!")
|
||||
return True
|
||||
|
||||
self.__Logs.debug(f"[UNLOAD MODULE]: Module {module_name} not found in DB_MODULES variable!")
|
||||
self._ctx.Logs.debug(f"[UNLOAD MODULE]: Module {module_name} not found in DB_MODULES variable!")
|
||||
return False
|
||||
|
||||
except Exception as err:
|
||||
self.__Logs.error(f"General Error: {err}", exc_info=True)
|
||||
self._ctx.Logs.error(f"General Error: {err}", exc_info=True)
|
||||
return False
|
||||
|
||||
def unload_all_modules(self) -> bool:
|
||||
@@ -319,9 +318,9 @@ class Module:
|
||||
"""
|
||||
module_folder, module_name, class_name = self.get_module_information(module_name)
|
||||
if "mods." + module_folder + "." + module_name in sys.modules:
|
||||
self.__Logs.debug(f"[SYS MODULE] (mods.{module_folder}.{module_name}) found in sys.modules")
|
||||
self._ctx.Logs.debug(f"[SYS MODULE] (mods.{module_folder}.{module_name}) found in sys.modules")
|
||||
return True
|
||||
self.__Logs.debug(f"[SYS MODULE] (mods.{module_folder}.{module_name}) not found in sys.modules")
|
||||
self._ctx.Logs.debug(f"[SYS MODULE] (mods.{module_folder}.{module_name}) not found in sys.modules")
|
||||
return False
|
||||
|
||||
'''
|
||||
@@ -338,10 +337,10 @@ class Module:
|
||||
"""
|
||||
for module in self.DB_MODULES:
|
||||
if module.module_name.lower() == module_name.lower():
|
||||
self.__Logs.debug(f"[MODEL MODULE GET] The module {module_name} has been found in the model DB_MODULES")
|
||||
self._ctx.Logs.debug(f"[MODEL MODULE GET] The module {module_name} has been found in the model DB_MODULES")
|
||||
return module
|
||||
|
||||
self.__Logs.debug(f"[MODEL MODULE GET] The module {module_name} not found in the model DB_MODULES")
|
||||
self._ctx.Logs.debug(f"[MODEL MODULE GET] The module {module_name} not found in the model DB_MODULES")
|
||||
return None
|
||||
|
||||
def model_get_loaded_modules(self) -> list[MModule]:
|
||||
@@ -351,7 +350,7 @@ class Module:
|
||||
Returns:
|
||||
list[MModule]: A list of module model object
|
||||
"""
|
||||
# self.__Logs.debug(f"[MODEL MODULE LOADED MODULES] {len(self.DB_MODULES)} modules found!")
|
||||
# self._ctx.Logs.debug(f"[MODEL MODULE LOADED MODULES] {len(self.DB_MODULES)} modules found!")
|
||||
return self.DB_MODULES
|
||||
|
||||
def model_insert_module(self, module_model: MModule) -> bool:
|
||||
@@ -366,17 +365,17 @@ class Module:
|
||||
module = self.model_get_module(module_model.module_name)
|
||||
if module is None:
|
||||
self.DB_MODULES.append(module_model)
|
||||
self.__Logs.debug(f"[MODEL MODULE INSERT] The module {module_model.module_name} has been inserted in the local variable model DB_MODULES")
|
||||
self._ctx.Logs.debug(f"[MODEL MODULE INSERT] The module {module_model.module_name} has been inserted in the local variable model DB_MODULES")
|
||||
return True
|
||||
|
||||
self.__Logs.debug(f"[MODEL MODULE INSERT] The module {module_model.module_name} already exist in the local variable model DB_MODULES")
|
||||
self._ctx.Logs.debug(f"[MODEL MODULE INSERT] The module {module_model.module_name} already exist in the local variable model DB_MODULES")
|
||||
return False
|
||||
|
||||
def model_clear(self) -> None:
|
||||
"""Clear DB_MODULES list!
|
||||
"""
|
||||
self.DB_MODULES.clear()
|
||||
self.__Logs.debug("[MODEL MODULE CLEAR] The local variable model DB_MODULES has been cleared")
|
||||
self._ctx.Logs.debug("[MODEL MODULE CLEAR] The local variable model DB_MODULES has been cleared")
|
||||
return None
|
||||
|
||||
def model_is_module_exist(self, module_name: str) -> bool:
|
||||
@@ -389,30 +388,30 @@ class Module:
|
||||
bool: True if the module_name exist
|
||||
"""
|
||||
if self.model_get_module(module_name):
|
||||
self.__Logs.debug(f"[MODEL MODULE EXIST] The module {module_name} exist in the local model DB_MODULES!")
|
||||
self._ctx.Logs.debug(f"[MODEL MODULE EXIST] The module {module_name} exist in the local model DB_MODULES!")
|
||||
return True
|
||||
|
||||
self.__Logs.debug(f"[MODEL MODULE EXIST] The module {module_name} is not available in the local model DB_MODULES!")
|
||||
self._ctx.Logs.debug(f"[MODEL MODULE EXIST] The module {module_name} is not available in the local model DB_MODULES!")
|
||||
return False
|
||||
|
||||
'''
|
||||
OPERATION DEDICATED TO DATABASE MANAGEMENT
|
||||
'''
|
||||
|
||||
async def db_load_all_existing_modules(self, uplink: 'Irc') -> bool:
|
||||
async def db_load_all_existing_modules(self) -> bool:
|
||||
"""Charge les modules qui existe déja dans la base de données
|
||||
|
||||
Returns:
|
||||
None: Aucun retour requis, elle charge puis c'est tout
|
||||
"""
|
||||
self.__Logs.debug("[DB LOAD MODULE] Loading modules from the database!")
|
||||
result = self.__Base.db_execute_query(f"SELECT module_name FROM {self.__Config.TABLE_MODULE}")
|
||||
self._ctx.Logs.debug("[DB LOAD MODULE] Loading modules from the database!")
|
||||
result = await self._ctx.Base.db_execute_query(f"SELECT module_name FROM {self._ctx.Config.TABLE_MODULE}")
|
||||
for r in result.fetchall():
|
||||
await self.load_one_module(uplink, r[0], 'sys', True)
|
||||
await self.load_one_module(r[0], 'sys', True)
|
||||
|
||||
return True
|
||||
|
||||
def db_is_module_exist(self, module_name: str) -> bool:
|
||||
async def db_is_module_exist(self, module_name: str) -> bool:
|
||||
"""Check if the module exist in the database
|
||||
|
||||
Args:
|
||||
@@ -421,18 +420,18 @@ class Module:
|
||||
Returns:
|
||||
bool: True if the module exist in the database
|
||||
"""
|
||||
query = f"SELECT id FROM {self.__Config.TABLE_MODULE} WHERE module_name = :module_name"
|
||||
query = f"SELECT id FROM {self._ctx.Config.TABLE_MODULE} WHERE module_name = :module_name"
|
||||
mes_donnes = {'module_name': module_name.lower()}
|
||||
results = self.__Base.db_execute_query(query, mes_donnes)
|
||||
results = await self._ctx.Base.db_execute_query(query, mes_donnes)
|
||||
|
||||
if results.fetchall():
|
||||
self.__Logs.debug(f"[DB MODULE EXIST] The module {module_name} exist in the database!")
|
||||
self._ctx.Logs.debug(f"[DB MODULE EXIST] The module {module_name} exist in the database!")
|
||||
return True
|
||||
else:
|
||||
self.__Logs.debug(f"[DB MODULE EXIST] The module {module_name} is not available in the database!")
|
||||
self._ctx.Logs.debug(f"[DB MODULE EXIST] The module {module_name} is not available in the database!")
|
||||
return False
|
||||
|
||||
def db_register_module(self, module_name: str, nickname: str, is_default: bool = False) -> bool:
|
||||
async def db_register_module(self, module_name: str, nickname: str, is_default: bool = False) -> bool:
|
||||
"""Insert a new module in the database
|
||||
|
||||
Args:
|
||||
@@ -440,49 +439,49 @@ class Module:
|
||||
nickname (str): The user who loaded the module
|
||||
isdefault (int): Is this a default module. Default 0
|
||||
"""
|
||||
if not self.db_is_module_exist(module_name):
|
||||
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.__Utils.get_sdatetime(), 'user': nickname, 'module_name': module_name.lower(), 'isdefault': is_default}
|
||||
insert = self.__Base.db_execute_query(insert_cmd_query, mes_donnees)
|
||||
if not await self.db_is_module_exist(module_name):
|
||||
insert_cmd_query = f"INSERT INTO {self._ctx.Config.TABLE_MODULE} (datetime, user, module_name, isdefault) VALUES (:datetime, :user, :module_name, :isdefault)"
|
||||
mes_donnees = {'datetime': self._ctx.Utils.get_sdatetime(), 'user': nickname, 'module_name': module_name.lower(), 'isdefault': is_default}
|
||||
insert = await self._ctx.Base.db_execute_query(insert_cmd_query, mes_donnees)
|
||||
if insert.rowcount > 0:
|
||||
self.__Logs.debug(f"[DB REGISTER MODULE] Module {module_name} has been inserted to the database!")
|
||||
self._ctx.Logs.debug(f"[DB REGISTER MODULE] Module {module_name} has been inserted to the database!")
|
||||
return True
|
||||
else:
|
||||
self.__Logs.debug(f"[DB REGISTER MODULE] Module {module_name} not inserted to the database!")
|
||||
self._ctx.Logs.debug(f"[DB REGISTER MODULE] Module {module_name} not inserted to the database!")
|
||||
return False
|
||||
|
||||
self.__Logs.debug(f"[DB REGISTER MODULE] Module {module_name} already exist in the database! Nothing to insert!")
|
||||
self._ctx.Logs.debug(f"[DB REGISTER MODULE] Module {module_name} already exist in the database! Nothing to insert!")
|
||||
return False
|
||||
|
||||
def db_update_module(self, module_name: str, nickname: str) -> None:
|
||||
async def db_update_module(self, module_name: str, nickname: str) -> None:
|
||||
"""Update the datetime and the user that updated the module
|
||||
|
||||
Args:
|
||||
module_name (str): The module name to update
|
||||
nickname (str): The nickname who updated the module
|
||||
"""
|
||||
update_cmd_query = f"UPDATE {self.__Config.TABLE_MODULE} SET datetime = :datetime, LOWER(user) = :user WHERE LOWER(module_name) = :module_name"
|
||||
mes_donnees = {'datetime': self.__Utils.get_sdatetime(), 'user': nickname.lower(), 'module_name': module_name.lower()}
|
||||
result = self.__Base.db_execute_query(update_cmd_query, mes_donnees)
|
||||
update_cmd_query = f"UPDATE {self._ctx.Config.TABLE_MODULE} SET datetime = :datetime, LOWER(user) = :user WHERE LOWER(module_name) = :module_name"
|
||||
mes_donnees = {'datetime': self._ctx.Utils.get_sdatetime(), 'user': nickname.lower(), 'module_name': module_name.lower()}
|
||||
result = await self._ctx.Base.db_execute_query(update_cmd_query, mes_donnees)
|
||||
if result.rowcount > 0:
|
||||
self.__Logs.debug(f"[DB UPDATE MODULE] Module {module_name} has been updated!")
|
||||
self._ctx.Logs.debug(f"[DB UPDATE MODULE] Module {module_name} has been updated!")
|
||||
return True
|
||||
else:
|
||||
self.__Logs.debug(f"[DB UPDATE MODULE] Module {module_name} not found! Nothing to update!")
|
||||
self._ctx.Logs.debug(f"[DB UPDATE MODULE] Module {module_name} not found! Nothing to update!")
|
||||
return False
|
||||
|
||||
def db_delete_module(self, module_name:str) -> None:
|
||||
async def db_delete_module(self, module_name:str) -> None:
|
||||
"""Delete a module from the database
|
||||
|
||||
Args:
|
||||
module_name (str): The module name you want to delete
|
||||
"""
|
||||
insert_cmd_query = f"DELETE FROM {self.__Config.TABLE_MODULE} WHERE LOWER(module_name) = :module_name"
|
||||
insert_cmd_query = f"DELETE FROM {self._ctx.Config.TABLE_MODULE} WHERE LOWER(module_name) = :module_name"
|
||||
mes_donnees = {'module_name': module_name.lower()}
|
||||
delete = self.__Base.db_execute_query(insert_cmd_query, mes_donnees)
|
||||
delete = await self._ctx.Base.db_execute_query(insert_cmd_query, mes_donnees)
|
||||
if delete.rowcount > 0:
|
||||
self.__Logs.debug(f"[DB MODULE DELETE] The module {module_name} has been deleted from the dabatase!")
|
||||
self._ctx.Logs.debug(f"[DB MODULE DELETE] The module {module_name} has been deleted from the dabatase!")
|
||||
return True
|
||||
|
||||
self.__Logs.debug(f"[DB MODULE DELETE] The module {module_name} is not available in the database! Nothing to delete!")
|
||||
self._ctx.Logs.debug(f"[DB MODULE DELETE] The module {module_name} is not available in the database! Nothing to delete!")
|
||||
return False
|
||||
|
||||
@@ -13,6 +13,7 @@ from time import time
|
||||
from random import choice
|
||||
from hashlib import md5, sha3_512
|
||||
from core.classes.modules.settings import global_settings
|
||||
from asyncio import iscoroutinefunction
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.irc import Irc
|
||||
@@ -243,3 +244,14 @@ def hide_sensitive_data(srvmsg: list[str]) -> list[str]:
|
||||
|
||||
except ValueError:
|
||||
return srvmsg
|
||||
|
||||
def is_coroutinefunction(func: Any) -> bool:
|
||||
"""Check if the function is a coroutine or not
|
||||
|
||||
Args:
|
||||
func (Any): an callable object
|
||||
|
||||
Returns:
|
||||
bool: True if the function is a coroutine
|
||||
"""
|
||||
return iscoroutinefunction(func)
|
||||
@@ -13,6 +13,7 @@ from core import install
|
||||
async def main():
|
||||
from core.loader import Loader
|
||||
loader = Loader()
|
||||
await loader.start()
|
||||
await loader.Irc.run()
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -10,7 +10,7 @@ class CloneManager:
|
||||
|
||||
def __init__(self, uplink: 'Clone'):
|
||||
|
||||
self.Logs = uplink.Logs
|
||||
self.Logs = uplink.ctx.Logs
|
||||
|
||||
def insert(self, new_clone_object: MClone) -> bool:
|
||||
"""Create new Clone object
|
||||
|
||||
@@ -8,6 +8,7 @@ from mods.clone.clone_manager import CloneManager
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from faker import Faker
|
||||
from core.loader import Loader
|
||||
|
||||
class Clone(IModule):
|
||||
|
||||
@@ -23,7 +24,15 @@ class Clone(IModule):
|
||||
'core_version':'Defender-6'
|
||||
}
|
||||
|
||||
def create_tables(self) -> None:
|
||||
def __init__(self, context: 'Loader') -> None:
|
||||
super().__init__(context)
|
||||
self._mod_config: Optional[schemas.ModConfModel] = None
|
||||
|
||||
@property
|
||||
def mod_config(self) -> ModConfModel:
|
||||
return self._mod_config
|
||||
|
||||
async 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
|
||||
|
||||
@@ -39,63 +48,69 @@ class Clone(IModule):
|
||||
)
|
||||
'''
|
||||
|
||||
# self.Base.db_execute_query(table_channel)
|
||||
# await self.ctx.Base.db_execute_query(table_channel)
|
||||
|
||||
return None
|
||||
|
||||
def load(self) -> None:
|
||||
self.ModConfig = self.ModConfModel()
|
||||
async def load(self) -> None:
|
||||
|
||||
# Variable qui va contenir les options de configuration du module Defender
|
||||
self._mod_config: schemas.ModConfModel = self.ModConfModel()
|
||||
|
||||
# sync the database with local variable (Mandatory)
|
||||
await self.sync_db()
|
||||
|
||||
self.stop = False
|
||||
self.Schemas = schemas
|
||||
self.Utils = utils
|
||||
self.Threads = thds
|
||||
self.Faker: Optional['Faker'] = self.Utils.create_faker_object('en_GB')
|
||||
self.Clone = CloneManager(self)
|
||||
metadata = self.Settings.get_cache('UID_CLONE_DB')
|
||||
metadata = self.ctx.Settings.get_cache('UID_CLONE_DB')
|
||||
|
||||
if metadata is not None:
|
||||
self.Clone.UID_CLONE_DB = metadata
|
||||
self.Logs.debug(f"Cache Size = {self.Settings.get_cache_size()}")
|
||||
self.ctx.Logs.debug(f"Cache Size = {self.ctx.Settings.get_cache_size()}")
|
||||
|
||||
# Créer les nouvelles commandes du module
|
||||
self.Irc.build_command(1, self.module_name, 'clone', 'Connect, join, part, kill and say clones')
|
||||
self.ctx.Irc.build_command(1, self.module_name, 'clone', 'Connect, join, part, kill and say clones')
|
||||
|
||||
self.Channel.db_query_channel(action='add', module_name=self.module_name, channel_name=self.Config.CLONE_CHANNEL)
|
||||
self.Protocol.send_sjoin(self.Config.CLONE_CHANNEL)
|
||||
self.Protocol.send_set_mode('+o', nickname=self.Config.SERVICE_NICKNAME, channel_name=self.Config.CLONE_CHANNEL)
|
||||
self.Protocol.send_set_mode('+nts', channel_name=self.Config.CLONE_CHANNEL)
|
||||
self.Protocol.send_set_mode('+k', channel_name=self.Config.CLONE_CHANNEL, params=self.Config.CLONE_CHANNEL_PASSWORD)
|
||||
await self.ctx.Channel.db_query_channel(action='add', module_name=self.module_name, channel_name=self.ctx.Config.CLONE_CHANNEL)
|
||||
await self.ctx.Irc.Protocol.send_sjoin(self.ctx.Config.CLONE_CHANNEL)
|
||||
await self.ctx.Irc.Protocol.send_set_mode('+o', nickname=self.ctx.Config.SERVICE_NICKNAME, channel_name=self.ctx.Config.CLONE_CHANNEL)
|
||||
await self.ctx.Irc.Protocol.send_set_mode('+nts', channel_name=self.ctx.Config.CLONE_CHANNEL)
|
||||
await self.ctx.Irc.Protocol.send_set_mode('+k', channel_name=self.ctx.Config.CLONE_CHANNEL, params=self.ctx.Config.CLONE_CHANNEL_PASSWORD)
|
||||
|
||||
def unload(self) -> None:
|
||||
async def unload(self) -> None:
|
||||
"""Cette methode sera executée a chaque désactivation ou
|
||||
rechargement de module
|
||||
"""
|
||||
# Store Clones DB into the global Settings to retrieve it after the reload.
|
||||
self.Settings.set_cache('UID_CLONE_DB', self.Clone.UID_CLONE_DB)
|
||||
self.ctx.Settings.set_cache('UID_CLONE_DB', self.Clone.UID_CLONE_DB)
|
||||
|
||||
self.Channel.db_query_channel(action='del', module_name=self.module_name, channel_name=self.Config.CLONE_CHANNEL)
|
||||
self.Protocol.send_set_mode('-nts', channel_name=self.Config.CLONE_CHANNEL)
|
||||
self.Protocol.send_set_mode('-k', channel_name=self.Config.CLONE_CHANNEL)
|
||||
self.Protocol.send_part_chan(self.Config.SERVICE_NICKNAME, self.Config.CLONE_CHANNEL)
|
||||
await self.ctx.Channel.db_query_channel(action='del', module_name=self.module_name, channel_name=self.ctx.Config.CLONE_CHANNEL)
|
||||
await self.ctx.Irc.Protocol.send_set_mode('-nts', channel_name=self.ctx.Config.CLONE_CHANNEL)
|
||||
await self.ctx.Irc.Protocol.send_set_mode('-k', channel_name=self.ctx.Config.CLONE_CHANNEL)
|
||||
await self.ctx.Irc.Protocol.send_part_chan(self.ctx.Config.SERVICE_NICKNAME, self.ctx.Config.CLONE_CHANNEL)
|
||||
|
||||
self.Irc.Commands.drop_command_by_module(self.module_name)
|
||||
self.ctx.Commands.drop_command_by_module(self.module_name)
|
||||
|
||||
return None
|
||||
|
||||
def cmd(self, data:list) -> None:
|
||||
async def cmd(self, data:list) -> None:
|
||||
try:
|
||||
if not data or len(data) < 2:
|
||||
return None
|
||||
|
||||
cmd = data.copy() if isinstance(data, list) else list(data).copy()
|
||||
index, command = self.Irc.Protocol.get_ircd_protocol_poisition(cmd)
|
||||
index, command = self.ctx.Irc.Protocol.get_ircd_protocol_poisition(cmd)
|
||||
if index == -1:
|
||||
return None
|
||||
|
||||
match command:
|
||||
|
||||
case 'PRIVMSG':
|
||||
self.Utils.handle_on_privmsg(self, cmd)
|
||||
await self.Utils.handle_on_privmsg(self, cmd)
|
||||
return None
|
||||
|
||||
case 'QUIT':
|
||||
@@ -105,10 +120,10 @@ class Clone(IModule):
|
||||
return None
|
||||
|
||||
except Exception as err:
|
||||
self.Logs.error(f'General Error: {err}', exc_info=True)
|
||||
self.ctx.Logs.error(f'General Error: {err}', exc_info=True)
|
||||
return None
|
||||
|
||||
def hcmds(self, user: str, channel: Any, cmd: list, fullcmd: list = []) -> None:
|
||||
async def hcmds(self, user: str, channel: Any, cmd: list, fullcmd: list = []) -> None:
|
||||
|
||||
try:
|
||||
|
||||
@@ -117,18 +132,18 @@ class Clone(IModule):
|
||||
|
||||
command = str(cmd[0]).lower()
|
||||
fromuser = user
|
||||
dnickname = self.Config.SERVICE_NICKNAME
|
||||
dnickname = self.ctx.Config.SERVICE_NICKNAME
|
||||
|
||||
match command:
|
||||
|
||||
case 'clone':
|
||||
|
||||
if len(cmd) == 1:
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone connect NUMBER GROUP_NAME INTERVAL")
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone kill [all | group_name | nickname]")
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone join [all | group_name | nickname] #channel")
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone part [all | group_name | nickname] #channel")
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone list [group name]")
|
||||
if len(cmd) < 2:
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone connect NUMBER GROUP_NAME INTERVAL")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone kill [all | group_name | nickname]")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone join [all | group_name | nickname] #channel")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone part [all | group_name | nickname] #channel")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone list [group name]")
|
||||
return None
|
||||
|
||||
option = str(cmd[1]).lower()
|
||||
@@ -143,15 +158,13 @@ class Clone(IModule):
|
||||
group = str(cmd[3]).lower()
|
||||
connection_interval = int(cmd[4]) if len(cmd) == 5 else 0.2
|
||||
|
||||
self.Base.create_thread(
|
||||
func=self.Threads.thread_connect_clones,
|
||||
func_args=(self, number_of_clones, group, False, connection_interval)
|
||||
self.ctx.Base.create_asynctask(
|
||||
func=self.Threads.coro_connect_clones(self, number_of_clones, group, False, connection_interval)
|
||||
)
|
||||
|
||||
except Exception as err:
|
||||
self.Logs.error(f'{err}')
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone connect [number of clone you want to connect] [Group] [freq]")
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Exemple /msg {dnickname} clone connect 6 Ambiance")
|
||||
except IndexError:
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone connect [number of clone you want to connect] [Group] [freq]")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Exemple /msg {dnickname} clone connect 6 Ambiance")
|
||||
|
||||
case 'kill':
|
||||
try:
|
||||
@@ -160,27 +173,26 @@ class Clone(IModule):
|
||||
option = str(cmd[2])
|
||||
|
||||
if option.lower() == 'all':
|
||||
self.Base.create_thread(func=self.Threads.thread_kill_clones, func_args=(self, ))
|
||||
self.ctx.Base.create_asynctask(func=self.Threads.thread_kill_clones(self))
|
||||
|
||||
elif self.Clone.group_exists(option):
|
||||
list_of_clones_in_group = self.Clone.get_clones_from_groupname(option)
|
||||
|
||||
if len(list_of_clones_in_group) > 0:
|
||||
self.Logs.debug(f"[Clone Kill Group] - Killing {len(list_of_clones_in_group)} clones in the group {option}")
|
||||
self.ctx.Logs.debug(f"[Clone Kill Group] - Killing {len(list_of_clones_in_group)} clones in the group {option}")
|
||||
|
||||
for clone in list_of_clones_in_group:
|
||||
self.Protocol.send_quit(clone.uid, "Now i am leaving irc but i'll come back soon ...", print_log=False)
|
||||
await self.ctx.Irc.Protocol.send_quit(clone.uid, "Now i am leaving irc but i'll come back soon ...", print_log=False)
|
||||
self.Clone.delete(clone.uid)
|
||||
|
||||
else:
|
||||
clone_obj = self.Clone.get_clone(option)
|
||||
if not clone_obj is None:
|
||||
self.Protocol.send_quit(clone_obj.uid, 'Goood bye', print_log=False)
|
||||
await self.ctx.Irc.Protocol.send_quit(clone_obj.uid, 'Goood bye', print_log=False)
|
||||
self.Clone.delete(clone_obj.uid)
|
||||
|
||||
except Exception as err:
|
||||
self.Logs.error(f'{err}')
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone kill [all | group name | nickname]")
|
||||
except IndexError:
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone kill [all | group name | nickname]")
|
||||
|
||||
case 'join':
|
||||
try:
|
||||
@@ -191,25 +203,24 @@ class Clone(IModule):
|
||||
if option.lower() == 'all':
|
||||
|
||||
for clone in self.Clone.UID_CLONE_DB:
|
||||
self.Protocol.send_join_chan(uidornickname=clone.uid, channel=clone_channel_to_join, print_log=False)
|
||||
await self.ctx.Irc.Protocol.send_join_chan(uidornickname=clone.uid, channel=clone_channel_to_join, print_log=False)
|
||||
|
||||
elif self.Clone.group_exists(option):
|
||||
list_of_clones_in_group = self.Clone.get_clones_from_groupname(option)
|
||||
|
||||
if len(list_of_clones_in_group) > 0:
|
||||
self.Logs.debug(f"[Clone Join Group] - Joining {len(list_of_clones_in_group)} clones from group {option} in the channel {clone_channel_to_join}")
|
||||
self.ctx.Logs.debug(f"[Clone Join Group] - Joining {len(list_of_clones_in_group)} clones from group {option} in the channel {clone_channel_to_join}")
|
||||
|
||||
for clone in list_of_clones_in_group:
|
||||
self.Protocol.send_join_chan(uidornickname=clone.nickname, channel=clone_channel_to_join, print_log=False)
|
||||
await self.ctx.Irc.Protocol.send_join_chan(uidornickname=clone.nickname, channel=clone_channel_to_join, print_log=False)
|
||||
|
||||
else:
|
||||
if self.Clone.nickname_exists(option):
|
||||
clone_uid = self.Clone.get_clone(option).uid
|
||||
self.Protocol.send_join_chan(uidornickname=clone_uid, channel=clone_channel_to_join, print_log=False)
|
||||
await self.ctx.Irc.Protocol.send_join_chan(uidornickname=clone_uid, channel=clone_channel_to_join, print_log=False)
|
||||
|
||||
except Exception as err:
|
||||
self.Logs.error(f'{err}')
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone join [all | group name | nickname] #channel")
|
||||
except IndexError:
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone join [all | group name | nickname] #channel")
|
||||
|
||||
case 'part':
|
||||
try:
|
||||
@@ -220,67 +231,66 @@ class Clone(IModule):
|
||||
if option.lower() == 'all':
|
||||
|
||||
for clone in self.Clone.UID_CLONE_DB:
|
||||
self.Protocol.send_part_chan(uidornickname=clone.uid, channel=clone_channel_to_part, print_log=False)
|
||||
await self.ctx.Irc.Protocol.send_part_chan(uidornickname=clone.uid, channel=clone_channel_to_part, print_log=False)
|
||||
|
||||
elif self.Clone.group_exists(option):
|
||||
list_of_clones_in_group = self.Clone.get_clones_from_groupname(option)
|
||||
|
||||
if len(list_of_clones_in_group) > 0:
|
||||
self.Logs.debug(f"[Clone Part Group] - Part {len(list_of_clones_in_group)} clones from group {option} from the channel {clone_channel_to_part}")
|
||||
self.ctx.Logs.debug(f"[Clone Part Group] - Part {len(list_of_clones_in_group)} clones from group {option} from the channel {clone_channel_to_part}")
|
||||
|
||||
for clone in list_of_clones_in_group:
|
||||
self.Protocol.send_part_chan(uidornickname=clone.uid, channel=clone_channel_to_part, print_log=False)
|
||||
await self.ctx.Irc.Protocol.send_part_chan(uidornickname=clone.uid, channel=clone_channel_to_part, print_log=False)
|
||||
|
||||
else:
|
||||
if self.Clone.nickname_exists(option):
|
||||
clone_uid = self.Clone.get_uid(option)
|
||||
if not clone_uid is None:
|
||||
self.Protocol.send_part_chan(uidornickname=clone_uid, channel=clone_channel_to_part, print_log=False)
|
||||
await self.ctx.Irc.Protocol.send_part_chan(uidornickname=clone_uid, channel=clone_channel_to_part, print_log=False)
|
||||
|
||||
except Exception as err:
|
||||
self.Logs.error(f'{err}')
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone part [all | group name | nickname] #channel")
|
||||
except IndexError:
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone part [all | group name | nickname] #channel")
|
||||
|
||||
case 'list':
|
||||
try:
|
||||
# Syntax. /msg defender clone list <group_name>
|
||||
header = f" {'Nickname':<12}| {'Real name':<25}| {'Group name':<15}| {'Connected':<35}"
|
||||
line = "-"*67
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=header)
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {line}")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=header)
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {line}")
|
||||
group_name = cmd[2] if len(cmd) > 2 else None
|
||||
|
||||
if group_name is None:
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Number of connected clones: {len(self.Clone.UID_CLONE_DB)}")
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {line}")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Number of connected clones: {len(self.Clone.UID_CLONE_DB)}")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {line}")
|
||||
for clone_name in self.Clone.UID_CLONE_DB:
|
||||
self.Protocol.send_notice(
|
||||
await self.ctx.Irc.Protocol.send_notice(
|
||||
nick_from=dnickname,
|
||||
nick_to=fromuser,
|
||||
msg=f" {clone_name.nickname:<12}| {clone_name.realname:<25}| {clone_name.group:<15}| {clone_name.connected:<35}")
|
||||
else:
|
||||
if not self.Clone.group_exists(group_name):
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="This Group name doesn't exist!")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="This Group name doesn't exist!")
|
||||
return None
|
||||
clones = self.Clone.get_clones_from_groupname(group_name)
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Number of connected clones: {len(clones)}")
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {line}")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Number of connected clones: {len(clones)}")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {line}")
|
||||
for clone in clones:
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,
|
||||
msg=f" {clone.nickname:<12}| {clone.realname:<25}| {clone.group:<15}| {clone.connected:<35}")
|
||||
except Exception as err:
|
||||
self.Logs.error(f'{err}')
|
||||
except IndexError:
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone list [group name]")
|
||||
|
||||
case 'say':
|
||||
try:
|
||||
# clone say clone_nickname #channel message
|
||||
clone_name = str(cmd[2])
|
||||
clone_channel = str(cmd[3]) if self.Channel.is_valid_channel(str(cmd[3])) else None
|
||||
clone_channel = str(cmd[3]) if self.ctx.Channel.is_valid_channel(str(cmd[3])) else None
|
||||
|
||||
final_message = ' '.join(cmd[4:])
|
||||
|
||||
if clone_channel is None or not self.Clone.nickname_exists(clone_name):
|
||||
self.Protocol.send_notice(
|
||||
await self.ctx.Irc.Protocol.send_notice(
|
||||
nick_from=dnickname,
|
||||
nick_to=fromuser,
|
||||
msg=f"/msg {dnickname} clone say [clone_nickname] #channel message"
|
||||
@@ -288,24 +298,21 @@ class Clone(IModule):
|
||||
return None
|
||||
|
||||
if self.Clone.nickname_exists(clone_name):
|
||||
self.Protocol.send_priv_msg(nick_from=clone_name, msg=final_message, channel=clone_channel)
|
||||
await self.ctx.Irc.Protocol.send_priv_msg(nick_from=clone_name, msg=final_message, channel=clone_channel)
|
||||
|
||||
except Exception as err:
|
||||
self.Logs.error(f'{err}')
|
||||
self.Protocol.send_notice(
|
||||
except IndexError:
|
||||
await self.ctx.Irc.Protocol.send_notice(
|
||||
nick_from=dnickname,
|
||||
nick_to=fromuser,
|
||||
msg=f"/msg {dnickname} clone say [clone_nickname] #channel message"
|
||||
)
|
||||
|
||||
case _:
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone connect NUMBER GROUP_NAME INTERVAL")
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone kill [all | group name | nickname]")
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone join [all | group name | nickname] #channel")
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone part [all | group name | nickname] #channel")
|
||||
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone list [group name]")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone connect NUMBER GROUP_NAME INTERVAL")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone kill [all | group name | nickname]")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone join [all | group name | nickname] #channel")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone part [all | group name | nickname] #channel")
|
||||
await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone list [group name]")
|
||||
|
||||
except IndexError as ie:
|
||||
self.Logs.error(f'Index Error: {ie}')
|
||||
except Exception as err:
|
||||
self.Logs.error(f'General Error: {err}')
|
||||
self.ctx.Logs.error(f'General Error: {err}', exc_info=True)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import asyncio
|
||||
from typing import TYPE_CHECKING
|
||||
from time import sleep
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mods.clone.mod_clone import Clone
|
||||
|
||||
def thread_connect_clones(uplink: 'Clone',
|
||||
async def coro_connect_clones(uplink: 'Clone',
|
||||
number_of_clones:int ,
|
||||
group: str = 'Default',
|
||||
auto_remote_ip: bool = False,
|
||||
@@ -27,18 +28,18 @@ def thread_connect_clones(uplink: 'Clone',
|
||||
break
|
||||
|
||||
if not clone.connected:
|
||||
uplink.Protocol.send_uid(clone.nickname, clone.username, clone.hostname, clone.uid, clone.umodes, clone.vhost, clone.remote_ip, clone.realname, print_log=False)
|
||||
uplink.Protocol.send_join_chan(uidornickname=clone.uid, channel=uplink.Config.CLONE_CHANNEL, password=uplink.Config.CLONE_CHANNEL_PASSWORD, print_log=False)
|
||||
await uplink.ctx.Irc.Protocol.send_uid(clone.nickname, clone.username, clone.hostname, clone.uid, clone.umodes, clone.vhost, clone.remote_ip, clone.realname, print_log=False)
|
||||
await uplink.ctx.Irc.Protocol.send_join_chan(uidornickname=clone.uid, channel=uplink.ctx.Config.CLONE_CHANNEL, password=uplink.ctx.Config.CLONE_CHANNEL_PASSWORD, print_log=False)
|
||||
|
||||
sleep(interval)
|
||||
await asyncio.sleep(interval)
|
||||
clone.connected = True
|
||||
|
||||
def thread_kill_clones(uplink: 'Clone'):
|
||||
async def thread_kill_clones(uplink: 'Clone'):
|
||||
|
||||
clone_to_kill = uplink.Clone.UID_CLONE_DB.copy()
|
||||
|
||||
for clone in clone_to_kill:
|
||||
uplink.Protocol.send_quit(clone.uid, 'Gooood bye', print_log=False)
|
||||
await uplink.ctx.Irc.Protocol.send_quit(clone.uid, 'Gooood bye', print_log=False)
|
||||
uplink.Clone.delete(clone.uid)
|
||||
|
||||
del clone_to_kill
|
||||
|
||||
@@ -125,8 +125,8 @@ def create_new_clone(uplink: 'Clone', faker_instance: 'Faker', group: str = 'Def
|
||||
"""
|
||||
faker = faker_instance
|
||||
|
||||
uid = generate_uid_for_clone(faker, uplink.Config.SERVEUR_ID)
|
||||
umodes = uplink.Config.CLONE_UMODES
|
||||
uid = generate_uid_for_clone(faker, uplink.ctx.Config.SERVEUR_ID)
|
||||
umodes = uplink.ctx.Config.CLONE_UMODES
|
||||
|
||||
# Generate Username
|
||||
username = generate_username_for_clone(faker)
|
||||
@@ -153,7 +153,7 @@ def create_new_clone(uplink: 'Clone', faker_instance: 'Faker', group: str = 'Def
|
||||
checkNickname = uplink.Clone.nickname_exists(nickname)
|
||||
|
||||
while checkUid:
|
||||
uid = generate_uid_for_clone(faker, uplink.Config.SERVEUR_ID)
|
||||
uid = generate_uid_for_clone(faker, uplink.ctx.Config.SERVEUR_ID)
|
||||
checkUid = uplink.Clone.uid_exists(uid=uid)
|
||||
|
||||
clone = uplink.Schemas.MClone(
|
||||
@@ -174,12 +174,12 @@ def create_new_clone(uplink: 'Clone', faker_instance: 'Faker', group: str = 'Def
|
||||
|
||||
return True
|
||||
|
||||
def handle_on_privmsg(uplink: 'Clone', srvmsg: list[str]) -> None:
|
||||
async def handle_on_privmsg(uplink: 'Clone', srvmsg: list[str]) -> None:
|
||||
|
||||
senderObj, recieverObj, channel, message = uplink.Protocol.parse_privmsg(srvmsg)
|
||||
senderObj, recieverObj, channel, message = uplink.ctx.Irc.Protocol.parse_privmsg(srvmsg)
|
||||
|
||||
if senderObj is not None:
|
||||
if senderObj.hostname in uplink.Config.CLONE_LOG_HOST_EXEMPT:
|
||||
if senderObj.hostname in uplink.ctx.Config.CLONE_LOG_HOST_EXEMPT:
|
||||
return
|
||||
senderMsg = message
|
||||
clone_obj = recieverObj
|
||||
@@ -187,12 +187,12 @@ def handle_on_privmsg(uplink: 'Clone', srvmsg: list[str]) -> None:
|
||||
if clone_obj is None:
|
||||
return
|
||||
|
||||
if clone_obj.uid != uplink.Config.SERVICE_ID:
|
||||
if clone_obj.uid != uplink.ctx.Config.SERVICE_ID:
|
||||
final_message = f"{senderObj.nickname}!{senderObj.username}@{senderObj.hostname} > {senderMsg.lstrip(':')}"
|
||||
uplink.Protocol.send_priv_msg(
|
||||
await uplink.ctx.Irc.Protocol.send_priv_msg(
|
||||
nick_from=clone_obj.uid,
|
||||
msg=final_message,
|
||||
channel=uplink.Config.CLONE_CHANNEL
|
||||
channel=uplink.ctx.Config.CLONE_CHANNEL
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,243 +4,243 @@ if TYPE_CHECKING:
|
||||
from mods.command.mod_command import Command
|
||||
|
||||
|
||||
def set_automode(uplink: 'Command', cmd: list[str], client: str) -> None:
|
||||
async def set_automode(uplink: 'Command', cmd: list[str], client: str) -> None:
|
||||
|
||||
command: str = str(cmd[0]).lower()
|
||||
option: str = str(cmd[1]).lower()
|
||||
allowed_modes: list[str] = uplink.Loader.Settings.PROTOCTL_PREFIX # ['q','a','o','h','v']
|
||||
dnickname = uplink.Config.SERVICE_NICKNAME
|
||||
service_id = uplink.Config.SERVICE_ID
|
||||
allowed_modes: list[str] = uplink.ctx.Settings.PROTOCTL_PREFIX # ['q','a','o','h','v']
|
||||
dnickname = uplink.ctx.Config.SERVICE_NICKNAME
|
||||
service_id = uplink.ctx.Config.SERVICE_ID
|
||||
fromuser = client
|
||||
|
||||
match option:
|
||||
case 'set':
|
||||
if len(cmd) < 5:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} [nickname] [+/-mode] [#channel]")
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"AutoModes available: {' / '.join(allowed_modes)}")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} [nickname] [+/-mode] [#channel]")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"AutoModes available: {' / '.join(allowed_modes)}")
|
||||
return None
|
||||
|
||||
nickname = str(cmd[2])
|
||||
mode = str(cmd[3])
|
||||
chan: str = str(cmd[4]).lower() if uplink.Channel.is_valid_channel(cmd[4]) else None
|
||||
chan: str = str(cmd[4]).lower() if uplink.ctx.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
|
||||
|
||||
if sign is None:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You must provide the flag mode + or -")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You must provide the flag mode + or -")
|
||||
return None
|
||||
|
||||
if clean_mode not in allowed_modes:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You should use one of those modes {' / '.join(allowed_modes)}")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You should use one of those modes {' / '.join(allowed_modes)}")
|
||||
return None
|
||||
|
||||
if chan is None:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You should use one of those modes {' / '.join(allowed_modes)}")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You should use one of those modes {' / '.join(allowed_modes)}")
|
||||
return None
|
||||
|
||||
db_data: dict[str, str] = {"nickname": nickname, "channel": chan}
|
||||
db_query = uplink.Base.db_execute_query(query="SELECT id FROM command_automode WHERE nickname = :nickname and channel = :channel", params=db_data)
|
||||
db_query = await uplink.ctx.Base.db_execute_query(query="SELECT id FROM command_automode WHERE nickname = :nickname and channel = :channel", params=db_data)
|
||||
db_result = db_query.fetchone()
|
||||
|
||||
if db_result is not None:
|
||||
if sign == '+':
|
||||
db_data = {"updated_on": uplink.MainUtils.get_sdatetime(), "nickname": nickname, "channel": chan, "mode": mode}
|
||||
db_result = uplink.Base.db_execute_query(query="UPDATE command_automode SET mode = :mode, updated_on = :updated_on WHERE nickname = :nickname and channel = :channel",
|
||||
db_data = {"updated_on": uplink.ctx.Utils.get_sdatetime(), "nickname": nickname, "channel": chan, "mode": mode}
|
||||
db_result = await uplink.ctx.Base.db_execute_query(query="UPDATE command_automode SET mode = :mode, updated_on = :updated_on WHERE nickname = :nickname and channel = :channel",
|
||||
params=db_data)
|
||||
if db_result.rowcount > 0:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} edited for {nickname} in {chan}")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} edited for {nickname} in {chan}")
|
||||
elif sign == '-':
|
||||
db_data = {"nickname": nickname, "channel": chan, "mode": f"+{clean_mode}"}
|
||||
db_result = uplink.Base.db_execute_query(query="DELETE FROM command_automode WHERE nickname = :nickname and channel = :channel and mode = :mode",
|
||||
db_result = await uplink.ctx.Base.db_execute_query(query="DELETE FROM command_automode WHERE nickname = :nickname and channel = :channel and mode = :mode",
|
||||
params=db_data)
|
||||
if db_result.rowcount > 0:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} deleted for {nickname} in {chan}")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} deleted for {nickname} in {chan}")
|
||||
else:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"The mode [{mode}] has not been found for {nickname} in channel {chan}")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"The mode [{mode}] has not been found for {nickname} in channel {chan}")
|
||||
|
||||
return None
|
||||
|
||||
# Instert a new automode
|
||||
if sign == '+':
|
||||
db_data = {"created_on": uplink.MainUtils.get_sdatetime(), "updated_on": uplink.MainUtils.get_sdatetime(), "nickname": nickname, "channel": chan, "mode": mode}
|
||||
db_query = uplink.Base.db_execute_query(
|
||||
db_data = {"created_on": uplink.ctx.Utils.get_sdatetime(), "updated_on": uplink.ctx.Utils.get_sdatetime(), "nickname": nickname, "channel": chan, "mode": mode}
|
||||
db_query = await uplink.ctx.Base.db_execute_query(
|
||||
query="INSERT INTO command_automode (created_on, updated_on, nickname, channel, mode) VALUES (:created_on, :updated_on, :nickname, :channel, :mode)",
|
||||
params=db_data
|
||||
)
|
||||
|
||||
if db_query.rowcount > 0:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} applied to {nickname} in {chan}")
|
||||
if uplink.Channel.is_user_present_in_channel(chan, uplink.User.get_uid(nickname)):
|
||||
uplink.Protocol.send2socket(f":{service_id} MODE {chan} {mode} {nickname}")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} applied to {nickname} in {chan}")
|
||||
if uplink.ctx.Channel.is_user_present_in_channel(chan, uplink.ctx.User.get_uid(nickname)):
|
||||
await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {chan} {mode} {nickname}")
|
||||
else:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"AUTOMODE {mode} cannot be added to {nickname} in {chan} because it doesn't exist")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"AUTOMODE {mode} cannot be added to {nickname} in {chan} because it doesn't exist")
|
||||
|
||||
case 'list':
|
||||
db_query = uplink.Base.db_execute_query("SELECT nickname, channel, mode FROM command_automode")
|
||||
db_query = await uplink.ctx.Base.db_execute_query("SELECT nickname, channel, mode FROM command_automode")
|
||||
db_results = db_query.fetchall()
|
||||
|
||||
if not db_results:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,
|
||||
msg="There is no automode to display.")
|
||||
|
||||
for db_result in db_results:
|
||||
db_nickname, db_channel, db_mode = db_result
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,
|
||||
msg=f"Nickname: {db_nickname} | Channel: {db_channel} | Mode: {db_mode}")
|
||||
|
||||
case _:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} SET [nickname] [+/-mode] [#channel]")
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} LIST")
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"[AUTOMODES AVAILABLE] are {' / '.join(allowed_modes)}")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} SET [nickname] [+/-mode] [#channel]")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} LIST")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"[AUTOMODES AVAILABLE] are {' / '.join(allowed_modes)}")
|
||||
|
||||
def set_deopall(uplink: 'Command', channel_name: str) -> None:
|
||||
async def set_deopall(uplink: 'Command', channel_name: str) -> None:
|
||||
|
||||
service_id = uplink.Config.SERVICE_ID
|
||||
uplink.Protocol.send2socket(f":{service_id} SVSMODE {channel_name} -o")
|
||||
service_id = uplink.ctx.Config.SERVICE_ID
|
||||
await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} SVSMODE {channel_name} -o")
|
||||
return None
|
||||
|
||||
def set_devoiceall(uplink: 'Command', channel_name: str) -> None:
|
||||
async def set_devoiceall(uplink: 'Command', channel_name: str) -> None:
|
||||
|
||||
service_id = uplink.Config.SERVICE_ID
|
||||
uplink.Protocol.send2socket(f":{service_id} SVSMODE {channel_name} -v")
|
||||
service_id = uplink.ctx.Config.SERVICE_ID
|
||||
await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} SVSMODE {channel_name} -v")
|
||||
return None
|
||||
|
||||
def set_mode_to_all(uplink: 'Command', channel_name: str, action: Literal['+', '-'], pmode: str) -> None:
|
||||
async def set_mode_to_all(uplink: 'Command', channel_name: str, action: Literal['+', '-'], pmode: str) -> None:
|
||||
|
||||
chan_info = uplink.Channel.get_channel(channel_name)
|
||||
service_id = uplink.Config.SERVICE_ID
|
||||
dnickname = uplink.Config.SERVICE_NICKNAME
|
||||
chan_info = uplink.ctx.Channel.get_channel(channel_name)
|
||||
service_id = uplink.ctx.Config.SERVICE_ID
|
||||
dnickname = uplink.ctx.Config.SERVICE_NICKNAME
|
||||
set_mode = pmode
|
||||
mode:str = ''
|
||||
users:str = ''
|
||||
uids_split = [chan_info.uids[i:i + 6] for i in range(0, len(chan_info.uids), 6)]
|
||||
|
||||
uplink.Protocol.send2socket(f":{service_id} MODE {channel_name} {action}{set_mode} {dnickname}")
|
||||
await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {channel_name} {action}{set_mode} {dnickname}")
|
||||
for uid in uids_split:
|
||||
for i in range(0, len(uid)):
|
||||
mode += set_mode
|
||||
users += f'{uplink.User.get_nickname(uplink.MainUtils.clean_uid(uid[i]))} '
|
||||
users += f'{uplink.ctx.User.get_nickname(uplink.ctx.Utils.clean_uid(uid[i]))} '
|
||||
if i == len(uid) - 1:
|
||||
uplink.Protocol.send2socket(f":{service_id} MODE {channel_name} {action}{mode} {users}")
|
||||
await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {channel_name} {action}{mode} {users}")
|
||||
mode = ''
|
||||
users = ''
|
||||
|
||||
def set_operation(uplink: 'Command', cmd: list[str], channel_name: Optional[str], client: str, mode: str) -> None:
|
||||
async def set_operation(uplink: 'Command', cmd: list[str], channel_name: Optional[str], client: str, mode: str) -> None:
|
||||
|
||||
dnickname = uplink.Config.SERVICE_NICKNAME
|
||||
service_id = uplink.Config.SERVICE_ID
|
||||
dnickname = uplink.ctx.Config.SERVICE_NICKNAME
|
||||
service_id = uplink.ctx.Config.SERVICE_ID
|
||||
if channel_name is None:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {mode} [#SALON] [NICKNAME]")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {mode} [#SALON] [NICKNAME]")
|
||||
return False
|
||||
|
||||
if len(cmd) == 1:
|
||||
# uplink.Protocol.send2socket(f":{service_id} MODE {channel_name} {mode} {client}")
|
||||
uplink.Protocol.send_set_mode(mode, nickname=client, channel_name=channel_name)
|
||||
# await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {channel_name} {mode} {client}")
|
||||
await uplink.ctx.Irc.Protocol.send_set_mode(mode, nickname=client, channel_name=channel_name)
|
||||
return None
|
||||
|
||||
# deop nickname
|
||||
if len(cmd) == 2:
|
||||
nickname = cmd[1]
|
||||
# uplink.Protocol.send2socket(f":{service_id} MODE {channel_name} {mode} {nickname}")
|
||||
uplink.Protocol.send_set_mode(mode, nickname=nickname, channel_name=channel_name)
|
||||
# await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {channel_name} {mode} {nickname}")
|
||||
await uplink.ctx.Irc.Protocol.send_set_mode(mode, nickname=nickname, channel_name=channel_name)
|
||||
return None
|
||||
|
||||
nickname = cmd[2]
|
||||
# uplink.Protocol.send2socket(f":{service_id} MODE {channel_name} {mode} {nickname}")
|
||||
uplink.Protocol.send_set_mode(mode, nickname=nickname, channel_name=channel_name)
|
||||
# await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {channel_name} {mode} {nickname}")
|
||||
await uplink.ctx.Irc.Protocol.send_set_mode(mode, nickname=nickname, channel_name=channel_name)
|
||||
return None
|
||||
|
||||
def set_ban(uplink: 'Command', cmd: list[str], action: Literal['+', '-'], client: str) -> None:
|
||||
async def set_ban(uplink: 'Command', cmd: list[str], action: Literal['+', '-'], client: str) -> None:
|
||||
|
||||
command = str(cmd[0])
|
||||
dnickname = uplink.Config.SERVICE_NICKNAME
|
||||
service_id = uplink.Config.SERVICE_ID
|
||||
sentchannel = str(cmd[1]) if uplink.Channel.is_valid_channel(cmd[1]) else None
|
||||
dnickname = uplink.ctx.Config.SERVICE_NICKNAME
|
||||
service_id = uplink.ctx.Config.SERVICE_ID
|
||||
sentchannel = str(cmd[1]) if uplink.ctx.Channel.is_valid_channel(cmd[1]) else None
|
||||
|
||||
if sentchannel is None:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME]")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME]")
|
||||
return None
|
||||
|
||||
nickname = cmd[2]
|
||||
|
||||
uplink.Protocol.send2socket(f":{service_id} MODE {sentchannel} {action}b {nickname}!*@*")
|
||||
uplink.Logs.debug(f'{client} has banned {nickname} from {sentchannel}')
|
||||
await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {sentchannel} {action}b {nickname}!*@*")
|
||||
uplink.ctx.Logs.debug(f'{client} has banned {nickname} from {sentchannel}')
|
||||
return None
|
||||
|
||||
def set_kick(uplink: 'Command', cmd: list[str], client: str) -> None:
|
||||
async def set_kick(uplink: 'Command', cmd: list[str], client: str) -> None:
|
||||
|
||||
command = str(cmd[0])
|
||||
dnickname = uplink.Config.SERVICE_NICKNAME
|
||||
service_id = uplink.Config.SERVICE_ID
|
||||
dnickname = uplink.ctx.Config.SERVICE_NICKNAME
|
||||
service_id = uplink.ctx.Config.SERVICE_ID
|
||||
|
||||
sentchannel = str(cmd[1]) if uplink.Channel.is_valid_channel(cmd[1]) else None
|
||||
sentchannel = str(cmd[1]) if uplink.ctx.Channel.is_valid_channel(cmd[1]) else None
|
||||
if sentchannel is None:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command} [#SALON] [NICKNAME]")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command} [#SALON] [NICKNAME]")
|
||||
return False
|
||||
|
||||
nickname = cmd[2]
|
||||
final_reason = ' '.join(cmd[3:])
|
||||
|
||||
uplink.Protocol.send2socket(f":{service_id} KICK {sentchannel} {nickname} {final_reason}")
|
||||
uplink.Logs.debug(f'{client} has kicked {nickname} from {sentchannel} : {final_reason}')
|
||||
await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} KICK {sentchannel} {nickname} {final_reason}")
|
||||
uplink.ctx.Logs.debug(f'{client} has kicked {nickname} from {sentchannel} : {final_reason}')
|
||||
return None
|
||||
|
||||
def set_kickban(uplink: 'Command', cmd: list[str], client: str) -> None:
|
||||
async def set_kickban(uplink: 'Command', cmd: list[str], client: str) -> None:
|
||||
|
||||
command = str(cmd[0])
|
||||
dnickname = uplink.Config.SERVICE_NICKNAME
|
||||
service_id = uplink.Config.SERVICE_ID
|
||||
dnickname = uplink.ctx.Config.SERVICE_NICKNAME
|
||||
service_id = uplink.ctx.Config.SERVICE_ID
|
||||
|
||||
sentchannel = str(cmd[1]) if uplink.Channel.is_valid_channel(cmd[1]) else None
|
||||
sentchannel = str(cmd[1]) if uplink.ctx.Channel.is_valid_channel(cmd[1]) else None
|
||||
if sentchannel is None:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command} [#SALON] [NICKNAME]")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command} [#SALON] [NICKNAME]")
|
||||
return False
|
||||
nickname = cmd[2]
|
||||
final_reason = ' '.join(cmd[3:])
|
||||
|
||||
uplink.Protocol.send2socket(f":{service_id} KICK {sentchannel} {nickname} {final_reason}")
|
||||
uplink.Protocol.send2socket(f":{service_id} MODE {sentchannel} +b {nickname}!*@*")
|
||||
uplink.Logs.debug(f'{client} has kicked and banned {nickname} from {sentchannel} : {final_reason}')
|
||||
await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} KICK {sentchannel} {nickname} {final_reason}")
|
||||
await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {sentchannel} +b {nickname}!*@*")
|
||||
uplink.ctx.Logs.debug(f'{client} has kicked and banned {nickname} from {sentchannel} : {final_reason}')
|
||||
|
||||
def set_assign_channel_to_service(uplink: 'Command', cmd: list[str], client: str) -> None:
|
||||
async def set_assign_channel_to_service(uplink: 'Command', cmd: list[str], client: str) -> None:
|
||||
|
||||
if len(cmd) < 2:
|
||||
raise IndexError(f"{cmd[0].upper()} is expecting the channel parameter")
|
||||
|
||||
command = str(cmd[0])
|
||||
dnickname = uplink.Config.SERVICE_NICKNAME
|
||||
sent_channel = str(cmd[1]) if uplink.Channel.is_valid_channel(cmd[1]) else None
|
||||
dnickname = uplink.ctx.Config.SERVICE_NICKNAME
|
||||
sent_channel = str(cmd[1]) if uplink.ctx.Channel.is_valid_channel(cmd[1]) else None
|
||||
if sent_channel is None:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON]")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON]")
|
||||
return None
|
||||
|
||||
# self.Protocol.send2socket(f':{service_id} JOIN {sent_channel}')
|
||||
uplink.Protocol.send_join_chan(uidornickname=dnickname,channel=sent_channel)
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Has joined {sent_channel}")
|
||||
uplink.Channel.db_query_channel('add', uplink.module_name, sent_channel)
|
||||
await uplink.ctx.Irc.Protocol.send_join_chan(uidornickname=dnickname,channel=sent_channel)
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Has joined {sent_channel}")
|
||||
await uplink.ctx.Channel.db_query_channel('add', uplink.module_name, sent_channel)
|
||||
|
||||
return None
|
||||
|
||||
def set_unassign_channel_to_service(uplink: 'Command', cmd: list[str], client: str) -> None:
|
||||
async def set_unassign_channel_to_service(uplink: 'Command', cmd: list[str], client: str) -> None:
|
||||
|
||||
if len(cmd) < 2:
|
||||
raise IndexError(f"{cmd[0].upper()} is expecting the channel parameter")
|
||||
|
||||
command = str(cmd[0])
|
||||
dnickname = uplink.Config.SERVICE_NICKNAME
|
||||
dchanlog = uplink.Config.SERVICE_CHANLOG
|
||||
dnickname = uplink.ctx.Config.SERVICE_NICKNAME
|
||||
dchanlog = uplink.ctx.Config.SERVICE_CHANLOG
|
||||
|
||||
sent_channel = str(cmd[1]) if uplink.Channel.is_valid_channel(cmd[1]) else None
|
||||
sent_channel = str(cmd[1]) if uplink.ctx.Channel.is_valid_channel(cmd[1]) else None
|
||||
if sent_channel is None:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON]")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON]")
|
||||
return None
|
||||
|
||||
if sent_channel == dchanlog:
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f"[!] CAN'T LEFT {sent_channel} AS IT IS LOG CHANNEL [!]")
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f"[!] CAN'T LEFT {sent_channel} AS IT IS LOG CHANNEL [!]")
|
||||
return None
|
||||
|
||||
uplink.Protocol.send_part_chan(uidornickname=dnickname, channel=sent_channel)
|
||||
uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Has left {sent_channel}")
|
||||
await uplink.ctx.Irc.Protocol.send_part_chan(uidornickname=dnickname, channel=sent_channel)
|
||||
await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Has left {sent_channel}")
|
||||
|
||||
uplink.Channel.db_query_channel('del', uplink.module_name, sent_channel)
|
||||
await uplink.ctx.Channel.db_query_channel('del', uplink.module_name, sent_channel)
|
||||
return None
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,115 +1,116 @@
|
||||
import asyncio
|
||||
from typing import TYPE_CHECKING
|
||||
from time import sleep
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mods.defender.mod_defender import Defender
|
||||
|
||||
def thread_apply_reputation_sanctions(uplink: 'Defender'):
|
||||
async def coro_apply_reputation_sanctions(uplink: 'Defender'):
|
||||
while uplink.reputationTimer_isRunning:
|
||||
uplink.Utils.action_apply_reputation_santions(uplink)
|
||||
sleep(5)
|
||||
await uplink.mod_utils.action_apply_reputation_santions(uplink)
|
||||
await asyncio.sleep(5)
|
||||
|
||||
def thread_cloudfilt_scan(uplink: 'Defender'):
|
||||
async def coro_cloudfilt_scan(uplink: 'Defender'):
|
||||
|
||||
while uplink.cloudfilt_isRunning:
|
||||
list_to_remove:list = []
|
||||
for user in uplink.Schemas.DB_CLOUDFILT_USERS:
|
||||
uplink.Utils.action_scan_client_with_cloudfilt(uplink, user)
|
||||
uplink.mod_utils.action_scan_client_with_cloudfilt(uplink, user)
|
||||
list_to_remove.append(user)
|
||||
sleep(1)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
for user_model in list_to_remove:
|
||||
uplink.Schemas.DB_CLOUDFILT_USERS.remove(user_model)
|
||||
|
||||
sleep(1)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
def thread_freeipapi_scan(uplink: 'Defender'):
|
||||
async def coro_freeipapi_scan(uplink: 'Defender'):
|
||||
|
||||
while uplink.freeipapi_isRunning:
|
||||
|
||||
list_to_remove: list = []
|
||||
for user in uplink.Schemas.DB_FREEIPAPI_USERS:
|
||||
uplink.Utils.action_scan_client_with_freeipapi(uplink, user)
|
||||
uplink.mod_utils.action_scan_client_with_freeipapi(uplink, user)
|
||||
list_to_remove.append(user)
|
||||
sleep(1)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
for user_model in list_to_remove:
|
||||
uplink.Schemas.DB_FREEIPAPI_USERS.remove(user_model)
|
||||
|
||||
sleep(1)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
def thread_abuseipdb_scan(uplink: 'Defender'):
|
||||
async def coro_abuseipdb_scan(uplink: 'Defender'):
|
||||
|
||||
while uplink.abuseipdb_isRunning:
|
||||
|
||||
list_to_remove: list = []
|
||||
for user in uplink.Schemas.DB_ABUSEIPDB_USERS:
|
||||
uplink.Utils.action_scan_client_with_abuseipdb(uplink, user)
|
||||
uplink.mod_utils.action_scan_client_with_abuseipdb(uplink, user)
|
||||
list_to_remove.append(user)
|
||||
sleep(1)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
for user_model in list_to_remove:
|
||||
uplink.Schemas.DB_ABUSEIPDB_USERS.remove(user_model)
|
||||
|
||||
sleep(1)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
def thread_local_scan(uplink: 'Defender'):
|
||||
async def coro_local_scan(uplink: 'Defender'):
|
||||
|
||||
while uplink.localscan_isRunning:
|
||||
list_to_remove:list = []
|
||||
for user in uplink.Schemas.DB_LOCALSCAN_USERS:
|
||||
uplink.Utils.action_scan_client_with_local_socket(uplink, user)
|
||||
uplink.mod_utils.action_scan_client_with_local_socket(uplink, user)
|
||||
list_to_remove.append(user)
|
||||
sleep(1)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
for user_model in list_to_remove:
|
||||
uplink.Schemas.DB_LOCALSCAN_USERS.remove(user_model)
|
||||
|
||||
sleep(1)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
def thread_psutil_scan(uplink: 'Defender'):
|
||||
async def coro_psutil_scan(uplink: 'Defender'):
|
||||
|
||||
while uplink.psutil_isRunning:
|
||||
|
||||
list_to_remove:list = []
|
||||
for user in uplink.Schemas.DB_PSUTIL_USERS:
|
||||
uplink.Utils.action_scan_client_with_psutil(uplink, user)
|
||||
uplink.mod_utils.action_scan_client_with_psutil(uplink, user)
|
||||
list_to_remove.append(user)
|
||||
sleep(1)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
for user_model in list_to_remove:
|
||||
uplink.Schemas.DB_PSUTIL_USERS.remove(user_model)
|
||||
|
||||
sleep(1)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
def thread_autolimit(uplink: 'Defender'):
|
||||
async def coro_autolimit(uplink: 'Defender'):
|
||||
|
||||
if uplink.ModConfig.autolimit == 0:
|
||||
uplink.Logs.debug("autolimit deactivated ... canceling the thread")
|
||||
if uplink.mod_config.autolimit == 0:
|
||||
uplink.ctx.Logs.debug("autolimit deactivated ... canceling the thread")
|
||||
return None
|
||||
|
||||
while uplink.Irc.autolimit_started:
|
||||
sleep(0.2)
|
||||
while uplink.ctx.Irc.autolimit_started:
|
||||
await asyncio.sleep(0.2)
|
||||
|
||||
uplink.Irc.autolimit_started = True
|
||||
init_amount = uplink.ModConfig.autolimit_amount
|
||||
p = uplink.Protocol
|
||||
uplink.ctx.Irc.autolimit_started = True
|
||||
init_amount = uplink.mod_config.autolimit_amount
|
||||
p = uplink.ctx.Irc.Protocol
|
||||
INIT = 1
|
||||
|
||||
# Copy Channels to a list of dict
|
||||
chanObj_copy: list[dict[str, int]] = [{"name": c.name, "uids_count": len(c.uids)} for c in uplink.Channel.UID_CHANNEL_DB]
|
||||
chan_list: list[str] = [c.name for c in uplink.Channel.UID_CHANNEL_DB]
|
||||
chanObj_copy: list[dict[str, int]] = [{"name": c.name, "uids_count": len(c.uids)} for c in uplink.ctx.Channel.UID_CHANNEL_DB]
|
||||
chan_list: list[str] = [c.name for c in uplink.ctx.Channel.UID_CHANNEL_DB]
|
||||
|
||||
while uplink.autolimit_isRunning:
|
||||
|
||||
if uplink.ModConfig.autolimit == 0:
|
||||
uplink.Logs.debug("autolimit deactivated ... stopping the current thread")
|
||||
if uplink.mod_config.autolimit == 0:
|
||||
uplink.ctx.Logs.debug("autolimit deactivated ... stopping the current thread")
|
||||
break
|
||||
|
||||
for chan in uplink.Channel.UID_CHANNEL_DB:
|
||||
for chan in uplink.ctx.Channel.UID_CHANNEL_DB:
|
||||
for chan_copy in chanObj_copy:
|
||||
if chan_copy["name"] == chan.name and len(chan.uids) != chan_copy["uids_count"]:
|
||||
p.send2socket(f":{uplink.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + uplink.ModConfig.autolimit_amount}")
|
||||
await p.send2socket(f":{uplink.ctx.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + uplink.mod_config.autolimit_amount}")
|
||||
chan_copy["uids_count"] = len(chan.uids)
|
||||
|
||||
if chan.name not in chan_list:
|
||||
@@ -117,51 +118,55 @@ def thread_autolimit(uplink: 'Defender'):
|
||||
chanObj_copy.append({"name": chan.name, "uids_count": 0})
|
||||
|
||||
# Verifier si un salon a été vidé
|
||||
current_chan_in_list = [d.name for d in uplink.Channel.UID_CHANNEL_DB]
|
||||
current_chan_in_list = [d.name for d in uplink.ctx.Channel.UID_CHANNEL_DB]
|
||||
for c in chan_list:
|
||||
if c not in current_chan_in_list:
|
||||
chan_list.remove(c)
|
||||
|
||||
# Si c'est la premiere execution
|
||||
if INIT == 1:
|
||||
for chan in uplink.Channel.UID_CHANNEL_DB:
|
||||
p.send2socket(f":{uplink.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + uplink.ModConfig.autolimit_amount}")
|
||||
for chan in uplink.ctx.Channel.UID_CHANNEL_DB:
|
||||
await p.send2socket(f":{uplink.ctx.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + uplink.mod_config.autolimit_amount}")
|
||||
|
||||
# Si le nouveau amount est différent de l'initial
|
||||
if init_amount != uplink.ModConfig.autolimit_amount:
|
||||
init_amount = uplink.ModConfig.autolimit_amount
|
||||
for chan in uplink.Channel.UID_CHANNEL_DB:
|
||||
p.send2socket(f":{uplink.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + uplink.ModConfig.autolimit_amount}")
|
||||
if init_amount != uplink.mod_config.autolimit_amount:
|
||||
init_amount = uplink.mod_config.autolimit_amount
|
||||
for chan in uplink.ctx.Channel.UID_CHANNEL_DB:
|
||||
await p.send2socket(f":{uplink.ctx.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + uplink.mod_config.autolimit_amount}")
|
||||
|
||||
INIT = 0
|
||||
|
||||
if uplink.autolimit_isRunning:
|
||||
sleep(uplink.ModConfig.autolimit_interval)
|
||||
await asyncio.sleep(uplink.mod_config.autolimit_interval)
|
||||
|
||||
for chan in uplink.Channel.UID_CHANNEL_DB:
|
||||
p.send2socket(f":{uplink.Config.SERVICE_ID} MODE {chan.name} -l")
|
||||
for chan in uplink.ctx.Channel.UID_CHANNEL_DB:
|
||||
# await p.send2socket(f":{uplink.ctx.Config.SERVICE_ID} MODE {chan.name} -l")
|
||||
await p.send_set_mode('-l', channel_name=chan.name)
|
||||
|
||||
uplink.Irc.autolimit_started = False
|
||||
uplink.ctx.Irc.autolimit_started = False
|
||||
|
||||
return None
|
||||
|
||||
def timer_release_mode_mute(uplink: 'Defender', action: str, channel: str):
|
||||
"""DO NOT EXECUTE THIS FUNCTION WITHOUT THREADING
|
||||
async def coro_release_mode_mute(uplink: 'Defender', action: str, channel: str):
|
||||
"""DO NOT EXECUTE THIS FUNCTION DIRECTLY
|
||||
IT WILL BLOCK THE PROCESS
|
||||
|
||||
Args:
|
||||
action (str): _description_
|
||||
action (str): mode-m
|
||||
channel (str): The related channel
|
||||
|
||||
"""
|
||||
service_id = uplink.Config.SERVICE_ID
|
||||
service_id = uplink.ctx.Config.SERVICE_ID
|
||||
timeout = uplink.mod_config.flood_timer
|
||||
await asyncio.sleep(timeout)
|
||||
|
||||
if not uplink.Channel.is_valid_channel(channel):
|
||||
uplink.Logs.debug(f"Channel is not valid {channel}")
|
||||
if not uplink.ctx.Channel.is_valid_channel(channel):
|
||||
uplink.ctx.Logs.debug(f"Channel is not valid {channel}")
|
||||
return
|
||||
|
||||
match action:
|
||||
case 'mode-m':
|
||||
# Action -m sur le salon
|
||||
uplink.Protocol.send2socket(f":{service_id} MODE {channel} -m")
|
||||
await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {channel} -m")
|
||||
case _:
|
||||
pass
|
||||
|
||||
@@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, Optional
|
||||
from mods.defender.schemas import FloodUser
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.loader import Loader
|
||||
from core.definition import MUser
|
||||
from mods.defender.mod_defender import Defender
|
||||
|
||||
@@ -28,10 +29,10 @@ def handle_on_reputation(uplink: 'Defender', srvmsg: list[str]):
|
||||
return
|
||||
|
||||
# Possibilité de déclancher les bans a ce niveau.
|
||||
if not uplink.Base.is_valid_ip(ip):
|
||||
if not uplink.ctx.Base.is_valid_ip(ip):
|
||||
return
|
||||
|
||||
def handle_on_mode(uplink: 'Defender', srvmsg: list[str]):
|
||||
async def handle_on_mode(uplink: 'Defender', srvmsg: list[str]):
|
||||
"""_summary_
|
||||
>>> srvmsg = ['@unrealircd.org/...', ':001C0MF01', 'MODE', '#services', '+l', '1']
|
||||
>>> srvmsg = ['...', ':001XSCU0Q', 'MODE', '#jail', '+b', '~security-group:unknown-users']
|
||||
@@ -40,10 +41,10 @@ def handle_on_mode(uplink: 'Defender', srvmsg: list[str]):
|
||||
srvmsg (list[str]): The Server MSG
|
||||
confmodel (ModConfModel): The Module Configuration
|
||||
"""
|
||||
irc = uplink.Irc
|
||||
gconfig = uplink.Config
|
||||
p = uplink.Protocol
|
||||
confmodel = uplink.ModConfig
|
||||
irc = uplink.ctx.Irc
|
||||
gconfig = uplink.ctx.Config
|
||||
p = irc.Protocol
|
||||
confmodel = uplink.mod_config
|
||||
|
||||
channel = str(srvmsg[3])
|
||||
mode = str(srvmsg[4])
|
||||
@@ -52,25 +53,25 @@ 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)
|
||||
p.send2socket(f":{gconfig.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + confmodel.autolimit_amount}")
|
||||
chan = uplink.ctx.Channel.get_channel(channel)
|
||||
await p.send2socket(f":{gconfig.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + confmodel.autolimit_amount}")
|
||||
|
||||
if gconfig.SALON_JAIL == channel:
|
||||
if mode == '+b' and group_to_unban in group_to_check:
|
||||
p.send2socket(f":{gconfig.SERVICE_ID} MODE {gconfig.SALON_JAIL} -b ~security-group:unknown-users")
|
||||
p.send2socket(f":{gconfig.SERVICE_ID} MODE {gconfig.SALON_JAIL} -eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
|
||||
await p.send2socket(f":{gconfig.SERVICE_ID} MODE {gconfig.SALON_JAIL} -b ~security-group:unknown-users")
|
||||
await p.send2socket(f":{gconfig.SERVICE_ID} MODE {gconfig.SALON_JAIL} -eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
|
||||
|
||||
def handle_on_privmsg(uplink: 'Defender', srvmsg: list[str]):
|
||||
async def handle_on_privmsg(uplink: 'Defender', srvmsg: list[str]):
|
||||
# ['@mtag....',':python', 'PRIVMSG', '#defender', ':zefzefzregreg', 'regg', 'aerg']
|
||||
|
||||
sender, reciever, channel, message = uplink.Protocol.parse_privmsg(srvmsg)
|
||||
if uplink.ModConfig.sentinel == 1 and channel.name != uplink.Config.SERVICE_CHANLOG:
|
||||
uplink.Protocol.send_priv_msg(uplink.Config.SERVICE_NICKNAME, f"{sender.nickname} say on {channel.name}: {' '.join(message)}", uplink.Config.SERVICE_CHANLOG)
|
||||
sender, reciever, channel, message = uplink.ctx.Irc.Protocol.parse_privmsg(srvmsg)
|
||||
if uplink.mod_config.sentinel == 1 and channel.name != uplink.ctx.Config.SERVICE_CHANLOG:
|
||||
await uplink.ctx.Irc.Protocol.send_priv_msg(uplink.ctx.Config.SERVICE_NICKNAME, f"{sender.nickname} say on {channel.name}: {' '.join(message)}", uplink.ctx.Config.SERVICE_CHANLOG)
|
||||
|
||||
action_on_flood(uplink, srvmsg)
|
||||
await action_on_flood(uplink, srvmsg)
|
||||
return None
|
||||
|
||||
def handle_on_sjoin(uplink: 'Defender', srvmsg: list[str]):
|
||||
async def handle_on_sjoin(uplink: 'Defender', srvmsg: list[str]):
|
||||
"""If Joining a new channel, it applies group bans.
|
||||
|
||||
>>> srvmsg = ['@msgid..', ':001', 'SJOIN', '1702138958', '#welcome', ':0015L1AHL']
|
||||
@@ -80,37 +81,37 @@ def handle_on_sjoin(uplink: 'Defender', srvmsg: list[str]):
|
||||
srvmsg (list[str]): The Server MSG
|
||||
confmodel (ModConfModel): The Module Configuration
|
||||
"""
|
||||
irc = uplink.Irc
|
||||
irc = uplink.ctx.Irc
|
||||
p = irc.Protocol
|
||||
gconfig = uplink.Config
|
||||
confmodel = uplink.ModConfig
|
||||
gconfig = uplink.ctx.Config
|
||||
confmodel = uplink.mod_config
|
||||
|
||||
parsed_chan = srvmsg[4] if irc.Channel.is_valid_channel(srvmsg[4]) else None
|
||||
parsed_UID = uplink.Loader.Utils.clean_uid(srvmsg[5])
|
||||
parsed_chan = srvmsg[4] if uplink.ctx.Channel.is_valid_channel(srvmsg[4]) else None
|
||||
parsed_UID = uplink.ctx.Utils.clean_uid(srvmsg[5])
|
||||
|
||||
if parsed_chan is None or parsed_UID is None:
|
||||
return
|
||||
|
||||
if confmodel.reputation == 1:
|
||||
get_reputation = irc.Reputation.get_reputation(parsed_UID)
|
||||
get_reputation = uplink.ctx.Reputation.get_reputation(parsed_UID)
|
||||
|
||||
if parsed_chan != gconfig.SALON_JAIL:
|
||||
p.send2socket(f":{gconfig.SERVICE_ID} MODE {parsed_chan} +b ~security-group:unknown-users")
|
||||
p.send2socket(f":{gconfig.SERVICE_ID} MODE {parsed_chan} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
|
||||
await p.send2socket(f":{gconfig.SERVICE_ID} MODE {parsed_chan} +b ~security-group:unknown-users")
|
||||
await p.send2socket(f":{gconfig.SERVICE_ID} MODE {parsed_chan} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
|
||||
|
||||
if get_reputation is not None:
|
||||
isWebirc = get_reputation.isWebirc
|
||||
|
||||
if not isWebirc:
|
||||
if parsed_chan != gconfig.SALON_JAIL:
|
||||
p.send_sapart(nick_to_sapart=get_reputation.nickname, channel_name=parsed_chan)
|
||||
await p.send_sapart(nick_to_sapart=get_reputation.nickname, channel_name=parsed_chan)
|
||||
|
||||
if confmodel.reputation_ban_all_chan == 1 and not isWebirc:
|
||||
if parsed_chan != gconfig.SALON_JAIL:
|
||||
p.send2socket(f":{gconfig.SERVICE_ID} MODE {parsed_chan} +b {get_reputation.nickname}!*@*")
|
||||
p.send2socket(f":{gconfig.SERVICE_ID} KICK {parsed_chan} {get_reputation.nickname}")
|
||||
await p.send2socket(f":{gconfig.SERVICE_ID} MODE {parsed_chan} +b {get_reputation.nickname}!*@*")
|
||||
await p.send2socket(f":{gconfig.SERVICE_ID} KICK {parsed_chan} {get_reputation.nickname}")
|
||||
|
||||
irc.Logs.debug(f'SJOIN parsed_uid : {parsed_UID}')
|
||||
uplink.ctx.Logs.debug(f'SJOIN parsed_uid : {parsed_UID}')
|
||||
|
||||
def handle_on_slog(uplink: 'Defender', srvmsg: list[str]):
|
||||
"""Handling SLOG messages
|
||||
@@ -122,27 +123,27 @@ def handle_on_slog(uplink: 'Defender', srvmsg: list[str]):
|
||||
"""
|
||||
['@unrealircd...', ':001', 'SLOG', 'info', 'blacklist', 'BLACKLIST_HIT', ':[Blacklist]', 'IP', '162.x.x.x', 'matches', 'blacklist', 'dronebl', '(dnsbl.dronebl.org/reply=6)']
|
||||
|
||||
if not uplink.Base.is_valid_ip(srvmsg[8]):
|
||||
if not uplink.ctx.Base.is_valid_ip(srvmsg[8]):
|
||||
return None
|
||||
|
||||
# if self.ModConfig.local_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||
# if self.mod_config.local_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||
# self.localscan_remote_ip.append(cmd[7])
|
||||
|
||||
# if self.ModConfig.psutil_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||
# if self.mod_config.psutil_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||
# self.psutil_remote_ip.append(cmd[7])
|
||||
|
||||
# if self.ModConfig.abuseipdb_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||
# if self.mod_config.abuseipdb_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||
# self.abuseipdb_remote_ip.append(cmd[7])
|
||||
|
||||
# if self.ModConfig.freeipapi_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||
# if self.mod_config.freeipapi_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||
# self.freeipapi_remote_ip.append(cmd[7])
|
||||
|
||||
# if self.ModConfig.cloudfilt_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||
# if self.mod_config.cloudfilt_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||
# self.cloudfilt_remote_ip.append(cmd[7])
|
||||
|
||||
return None
|
||||
|
||||
def handle_on_nick(uplink: 'Defender', srvmsg: list[str]):
|
||||
async def handle_on_nick(uplink: 'Defender', srvmsg: list[str]):
|
||||
"""Handle nickname changes.
|
||||
>>> srvmsg = ['@unrealircd.org...', ':001MZQ0RB', 'NICK', 'newnickname', '1754663712']
|
||||
>>> [':97KAAAAAC', 'NICK', 'testinspir', '1757360740']
|
||||
@@ -151,22 +152,22 @@ def handle_on_nick(uplink: 'Defender', srvmsg: list[str]):
|
||||
srvmsg (list[str]): The Server MSG
|
||||
confmodel (ModConfModel): The Module Configuration
|
||||
"""
|
||||
p = uplink.Protocol
|
||||
p = uplink.ctx.Irc.Protocol
|
||||
u, new_nickname, timestamp = p.parse_nick(srvmsg)
|
||||
|
||||
if u is None:
|
||||
uplink.Logs.error(f"[USER OBJ ERROR {timestamp}] - {srvmsg}")
|
||||
uplink.ctx.Logs.error(f"[USER OBJ ERROR {timestamp}] - {srvmsg}")
|
||||
return None
|
||||
|
||||
uid = u.uid
|
||||
confmodel = uplink.ModConfig
|
||||
confmodel = uplink.mod_config
|
||||
|
||||
get_reputation = uplink.Reputation.get_reputation(uid)
|
||||
jail_salon = uplink.Config.SALON_JAIL
|
||||
service_id = uplink.Config.SERVICE_ID
|
||||
get_reputation = uplink.ctx.Reputation.get_reputation(uid)
|
||||
jail_salon = uplink.ctx.Config.SALON_JAIL
|
||||
service_id = uplink.ctx.Config.SERVICE_ID
|
||||
|
||||
if get_reputation is None:
|
||||
uplink.Logs.debug(f'This UID: {uid} is not listed in the reputation dataclass')
|
||||
uplink.ctx.Logs.debug(f'This UID: {uid} is not listed in the reputation dataclass')
|
||||
return None
|
||||
|
||||
# Update the new nickname
|
||||
@@ -176,42 +177,42 @@ def handle_on_nick(uplink: 'Defender', srvmsg: list[str]):
|
||||
|
||||
# If ban in all channel is ON then unban old nickname an ban the new nickname
|
||||
if confmodel.reputation_ban_all_chan == 1:
|
||||
for chan in uplink.Channel.UID_CHANNEL_DB:
|
||||
for chan in uplink.ctx.Channel.UID_CHANNEL_DB:
|
||||
if chan.name != jail_salon:
|
||||
p.send2socket(f":{service_id} MODE {chan.name} -b {oldnick}!*@*")
|
||||
p.send2socket(f":{service_id} MODE {chan.name} +b {newnickname}!*@*")
|
||||
await p.send2socket(f":{service_id} MODE {chan.name} -b {oldnick}!*@*")
|
||||
await p.send2socket(f":{service_id} MODE {chan.name} +b {newnickname}!*@*")
|
||||
|
||||
def handle_on_quit(uplink: 'Defender', srvmsg: list[str]):
|
||||
async def handle_on_quit(uplink: 'Defender', srvmsg: list[str]):
|
||||
"""Handle on quit message
|
||||
>>> srvmsg = ['@unrealircd.org...', ':001MZQ0RB', 'QUIT', ':Quit:', 'quit message']
|
||||
Args:
|
||||
uplink (Irc): The Defender Module instance
|
||||
srvmsg (list[str]): The Server MSG
|
||||
"""
|
||||
p = uplink.Protocol
|
||||
p = uplink.ctx.Irc.Protocol
|
||||
userobj, reason = p.parse_quit(srvmsg)
|
||||
confmodel = uplink.ModConfig
|
||||
confmodel = uplink.mod_config
|
||||
|
||||
if userobj is None:
|
||||
uplink.Logs.debug(f"This UID do not exist anymore: {srvmsg}")
|
||||
uplink.ctx.Logs.debug(f"This UID do not exist anymore: {srvmsg}")
|
||||
return None
|
||||
|
||||
ban_all_chan = uplink.Base.int_if_possible(confmodel.reputation_ban_all_chan)
|
||||
jail_salon = uplink.Config.SALON_JAIL
|
||||
service_id = uplink.Config.SERVICE_ID
|
||||
get_user_reputation = uplink.Reputation.get_reputation(userobj.uid)
|
||||
ban_all_chan = uplink.ctx.Base.int_if_possible(confmodel.reputation_ban_all_chan)
|
||||
jail_salon = uplink.ctx.Config.SALON_JAIL
|
||||
service_id = uplink.ctx.Config.SERVICE_ID
|
||||
get_user_reputation = uplink.ctx.Reputation.get_reputation(userobj.uid)
|
||||
|
||||
if get_user_reputation is not None:
|
||||
final_nickname = get_user_reputation.nickname
|
||||
for chan in uplink.Channel.UID_CHANNEL_DB:
|
||||
for chan in uplink.ctx.Channel.UID_CHANNEL_DB:
|
||||
if chan.name != jail_salon and ban_all_chan == 1:
|
||||
p.send2socket(f":{service_id} MODE {chan.name} -b {final_nickname}!*@*")
|
||||
uplink.Logs.debug(f"Mode -b {final_nickname} on channel {chan.name}")
|
||||
await p.send2socket(f":{service_id} MODE {chan.name} -b {final_nickname}!*@*")
|
||||
uplink.ctx.Logs.debug(f"Mode -b {final_nickname} on channel {chan.name}")
|
||||
|
||||
uplink.Reputation.delete(userobj.uid)
|
||||
uplink.Logs.debug(f"Client {get_user_reputation.nickname} has been removed from Reputation local DB")
|
||||
uplink.ctx.Reputation.delete(userobj.uid)
|
||||
uplink.ctx.Logs.debug(f"Client {get_user_reputation.nickname} has been removed from Reputation local DB")
|
||||
|
||||
def handle_on_uid(uplink: 'Defender', srvmsg: list[str]):
|
||||
async def handle_on_uid(uplink: 'Defender', srvmsg: list[str]):
|
||||
"""_summary_
|
||||
>>> ['@s2s-md...', ':001', 'UID', 'nickname', '0', '1754675249', '...', '125-168-141-239.hostname.net', '001BAPN8M',
|
||||
'0', '+iwx', '*', '32001BBE.25ACEFE7.429FE90D.IP', 'ZA2ic7w==', ':realname']
|
||||
@@ -220,10 +221,10 @@ def handle_on_uid(uplink: 'Defender', srvmsg: list[str]):
|
||||
uplink (Defender): The Defender instance
|
||||
srvmsg (list[str]): The Server MSG
|
||||
"""
|
||||
_User = uplink.Protocol.parse_uid(srvmsg)
|
||||
gconfig = uplink.Config
|
||||
irc = uplink.Irc
|
||||
confmodel = uplink.ModConfig
|
||||
irc = uplink.ctx.Irc
|
||||
_User = irc.Protocol.parse_uid(srvmsg)
|
||||
gconfig = uplink.ctx.Config
|
||||
confmodel = uplink.mod_config
|
||||
|
||||
# If Init then do nothing
|
||||
if gconfig.DEFENDER_INIT == 1:
|
||||
@@ -231,7 +232,7 @@ def handle_on_uid(uplink: 'Defender', srvmsg: list[str]):
|
||||
|
||||
# Get User information
|
||||
if _User is None:
|
||||
irc.Logs.warning(f'Error when parsing UID', exc_info=True)
|
||||
uplink.ctx.Logs.warning(f'Error when parsing UID', exc_info=True)
|
||||
return
|
||||
|
||||
# If user is not service or IrcOp then scan them
|
||||
@@ -250,38 +251,38 @@ def handle_on_uid(uplink: 'Defender', srvmsg: list[str]):
|
||||
if not match(r'^.*[S|o?].*$', _User.umodes):
|
||||
if reputation_flag == 1 and _User.score_connexion <= reputation_seuil:
|
||||
# currentDateTime = self.Base.get_datetime()
|
||||
irc.Reputation.insert(
|
||||
irc.Loader.Definition.MReputation(
|
||||
uplink.ctx.Reputation.insert(
|
||||
uplink.ctx.Definition.MReputation(
|
||||
**_User.to_dict(),
|
||||
secret_code=irc.Utils.generate_random_string(8)
|
||||
secret_code=uplink.ctx.Utils.generate_random_string(8)
|
||||
)
|
||||
)
|
||||
if irc.Reputation.is_exist(_User.uid):
|
||||
if uplink.ctx.Reputation.is_exist(_User.uid):
|
||||
if reputation_flag == 1 and _User.score_connexion <= reputation_seuil:
|
||||
action_add_reputation_sanctions(uplink, _User.uid)
|
||||
irc.Logs.info(f'[REPUTATION] Reputation system ON (Nickname: {_User.nickname}, uid: {_User.uid})')
|
||||
await action_add_reputation_sanctions(uplink, _User.uid)
|
||||
uplink.ctx.Logs.info(f'[REPUTATION] Reputation system ON (Nickname: {_User.nickname}, uid: {_User.uid})')
|
||||
|
||||
####################
|
||||
# ACTION FUNCTIONS #
|
||||
####################
|
||||
# [:<sid>] UID <uid> <ts> <nick> <real-host> <displayed-host> <real-user> <ip> <signon> <modes> [<mode-parameters>]+ :<real>
|
||||
# [:<sid>] UID nickname hopcount timestamp username hostname uid servicestamp umodes virthost cloakedhost ip :gecos
|
||||
def action_on_flood(uplink: 'Defender', srvmsg: list[str]):
|
||||
async def action_on_flood(uplink: 'Defender', srvmsg: list[str]):
|
||||
|
||||
confmodel = uplink.ModConfig
|
||||
confmodel = uplink.mod_config
|
||||
if confmodel.flood == 0:
|
||||
return None
|
||||
|
||||
irc = uplink.Irc
|
||||
gconfig = uplink.Config
|
||||
p = uplink.Protocol
|
||||
irc = uplink.ctx.Irc
|
||||
gconfig = uplink.ctx.Config
|
||||
p = irc.Protocol
|
||||
flood_users = uplink.Schemas.DB_FLOOD_USERS
|
||||
|
||||
user_trigger = str(srvmsg[1]).replace(':','')
|
||||
channel = srvmsg[3]
|
||||
User = irc.User.get_user(user_trigger)
|
||||
User = uplink.ctx.User.get_user(user_trigger)
|
||||
|
||||
if User is None or not irc.Channel.is_valid_channel(channel_to_check=channel):
|
||||
if User is None or not uplink.ctx.Channel.is_valid_channel(channel_to_check=channel):
|
||||
return
|
||||
|
||||
flood_time = confmodel.flood_time
|
||||
@@ -294,7 +295,7 @@ def action_on_flood(uplink: 'Defender', srvmsg: list[str]):
|
||||
|
||||
get_detected_uid = User.uid
|
||||
get_detected_nickname = User.nickname
|
||||
unixtime = irc.Utils.get_unixtime()
|
||||
unixtime = uplink.ctx.Utils.get_unixtime()
|
||||
get_diff_secondes = 0
|
||||
|
||||
def get_flood_user(uid: str) -> Optional[FloodUser]:
|
||||
@@ -315,29 +316,29 @@ def action_on_flood(uplink: 'Defender', srvmsg: list[str]):
|
||||
fu.nbr_msg = 0
|
||||
get_diff_secondes = unixtime - fu.first_msg_time
|
||||
elif fu.nbr_msg > flood_message:
|
||||
irc.Logs.info('system de flood detecté')
|
||||
p.send_priv_msg(
|
||||
uplink.ctx.Logs.info('system de flood detecté')
|
||||
await p.send_priv_msg(
|
||||
nick_from=dnickname,
|
||||
msg=f"{color_red} {color_bold} Flood detected. Apply the +m mode (Ô_o)",
|
||||
channel=channel
|
||||
)
|
||||
p.send2socket(f":{service_id} MODE {channel} +m")
|
||||
irc.Logs.info(f'FLOOD Détecté sur {get_detected_nickname} mode +m appliqué sur le salon {channel}')
|
||||
await p.send2socket(f":{service_id} MODE {channel} +m")
|
||||
uplink.ctx.Logs.info(f'FLOOD Détecté sur {get_detected_nickname} mode +m appliqué sur le salon {channel}')
|
||||
fu.nbr_msg = 0
|
||||
fu.first_msg_time = unixtime
|
||||
irc.Base.create_timer(flood_timer, dthreads.timer_release_mode_mute, (uplink, 'mode-m', channel))
|
||||
uplink.ctx.Base.create_asynctask(dthreads.coro_release_mode_mute(uplink, 'mode-m', channel))
|
||||
|
||||
def action_add_reputation_sanctions(uplink: 'Defender', jailed_uid: str ):
|
||||
async def action_add_reputation_sanctions(uplink: 'Defender', jailed_uid: str ):
|
||||
|
||||
irc = uplink.Irc
|
||||
gconfig = uplink.Config
|
||||
p = uplink.Protocol
|
||||
confmodel = uplink.ModConfig
|
||||
irc = uplink.ctx.Irc
|
||||
gconfig = uplink.ctx.Config
|
||||
p = irc.Protocol
|
||||
confmodel = uplink.mod_config
|
||||
|
||||
get_reputation = irc.Reputation.get_reputation(jailed_uid)
|
||||
get_reputation = uplink.ctx.Reputation.get_reputation(jailed_uid)
|
||||
|
||||
if get_reputation is None:
|
||||
irc.Logs.warning(f'UID {jailed_uid} has not been found')
|
||||
uplink.ctx.Logs.warning(f'UID {jailed_uid} has not been found')
|
||||
return
|
||||
|
||||
salon_logs = gconfig.SERVICE_CHANLOG
|
||||
@@ -357,33 +358,33 @@ def action_add_reputation_sanctions(uplink: 'Defender', jailed_uid: str ):
|
||||
|
||||
if not get_reputation.isWebirc:
|
||||
# Si le user ne vient pas de webIrc
|
||||
p.send_sajoin(nick_to_sajoin=jailed_nickname, channel_name=salon_jail)
|
||||
p.send_priv_msg(nick_from=gconfig.SERVICE_NICKNAME,
|
||||
await p.send_sajoin(nick_to_sajoin=jailed_nickname, channel_name=salon_jail)
|
||||
await p.send_priv_msg(nick_from=gconfig.SERVICE_NICKNAME,
|
||||
msg=f" [{color_red} REPUTATION {nogc}] : Connexion de {jailed_nickname} ({jailed_score}) ==> {salon_jail}",
|
||||
channel=salon_logs
|
||||
)
|
||||
p.send_notice(
|
||||
await p.send_notice(
|
||||
nick_from=gconfig.SERVICE_NICKNAME,
|
||||
nick_to=jailed_nickname,
|
||||
msg=f"[{color_red} {jailed_nickname} {color_black}] : Merci de tapez la commande suivante {color_bold}{service_prefix}code {code}{color_bold}"
|
||||
)
|
||||
if reputation_ban_all_chan == 1:
|
||||
for chan in irc.Channel.UID_CHANNEL_DB:
|
||||
for chan in uplink.ctx.Channel.UID_CHANNEL_DB:
|
||||
if chan.name != salon_jail:
|
||||
p.send2socket(f":{service_id} MODE {chan.name} +b {jailed_nickname}!*@*")
|
||||
p.send2socket(f":{service_id} KICK {chan.name} {jailed_nickname}")
|
||||
await p.send2socket(f":{service_id} MODE {chan.name} +b {jailed_nickname}!*@*")
|
||||
await p.send2socket(f":{service_id} KICK {chan.name} {jailed_nickname}")
|
||||
|
||||
irc.Logs.info(f"[REPUTATION] {jailed_nickname} jailed (UID: {jailed_uid}, score: {jailed_score})")
|
||||
uplink.ctx.Logs.info(f"[REPUTATION] {jailed_nickname} jailed (UID: {jailed_uid}, score: {jailed_score})")
|
||||
else:
|
||||
irc.Logs.info(f"[REPUTATION] {jailed_nickname} skipped (trusted or WebIRC)")
|
||||
irc.Reputation.delete(jailed_uid)
|
||||
uplink.ctx.Logs.info(f"[REPUTATION] {jailed_nickname} skipped (trusted or WebIRC)")
|
||||
uplink.ctx.Reputation.delete(jailed_uid)
|
||||
|
||||
def action_apply_reputation_santions(uplink: 'Defender') -> None:
|
||||
async def action_apply_reputation_santions(uplink: 'Defender') -> None:
|
||||
|
||||
irc = uplink.Irc
|
||||
gconfig = uplink.Config
|
||||
p = uplink.Protocol
|
||||
confmodel = uplink.ModConfig
|
||||
irc = uplink.ctx.Irc
|
||||
gconfig = uplink.ctx.Config
|
||||
p = irc.Protocol
|
||||
confmodel = uplink.mod_config
|
||||
|
||||
reputation_flag = confmodel.reputation
|
||||
reputation_timer = confmodel.reputation_timer
|
||||
@@ -396,36 +397,36 @@ def action_apply_reputation_santions(uplink: 'Defender') -> None:
|
||||
salon_jail = gconfig.SALON_JAIL
|
||||
uid_to_clean = []
|
||||
|
||||
if reputation_flag == 0 or reputation_timer == 0 or not irc.Reputation.UID_REPUTATION_DB:
|
||||
if reputation_flag == 0 or reputation_timer == 0 or not uplink.ctx.Reputation.UID_REPUTATION_DB:
|
||||
return None
|
||||
|
||||
for user in irc.Reputation.UID_REPUTATION_DB:
|
||||
for user in uplink.ctx.Reputation.UID_REPUTATION_DB:
|
||||
if not user.isWebirc: # Si il ne vient pas de WebIRC
|
||||
if irc.User.get_user_uptime_in_minutes(user.uid) >= reputation_timer and int(user.score_connexion) <= int(reputation_seuil):
|
||||
p.send_priv_msg(
|
||||
if uplink.ctx.User.get_user_uptime_in_minutes(user.uid) >= reputation_timer and int(user.score_connexion) <= int(reputation_seuil):
|
||||
await p.send_priv_msg(
|
||||
nick_from=service_id,
|
||||
msg=f"[{color_red} REPUTATION {nogc}] : Action sur {user.nickname} aprés {str(reputation_timer)} minutes d'inactivité",
|
||||
channel=dchanlog
|
||||
)
|
||||
p.send2socket(f":{service_id} KILL {user.nickname} After {str(reputation_timer)} minutes of inactivity you should reconnect and type the password code")
|
||||
p.send2socket(f":{gconfig.SERVEUR_LINK} REPUTATION {user.remote_ip} 0")
|
||||
await p.send2socket(f":{service_id} KILL {user.nickname} After {str(reputation_timer)} minutes of inactivity you should reconnect and type the password code")
|
||||
await p.send2socket(f":{gconfig.SERVEUR_LINK} REPUTATION {user.remote_ip} 0")
|
||||
|
||||
irc.Logs.info(f"Nickname: {user.nickname} KILLED after {str(reputation_timer)} minutes of inactivity")
|
||||
uplink.ctx.Logs.info(f"Nickname: {user.nickname} KILLED after {str(reputation_timer)} minutes of inactivity")
|
||||
uid_to_clean.append(user.uid)
|
||||
|
||||
for uid in uid_to_clean:
|
||||
# Suppression des éléments dans {UID_DB} et {REPUTATION_DB}
|
||||
for chan in irc.Channel.UID_CHANNEL_DB:
|
||||
for chan in uplink.ctx.Channel.UID_CHANNEL_DB:
|
||||
if chan.name != salon_jail and ban_all_chan == 1:
|
||||
get_user_reputation = irc.Reputation.get_reputation(uid)
|
||||
p.send2socket(f":{service_id} MODE {chan.name} -b {get_user_reputation.nickname}!*@*")
|
||||
get_user_reputation = uplink.ctx.Reputation.get_reputation(uid)
|
||||
await p.send2socket(f":{service_id} MODE {chan.name} -b {get_user_reputation.nickname}!*@*")
|
||||
|
||||
# Lorsqu'un utilisateur quitte, il doit être supprimé de {UID_DB}.
|
||||
irc.Channel.delete_user_from_all_channel(uid)
|
||||
irc.Reputation.delete(uid)
|
||||
irc.User.delete(uid)
|
||||
uplink.ctx.Channel.delete_user_from_all_channel(uid)
|
||||
uplink.ctx.Reputation.delete(uid)
|
||||
uplink.ctx.User.delete(uid)
|
||||
|
||||
def action_scan_client_with_cloudfilt(uplink: 'Defender', user_model: 'MUser') -> Optional[dict[str, str]]:
|
||||
async def action_scan_client_with_cloudfilt(uplink: 'Defender', user_model: 'MUser') -> Optional[dict[str, str]]:
|
||||
"""Analyse l'ip avec cloudfilt
|
||||
Cette methode devra etre lancer toujours via un thread ou un timer.
|
||||
Args:
|
||||
@@ -440,19 +441,19 @@ def action_scan_client_with_cloudfilt(uplink: 'Defender', user_model: 'MUser') -
|
||||
username = user_model.username
|
||||
hostname = user_model.hostname
|
||||
nickname = user_model.nickname
|
||||
p = uplink.Protocol
|
||||
p = uplink.ctx.Irc.Protocol
|
||||
|
||||
if remote_ip in uplink.Config.WHITELISTED_IP:
|
||||
if remote_ip in uplink.ctx.Config.WHITELISTED_IP:
|
||||
return None
|
||||
if uplink.ModConfig.cloudfilt_scan == 0:
|
||||
if uplink.mod_config.cloudfilt_scan == 0:
|
||||
return None
|
||||
if uplink.cloudfilt_key == '':
|
||||
return None
|
||||
|
||||
service_id = uplink.Config.SERVICE_ID
|
||||
service_chanlog = uplink.Config.SERVICE_CHANLOG
|
||||
color_red = uplink.Config.COLORS.red
|
||||
nogc = uplink.Config.COLORS.nogc
|
||||
service_id = uplink.ctx.Config.SERVICE_ID
|
||||
service_chanlog = uplink.ctx.Config.SERVICE_CHANLOG
|
||||
color_red = uplink.ctx.Config.COLORS.red
|
||||
nogc = uplink.ctx.Config.COLORS.nogc
|
||||
|
||||
url = "https://developers18334.cloudfilt.com/"
|
||||
|
||||
@@ -466,7 +467,7 @@ def action_scan_client_with_cloudfilt(uplink: 'Defender', user_model: 'MUser') -
|
||||
decoded_response: dict = loads(response.text)
|
||||
status_code = response.status_code
|
||||
if status_code != 200:
|
||||
uplink.Logs.warning(f'Error connecting to cloudfilt API | Code: {str(status_code)}')
|
||||
uplink.ctx.Logs.warning(f'Error connecting to cloudfilt API | Code: {str(status_code)}')
|
||||
return
|
||||
|
||||
result = {
|
||||
@@ -479,22 +480,22 @@ def action_scan_client_with_cloudfilt(uplink: 'Defender', user_model: 'MUser') -
|
||||
# pseudo!ident@host
|
||||
fullname = f'{nickname}!{username}@{hostname}'
|
||||
|
||||
p.send_priv_msg(
|
||||
await p.send_priv_msg(
|
||||
nick_from=service_id,
|
||||
msg=f"[ {color_red}CLOUDFILT_SCAN{nogc} ] : Connexion de {fullname} ({remote_ip}) ==> Host: {str(result['host'])} | country: {str(result['countryiso'])} | listed: {str(result['listed'])} | listed by : {str(result['listed_by'])}",
|
||||
channel=service_chanlog)
|
||||
|
||||
uplink.Logs.debug(f"[CLOUDFILT SCAN] ({fullname}) connected from ({result['countryiso']}), Listed: {result['listed']}, by: {result['listed_by']}")
|
||||
uplink.ctx.Logs.debug(f"[CLOUDFILT SCAN] ({fullname}) connected from ({result['countryiso']}), Listed: {result['listed']}, by: {result['listed_by']}")
|
||||
|
||||
if result['listed']:
|
||||
p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.Config.GLINE_DURATION} Your connexion is listed as dangerous {str(result['listed'])} {str(result['listed_by'])} - detected by cloudfilt")
|
||||
uplink.Logs.debug(f"[CLOUDFILT SCAN GLINE] Dangerous connection ({fullname}) from ({result['countryiso']}) Listed: {result['listed']}, by: {result['listed_by']}")
|
||||
await p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.ctx.Config.GLINE_DURATION} Your connexion is listed as dangerous {str(result['listed'])} {str(result['listed_by'])} - detected by cloudfilt")
|
||||
uplink.ctx.Logs.debug(f"[CLOUDFILT SCAN GLINE] Dangerous connection ({fullname}) from ({result['countryiso']}) Listed: {result['listed']}, by: {result['listed_by']}")
|
||||
|
||||
response.close()
|
||||
|
||||
return result
|
||||
|
||||
def action_scan_client_with_freeipapi(uplink: 'Defender', user_model: 'MUser') -> Optional[dict[str, str]]:
|
||||
async def action_scan_client_with_freeipapi(uplink: 'Defender', user_model: 'MUser') -> Optional[dict[str, str]]:
|
||||
"""Analyse l'ip avec Freeipapi
|
||||
Cette methode devra etre lancer toujours via un thread ou un timer.
|
||||
Args:
|
||||
@@ -504,21 +505,21 @@ def action_scan_client_with_freeipapi(uplink: 'Defender', user_model: 'MUser') -
|
||||
dict[str, any] | None: les informations du provider
|
||||
keys : 'countryCode', 'isProxy'
|
||||
"""
|
||||
p = uplink.Protocol
|
||||
p = uplink.ctx.Irc.Protocol
|
||||
remote_ip = user_model.remote_ip
|
||||
username = user_model.username
|
||||
hostname = user_model.hostname
|
||||
nickname = user_model.nickname
|
||||
|
||||
if remote_ip in uplink.Config.WHITELISTED_IP:
|
||||
if remote_ip in uplink.ctx.Config.WHITELISTED_IP:
|
||||
return None
|
||||
if uplink.ModConfig.freeipapi_scan == 0:
|
||||
if uplink.mod_config.freeipapi_scan == 0:
|
||||
return None
|
||||
|
||||
service_id = uplink.Config.SERVICE_ID
|
||||
service_chanlog = uplink.Config.SERVICE_CHANLOG
|
||||
color_red = uplink.Config.COLORS.red
|
||||
nogc = uplink.Config.COLORS.nogc
|
||||
service_id = uplink.ctx.Config.SERVICE_ID
|
||||
service_chanlog = uplink.ctx.Config.SERVICE_CHANLOG
|
||||
color_red = uplink.ctx.Config.COLORS.red
|
||||
nogc = uplink.ctx.Config.COLORS.nogc
|
||||
|
||||
url = f'https://freeipapi.com/api/json/{remote_ip}'
|
||||
|
||||
@@ -533,10 +534,10 @@ def action_scan_client_with_freeipapi(uplink: 'Defender', user_model: 'MUser') -
|
||||
|
||||
status_code = response.status_code
|
||||
if status_code == 429:
|
||||
uplink.Logs.warning('Too Many Requests - The rate limit for the API has been exceeded.')
|
||||
uplink.ctx.Logs.warning('Too Many Requests - The rate limit for the API has been exceeded.')
|
||||
return None
|
||||
elif status_code != 200:
|
||||
uplink.Logs.warning(f'status code = {str(status_code)}')
|
||||
uplink.ctx.Logs.warning(f'status code = {str(status_code)}')
|
||||
return None
|
||||
|
||||
result = {
|
||||
@@ -547,21 +548,21 @@ def action_scan_client_with_freeipapi(uplink: 'Defender', user_model: 'MUser') -
|
||||
# pseudo!ident@host
|
||||
fullname = f'{nickname}!{username}@{hostname}'
|
||||
|
||||
p.send_priv_msg(
|
||||
await p.send_priv_msg(
|
||||
nick_from=service_id,
|
||||
msg=f"[ {color_red}FREEIPAPI_SCAN{nogc} ] : Connexion de {fullname} ({remote_ip}) ==> Proxy: {str(result['isProxy'])} | Country : {str(result['countryCode'])}",
|
||||
channel=service_chanlog)
|
||||
uplink.Logs.debug(f"[FREEIPAPI SCAN] ({fullname}) connected from ({result['countryCode']}), Proxy: {result['isProxy']}")
|
||||
uplink.ctx.Logs.debug(f"[FREEIPAPI SCAN] ({fullname}) connected from ({result['countryCode']}), Proxy: {result['isProxy']}")
|
||||
|
||||
if result['isProxy']:
|
||||
p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.Config.GLINE_DURATION} This server do not allow proxy connexions {str(result['isProxy'])} - detected by freeipapi")
|
||||
uplink.Logs.debug(f"[FREEIPAPI SCAN GLINE] Server do not allow proxy connexions {result['isProxy']}")
|
||||
await p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.ctx.Config.GLINE_DURATION} This server do not allow proxy connexions {str(result['isProxy'])} - detected by freeipapi")
|
||||
uplink.ctx.Logs.debug(f"[FREEIPAPI SCAN GLINE] Server do not allow proxy connexions {result['isProxy']}")
|
||||
|
||||
response.close()
|
||||
|
||||
return result
|
||||
|
||||
def action_scan_client_with_abuseipdb(uplink: 'Defender', user_model: 'MUser') -> Optional[dict[str, str]]:
|
||||
async def action_scan_client_with_abuseipdb(uplink: 'Defender', user_model: 'MUser') -> Optional[dict[str, str]]:
|
||||
"""Analyse l'ip avec AbuseIpDB
|
||||
Cette methode devra etre lancer toujours via un thread ou un timer.
|
||||
Args:
|
||||
@@ -571,15 +572,15 @@ def action_scan_client_with_abuseipdb(uplink: 'Defender', user_model: 'MUser') -
|
||||
Returns:
|
||||
dict[str, str] | None: les informations du provider
|
||||
"""
|
||||
p = uplink.Protocol
|
||||
p = uplink.ctx.Irc.Protocol
|
||||
remote_ip = user_model.remote_ip
|
||||
username = user_model.username
|
||||
hostname = user_model.hostname
|
||||
nickname = user_model.nickname
|
||||
|
||||
if remote_ip in uplink.Config.WHITELISTED_IP:
|
||||
if remote_ip in uplink.ctx.Config.WHITELISTED_IP:
|
||||
return None
|
||||
if uplink.ModConfig.abuseipdb_scan == 0:
|
||||
if uplink.mod_config.abuseipdb_scan == 0:
|
||||
return None
|
||||
|
||||
if uplink.abuseipdb_key == '':
|
||||
@@ -611,81 +612,81 @@ def action_scan_client_with_abuseipdb(uplink: 'Defender', user_model: 'MUser') -
|
||||
'totalReports': decoded_response.get('data', {}).get('totalReports', 0)
|
||||
}
|
||||
|
||||
service_id = uplink.Config.SERVICE_ID
|
||||
service_chanlog = uplink.Config.SERVICE_CHANLOG
|
||||
color_red = uplink.Config.COLORS.red
|
||||
nogc = uplink.Config.COLORS.nogc
|
||||
service_id = uplink.ctx.Config.SERVICE_ID
|
||||
service_chanlog = uplink.ctx.Config.SERVICE_CHANLOG
|
||||
color_red = uplink.ctx.Config.COLORS.red
|
||||
nogc = uplink.ctx.Config.COLORS.nogc
|
||||
|
||||
# pseudo!ident@host
|
||||
fullname = f'{nickname}!{username}@{hostname}'
|
||||
|
||||
p.send_priv_msg(
|
||||
await p.send_priv_msg(
|
||||
nick_from=service_id,
|
||||
msg=f"[ {color_red}ABUSEIPDB_SCAN{nogc} ] : Connexion de {fullname} ({remote_ip}) ==> Score: {str(result['score'])} | Country : {result['country']} | Tor : {str(result['isTor'])} | Total Reports : {str(result['totalReports'])}",
|
||||
channel=service_chanlog
|
||||
)
|
||||
uplink.Logs.debug(f"[ABUSEIPDB SCAN] ({fullname}) connected from ({result['country']}), Score: {result['score']}, Tor: {result['isTor']}")
|
||||
uplink.ctx.Logs.debug(f"[ABUSEIPDB SCAN] ({fullname}) connected from ({result['country']}), Score: {result['score']}, Tor: {result['isTor']}")
|
||||
|
||||
if result['isTor']:
|
||||
p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.Config.GLINE_DURATION} This server do not allow Tor connexions {str(result['isTor'])} - Detected by Abuseipdb")
|
||||
uplink.Logs.debug(f"[ABUSEIPDB SCAN GLINE] Server do not allow Tor connections Tor: {result['isTor']}, Score: {result['score']}")
|
||||
await p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.ctx.Config.GLINE_DURATION} This server do not allow Tor connexions {str(result['isTor'])} - Detected by Abuseipdb")
|
||||
uplink.ctx.Logs.debug(f"[ABUSEIPDB SCAN GLINE] Server do not allow Tor connections Tor: {result['isTor']}, Score: {result['score']}")
|
||||
elif result['score'] >= 95:
|
||||
p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.Config.GLINE_DURATION} You were banned from this server because your abuse score is = {str(result['score'])} - Detected by Abuseipdb")
|
||||
uplink.Logs.debug(f"[ABUSEIPDB SCAN GLINE] Server do not high risk connections Country: {result['country']}, Score: {result['score']}")
|
||||
await p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.ctx.Config.GLINE_DURATION} You were banned from this server because your abuse score is = {str(result['score'])} - Detected by Abuseipdb")
|
||||
uplink.ctx.Logs.debug(f"[ABUSEIPDB SCAN GLINE] Server do not high risk connections Country: {result['country']}, Score: {result['score']}")
|
||||
|
||||
response.close()
|
||||
|
||||
return result
|
||||
|
||||
def action_scan_client_with_local_socket(uplink: 'Defender', user_model: 'MUser'):
|
||||
async def action_scan_client_with_local_socket(uplink: 'Defender', user_model: 'MUser'):
|
||||
"""local_scan
|
||||
|
||||
Args:
|
||||
uplink (Defender): Defender instance object
|
||||
user_model (MUser): l'objet User qui contient l'ip
|
||||
"""
|
||||
p = uplink.Protocol
|
||||
p = uplink.ctx.Irc.Protocol
|
||||
remote_ip = user_model.remote_ip
|
||||
username = user_model.username
|
||||
hostname = user_model.hostname
|
||||
nickname = user_model.nickname
|
||||
fullname = f'{nickname}!{username}@{hostname}'
|
||||
|
||||
if remote_ip in uplink.Config.WHITELISTED_IP:
|
||||
if remote_ip in uplink.ctx.Config.WHITELISTED_IP:
|
||||
return None
|
||||
|
||||
for port in uplink.Config.PORTS_TO_SCAN:
|
||||
for port in uplink.ctx.Config.PORTS_TO_SCAN:
|
||||
try:
|
||||
newSocket = ''
|
||||
newSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM or socket.SOCK_NONBLOCK)
|
||||
newSocket.settimeout(0.5)
|
||||
|
||||
connection = (remote_ip, uplink.Base.int_if_possible(port))
|
||||
connection = (remote_ip, uplink.ctx.Base.int_if_possible(port))
|
||||
newSocket.connect(connection)
|
||||
|
||||
p.send_priv_msg(
|
||||
nick_from=uplink.Config.SERVICE_NICKNAME,
|
||||
msg=f"[ {uplink.Config.COLORS.red}PROXY_SCAN{uplink.Config.COLORS.nogc} ] {fullname} ({remote_ip}) : Port [{str(port)}] ouvert sur l'adresse ip [{remote_ip}]",
|
||||
channel=uplink.Config.SERVICE_CHANLOG
|
||||
await p.send_priv_msg(
|
||||
nick_from=uplink.ctx.Config.SERVICE_NICKNAME,
|
||||
msg=f"[ {uplink.ctx.Config.COLORS.red}PROXY_SCAN{uplink.ctx.Config.COLORS.nogc} ] {fullname} ({remote_ip}) : Port [{str(port)}] ouvert sur l'adresse ip [{remote_ip}]",
|
||||
channel=uplink.ctx.Config.SERVICE_CHANLOG
|
||||
)
|
||||
# print(f"=======> Le port {str(port)} est ouvert !!")
|
||||
uplink.Base.running_sockets.append(newSocket)
|
||||
uplink.ctx.Base.running_sockets.append(newSocket)
|
||||
# print(newSocket)
|
||||
newSocket.shutdown(socket.SHUT_RDWR)
|
||||
newSocket.close()
|
||||
|
||||
except (socket.timeout, ConnectionRefusedError):
|
||||
uplink.Logs.info(f"Le port {remote_ip}:{str(port)} est fermé")
|
||||
uplink.ctx.Logs.info(f"Le port {remote_ip}:{str(port)} est fermé")
|
||||
except AttributeError as ae:
|
||||
uplink.Logs.warning(f"AttributeError ({remote_ip}): {ae}")
|
||||
uplink.ctx.Logs.warning(f"AttributeError ({remote_ip}): {ae}")
|
||||
except socket.gaierror as err:
|
||||
uplink.Logs.warning(f"Address Info Error ({remote_ip}): {err}")
|
||||
uplink.ctx.Logs.warning(f"Address Info Error ({remote_ip}): {err}")
|
||||
finally:
|
||||
# newSocket.shutdown(socket.SHUT_RDWR)
|
||||
newSocket.close()
|
||||
uplink.Logs.info('=======> Fermeture de la socket')
|
||||
uplink.ctx.Logs.info('=======> Fermeture de la socket')
|
||||
|
||||
def action_scan_client_with_psutil(uplink: 'Defender', user_model: 'MUser') -> list[int]:
|
||||
async def action_scan_client_with_psutil(uplink: 'Defender', user_model: 'MUser') -> list[int]:
|
||||
"""psutil_scan for Linux (should be run on the same location as the unrealircd server)
|
||||
|
||||
Args:
|
||||
@@ -694,13 +695,13 @@ def action_scan_client_with_psutil(uplink: 'Defender', user_model: 'MUser') -> l
|
||||
Returns:
|
||||
list[int]: list of ports
|
||||
"""
|
||||
p = uplink.Protocol
|
||||
p = uplink.ctx.Irc.Protocol
|
||||
remote_ip = user_model.remote_ip
|
||||
username = user_model.username
|
||||
hostname = user_model.hostname
|
||||
nickname = user_model.nickname
|
||||
|
||||
if remote_ip in uplink.Config.WHITELISTED_IP:
|
||||
if remote_ip in uplink.ctx.Config.WHITELISTED_IP:
|
||||
return None
|
||||
|
||||
try:
|
||||
@@ -708,16 +709,16 @@ def action_scan_client_with_psutil(uplink: 'Defender', user_model: 'MUser') -> l
|
||||
fullname = f'{nickname}!{username}@{hostname}'
|
||||
|
||||
matching_ports = [conn.raddr.port for conn in connections if conn.raddr and conn.raddr.ip == remote_ip]
|
||||
uplink.Logs.info(f"Connexion of {fullname} ({remote_ip}) using ports : {str(matching_ports)}")
|
||||
uplink.ctx.Logs.info(f"Connexion of {fullname} ({remote_ip}) using ports : {str(matching_ports)}")
|
||||
|
||||
if matching_ports:
|
||||
p.send_priv_msg(
|
||||
nick_from=uplink.Config.SERVICE_NICKNAME,
|
||||
msg=f"[ {uplink.Config.COLORS.red}PSUTIL_SCAN{uplink.Config.COLORS.black} ] {fullname} ({remote_ip}) : is using ports {matching_ports}",
|
||||
channel=uplink.Config.SERVICE_CHANLOG
|
||||
await p.send_priv_msg(
|
||||
nick_from=uplink.ctx.Config.SERVICE_NICKNAME,
|
||||
msg=f"[ {uplink.ctx.Config.COLORS.red}PSUTIL_SCAN{uplink.ctx.Config.COLORS.black} ] {fullname} ({remote_ip}) : is using ports {matching_ports}",
|
||||
channel=uplink.ctx.Config.SERVICE_CHANLOG
|
||||
)
|
||||
|
||||
return matching_ports
|
||||
|
||||
except psutil.AccessDenied as ad:
|
||||
uplink.Logs.critical(f'psutil_scan: Permission error: {ad}')
|
||||
uplink.ctx.Logs.critical(f'psutil_scan: Permission error: {ad}')
|
||||
@@ -48,7 +48,7 @@ class Test(IModule):
|
||||
# self.ctx.Base.db_execute_query(table_logs)
|
||||
return None
|
||||
|
||||
def load(self) -> None:
|
||||
async def load(self) -> None:
|
||||
"""### Load Module Configuration (Mandatory)
|
||||
"""
|
||||
|
||||
@@ -62,8 +62,11 @@ class Test(IModule):
|
||||
# Build the default configuration model (Mandatory)
|
||||
self._mod_config = self.ModConfModel(param_exemple1='str', param_exemple2=1)
|
||||
|
||||
# Init the module (Mandatory)
|
||||
self.init()
|
||||
# sync the database with local variable (Mandatory)
|
||||
await self.sync_db()
|
||||
|
||||
if self.mod_config.param_exemple2 == 1:
|
||||
await self.ctx.Irc.Protocol.send_priv_msg(self.ctx.Config.SERVICE_NICKNAME, "Param activated", self.ctx.Config.SERVICE_CHANLOG)
|
||||
|
||||
@property
|
||||
def mod_config(self) -> ModConfModel:
|
||||
@@ -71,7 +74,7 @@ class Test(IModule):
|
||||
|
||||
def unload(self) -> None:
|
||||
"""### This method is called when you unload, or you reload the module (Mandatory)"""
|
||||
self.ctx.Irc.Commands.drop_command_by_module(self.module_name)
|
||||
self.ctx.Commands.drop_command_by_module(self.module_name)
|
||||
return None
|
||||
|
||||
def cmd(self, data: list[str]) -> None:
|
||||
|
||||
@@ -3,4 +3,6 @@ psutil==7.1.2
|
||||
PyYAML==6.0.3
|
||||
requests==2.32.5
|
||||
SQLAlchemy==2.0.44
|
||||
unrealircd_rpc_py==3.0.2
|
||||
unrealircd_rpc_py==3.0.2
|
||||
starlette==0.50.0
|
||||
uvicorn==0.38.0
|
||||
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"version": "6.3.3",
|
||||
"version": "6.4.0",
|
||||
|
||||
"requests": "2.32.5",
|
||||
"psutil": "7.1.2",
|
||||
"unrealircd_rpc_py": "3.0.1",
|
||||
"sqlalchemy": "2.0.44",
|
||||
"faker": "37.12.0",
|
||||
"pyyaml": "6.0.3"
|
||||
"pyyaml": "6.0.3",
|
||||
"starlette":"0.50.0",
|
||||
"uvicorn":"0.38.0"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user