37 Commits

Author SHA1 Message Date
adator
80b329dd5d Merge pull request #52 from adator85/dev
You need to have unrealirc_rpc_py v1.0.3
2024-09-30 01:40:36 +02:00
adator
f7b49c151f Merge pull request #51 from adator85/dev
V5.3.4
2024-09-29 22:43:28 +02:00
adator
1ee9b7e3ff Merge pull request #50 from adator85/dev
Dev
2024-09-26 01:00:39 +02:00
adator
4d0087623c Merge pull request #49 from adator85/dev
unsubscribe before unload
2024-09-22 23:54:22 +02:00
adator
dc20f5ec3c Merge pull request #48 from adator85/dev
Dev
2024-09-22 23:20:37 +02:00
adator
110cae3b84 Merge pull request #47 from adator85/dev
Update the way to clean exceptions and bans
2024-09-22 16:45:54 +02:00
adator
857cbfc85d Merge pull request #46 from adator85/dev
Send the ready msg to channel log
2024-09-22 16:33:49 +02:00
adator
3518589e9c Merge pull request #45 from adator85/dev
Fix ConfModel error
2024-09-22 16:31:35 +02:00
adator
e14c97de03 Merge pull request #44 from adator85/dev
V5.3.0
2024-09-22 16:20:45 +02:00
adator
69360be3ad Merge pull request #43 from adator85/dev
Update info command
2024-09-21 20:28:29 +02:00
adator
bfa90c6bd5 Merge pull request #42 from adator85/dev
V5.2.9
2024-09-21 20:22:42 +02:00
adator
5c8378a0e7 Merge pull request #41 from adator85/dev
V5.2.9
2024-09-21 16:43:14 +02:00
adator
e3b212ea88 Merge pull request #40 from adator85/dev
finetune clone connection
2024-09-20 23:13:33 +02:00
adator
0c2a350d38 Merge pull request #39 from adator85/dev
Dev
2024-09-20 21:12:59 +02:00
adator
1cea8d0601 Merge pull request #38 from adator85/dev
V5.2.1
2024-09-15 03:09:22 +02:00
adator
652b400d5e Merge pull request #37 from adator85/dev
update mode clone
2024-09-15 02:50:27 +02:00
adator
2f8b965b59 Merge pull request #36 from adator85/dev
Dev
2024-09-15 02:04:32 +02:00
adator
3c043cefd8 Merge pull request #35 from adator85/dev
V5.1.8
2024-09-08 00:42:57 +02:00
adator
59a75cecd8 Merge pull request #34 from adator85/dev
V5.1.7
2024-09-03 00:21:32 +02:00
adator
71053437a7 Merge pull request #33 from adator85/dev
V5.1.6
2024-09-01 22:15:54 +02:00
adator
7796d05206 Merge pull request #32 from adator85/dev
Update vote kick commands
2024-09-01 18:55:57 +02:00
adator
5f2567f9e5 Merge pull request #31 from adator85/dev
mod_command update
2024-09-01 17:30:05 +02:00
adator
aaa1dd9a1a Merge pull request #30 from adator85/dev
adding Say command for clones
2024-09-01 16:40:25 +02:00
adator
a02f2f9a26 Merge pull request #29 from adator85/dev
update mod_clone module
2024-09-01 15:54:50 +02:00
adator
d73adb6f0b Merge pull request #28 from adator85/dev
update readme
2024-09-01 15:35:59 +02:00
adator
b812e64992 Merge pull request #27 from adator85/dev
Dev
2024-09-01 15:24:18 +02:00
adator
9bd1f68df2 Merge pull request #26 from adator85/dev
Dev
2024-09-01 14:59:38 +02:00
adator
f44b08bf36 Merge pull request #25 from adator85/dev
fix Installation
2024-08-29 01:36:38 +02:00
adator
1a19e1613a Merge pull request #24 from adator85/dev
Fix Bug installation
2024-08-29 01:31:19 +02:00
adator
cdc15b7b47 Merge pull request #23 from adator85/dev
Dev
2024-08-29 01:16:55 +02:00
adator
31fe9f62ec Merge pull request #22 from adator85/dev
Dev
2024-08-24 01:39:11 +02:00
adator
f0853e3afb Merge pull request #21 from adator85/dev
New Installation file created for unix system
2024-08-22 01:02:00 +02:00
adator
6dade09257 Merge pull request #20 from adator85/dev
README Update
2024-08-21 00:50:31 +02:00
adator
9533b010b2 Merge pull request #19 from adator85/dev
V5.0.4 - Delete a user when a user has been kicked
2024-08-20 02:24:37 +02:00
adator
824db73590 Merge pull request #18 from adator85/dev
Delete channel mode information
2024-08-20 02:14:31 +02:00
adator
96bf4b6f80 Merge pull request #17 from adator85/dev
Fix channel update
2024-08-20 02:08:09 +02:00
adator
922336363e Merge pull request #16 from adator85/dev
Dev
2024-08-20 01:56:04 +02:00
10 changed files with 282 additions and 439 deletions

View File

@@ -48,6 +48,7 @@ class Base:
with open(version_filename, 'r') as version_data: with open(version_filename, 'r') as version_data:
current_version:dict[str, str] = json.load(version_data) current_version:dict[str, str] = json.load(version_data)
# self.DEFENDER_VERSION = current_version["version"]
self.Config.current_version = current_version['version'] self.Config.current_version = current_version['version']
return None return None
@@ -80,14 +81,6 @@ class Base:
self.logs.warning(f'Github not available to fetch latest version') self.logs.warning(f'Github not available to fetch latest version')
def check_for_new_version(self, online:bool) -> bool: def check_for_new_version(self, online:bool) -> bool:
"""Check if there is a new version available
Args:
online (bool): True if you want to get the version from github (main branch)
Returns:
bool: True if there is a new version available
"""
try: try:
self.logs.debug(f'Checking for a new service version') self.logs.debug(f'Checking for a new service version')
@@ -236,19 +229,6 @@ class Base:
return False return False
def db_update_module(self, user_cmd: str, module_name: str) -> None:
"""Modifie la date et le user qui a rechargé le module
Args:
user_cmd (str): le user qui a rechargé le module
module_name (str): le module a rechargé
"""
update_cmd_query = f"UPDATE {self.Config.table_module} SET datetime = :datetime, user = :user WHERE module_name = :module_name"
mes_donnees = {'datetime': self.get_datetime(), 'user': user_cmd, 'module_name': module_name}
self.db_execute_query(update_cmd_query, mes_donnees)
return False
def db_delete_module(self, module_name:str) -> None: def db_delete_module(self, module_name:str) -> None:
"""Supprime les modules de la base de données """Supprime les modules de la base de données
@@ -611,7 +591,7 @@ class Base:
) )
''' '''
table_core_channel = f'''CREATE TABLE IF NOT EXISTS {self.Config.table_channel} ( table_core_channel = '''CREATE TABLE IF NOT EXISTS core_channel (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
datetime TEXT, datetime TEXT,
module_name TEXT, module_name TEXT,

View File

@@ -1,8 +1,7 @@
import os import os
import json from sys import exit
from sys import exit, prefix
from dataclasses import dataclass from dataclasses import dataclass
from subprocess import check_call, run, CalledProcessError, PIPE, check_output from subprocess import check_call, run, CalledProcessError, PIPE
from platform import python_version, python_version_tuple from platform import python_version, python_version_tuple
class Install: class Install:
@@ -25,23 +24,13 @@ class Install:
venv_pip_executable: str venv_pip_executable: str
venv_python_executable: str venv_python_executable: str
@dataclass
class Package:
name: str = None
version: str = None
DB_PACKAGES: list[Package] = []
def __init__(self) -> None: def __init__(self) -> None:
self.set_configuration() self.set_configuration()
if self.skip_install: if self.skip_install:
self.check_packages_version()
return None return None
self.check_packages_version()
# Sinon tester les dependances python et les installer avec pip # Sinon tester les dependances python et les installer avec pip
if self.do_install(): if self.do_install():
@@ -86,13 +75,11 @@ class Install:
if not os.path.exists(os.path.join(self.config.defender_install_folder, 'core', 'configuration.json')): if not os.path.exists(os.path.join(self.config.defender_install_folder, 'core', 'configuration.json')):
# If configuration file do not exist # If configuration file do not exist
exit("/!\\ Configuration file (core/configuration.json) doesn't exist! please create it /!\\") exit("/!\\ Configuration file (configuration.json) doesn't exist /!\\")
# Exclude Windows OS from the installation # Exclude Windows OS from the installation
if os.name == 'nt': if os.name == 'nt':
# If windows, modify pip and python virtual environment executable #print('/!\\ Skip installation /!\\')
self.config.venv_pip_executable = f'{os.path.join(defender_install_folder, venv_folder, "Scripts")}{os.sep}pip.exe'
self.config.venv_python_executable = f'{os.path.join(defender_install_folder, venv_folder, "Scripts")}{os.sep}python.exe'
self.skip_install = True self.skip_install = True
return False return False
@@ -104,7 +91,7 @@ class Install:
def is_root(self) -> bool: def is_root(self) -> bool:
if os.geteuid() != 0: if os.geteuid() != 0:
print('> User without privileges ==> OK') print('User without privileges ==> PASS')
return False return False
elif os.geteuid() == 0: elif os.geteuid() == 0:
print('/!\\ Do not use root to install Defender /!\\') print('/!\\ Do not use root to install Defender /!\\')
@@ -136,75 +123,6 @@ class Install:
print(f"Try to install dependencies ...") print(f"Try to install dependencies ...")
exit(5) exit(5)
def get_packages_version_from_json(self) -> None:
"""This will create Package model with package names and required version
"""
try:
version_filename = f'.{os.sep}version.json'
with open(version_filename, 'r') as version_data:
package_info:dict[str, str] = json.load(version_data)
for name, version in package_info.items():
if name == 'version':
continue
self.DB_PACKAGES.append(
self.Package(name=name, version=version)
)
return None
except FileNotFoundError as fe:
print(f"File not found: {fe}")
except Exception as err:
print(f"General Error: {err}")
def check_packages_version(self) -> bool:
try:
newVersion = False
self.get_packages_version_from_json()
if not self.config.venv_folder in prefix:
print(f"You are probably running a new installation or you are not using your virtual env {self.config.venv_folder}")
return newVersion
print(f"> Checking for dependencies versions ==> WAIT")
for package in self.DB_PACKAGES:
newVersion = False
required_version = package.version
installed_version = None
output = check_output([self.config.venv_pip_executable, 'show', package.name])
for line in output.decode().splitlines():
if line.startswith('Version:'):
installed_version = line.split(':')[1].strip()
break
required_major, required_minor, required_patch = required_version.split('.')
installed_major, installed_minor, installed_patch = installed_version.split('.')
if required_major > installed_major:
print(f'> New version of {package.name} is available {installed_version} ==> {required_version}')
newVersion = True
elif required_major == installed_major and required_minor > installed_minor:
print(f'> New version of {package.name} is available {installed_version} ==> {required_version}')
newVersion = True
elif required_major == installed_major and required_minor == installed_minor and required_patch > installed_patch:
print(f'> New version of {package.name} is available {installed_version} ==> {required_version}')
newVersion = True
if newVersion:
self.run_subprocess([self.config.venv_pip_executable, 'install', '--upgrade', package.name])
print(f"> Dependencies versions ==> OK")
return newVersion
except CalledProcessError:
print(f"/!\\ Package {package.name} not installed /!\\")
except Exception as err:
print(f"General Error: {err}")
def check_python_version(self) -> bool: def check_python_version(self) -> bool:
"""Test si la version de python est autorisée ou non """Test si la version de python est autorisée ou non

View File

@@ -95,15 +95,13 @@ class Irc:
return None return None
except ssl.SSLEOFError as soe: except ssl.SSLEOFError as soe:
self.Base.logs.critical(f"SSLEOFError: {soe} - {soc.fileno()}") self.Base.logs.critical(f"SSLEOFError __create_socket: {soe} - {soc.fileno()}")
except ssl.SSLError as se: except ssl.SSLError as se:
self.Base.logs.critical(f"SSLError: {se} - {soc.fileno()}") self.Base.logs.critical(f"SSLError __create_socket: {se} - {soc.fileno()}")
except OSError as oe: except OSError as oe:
self.Base.logs.critical(f"OSError: {oe} - {soc.fileno()}") self.Base.logs.critical(f"OSError __create_socket: {oe} - {soc.fileno()}")
if 'connection refused' in str(oe).lower():
sys.exit(oe)
except AttributeError as ae: except AttributeError as ae:
self.Base.logs.critical(f"AttributeError: {ae} - {soc.fileno()}") self.Base.logs.critical(f"AttributeError __create_socket: {ae} - {soc.fileno()}")
def __ssl_context(self) -> ssl.SSLContext: def __ssl_context(self) -> ssl.SSLContext:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
@@ -313,7 +311,7 @@ class Irc:
def send_response(self, responses:list[bytes]) -> None: def send_response(self, responses:list[bytes]) -> None:
try: try:
# print(responses) # print(data)
for data in responses: for data in responses:
response = data.decode(self.CHARSET[0]).split() response = data.decode(self.CHARSET[0]).split()
self.cmd(response) self.cmd(response)
@@ -490,8 +488,7 @@ class Irc:
self.Base.db_record_module(fromuser, module_name) self.Base.db_record_module(fromuser, module_name)
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} chargé") self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} chargé")
# self.Base.logs.info(self.loaded_classes) self.Base.logs.info(self.loaded_classes)
self.Base.logs.info(f"Module {class_name} has been loaded")
return True return True
except ModuleNotFoundError as moduleNotFound: except ModuleNotFoundError as moduleNotFound:
@@ -535,61 +532,11 @@ class Irc:
self.Base.logs.error(f"General Error: {err}") self.Base.logs.error(f"General Error: {err}")
return False return False
def reload_module(self, from_user: str, mod_name: str) -> bool:
try:
module_name = mod_name.lower() # ==> mod_defender
class_name = module_name.split('_')[1].capitalize() # ==> Defender
if 'mods.' + module_name in sys.modules:
self.Base.logs.info('Unload the module ...')
self.loaded_classes[class_name].unload()
self.Base.logs.info('Module Already Loaded ... reloading the module ...')
the_module = sys.modules['mods.' + module_name]
importlib.reload(the_module)
# Supprimer la class déja instancier
if class_name in self.loaded_classes:
# Supprimer les commandes déclarer dans la classe
for level, command in self.loaded_classes[class_name].commands_level.items():
# Supprimer la commande de la variable commands
for c in self.loaded_classes[class_name].commands_level[level]:
self.commands.remove(c)
self.commands_level[level].remove(c)
del self.loaded_classes[class_name]
my_class = getattr(the_module, class_name, None)
new_instance = my_class(self.ircObject)
self.loaded_classes[class_name] = new_instance
self.Base.db_update_module(from_user, mod_name)
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} rechargé")
return False
else:
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} n'est pas chargé !")
except TypeError as te:
self.Base.logs.error(f"A TypeError raised: {te}")
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :A TypeError raised: {te}")
self.Base.db_delete_module(module_name)
except AttributeError as ae:
self.Base.logs.error(f"Missing Attribute: {ae}")
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Missing Attribute: {ae}")
self.Base.db_delete_module(module_name)
except KeyError as ke:
self.Base.logs.error(f"Key Error: {ke}")
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Key Error: {ke}")
self.Base.db_delete_module(module_name)
except Exception as e:
self.Base.logs.error(f"Something went wrong with a module you want to reload: {e}")
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Something went wrong with the module: {e}")
self.Base.db_delete_module(module_name)
def insert_db_admin(self, uid:str, level:int) -> None: def insert_db_admin(self, uid:str, level:int) -> None:
if self.User.get_User(uid) is None: if self.User.get_User(uid) is None:
return None return None
getUser = self.User.get_User(uid) getUser = self.User.get_User(uid)
nickname = getUser.nickname nickname = getUser.nickname
@@ -874,7 +821,7 @@ class Irc:
self.Base.logs.info(f"# CHANNEL : {self.Config.SERVICE_CHANLOG} ") self.Base.logs.info(f"# CHANNEL : {self.Config.SERVICE_CHANLOG} ")
self.Base.logs.info(f"# VERSION : {version} ") self.Base.logs.info(f"# VERSION : {version} ")
self.Base.logs.info(f"################################################") self.Base.logs.info(f"################################################")
if self.Base.check_for_new_version(False): if self.Base.check_for_new_version(False):
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} : New Version available {version}") self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} : New Version available {version}")
@@ -882,13 +829,6 @@ class Irc:
self.sendPrivMsg(msg=f'[{self.Config.COLORS.green}INFORMATION{self.Config.COLORS.nogc}] >> Defender is ready', channel=self.Config.SERVICE_CHANLOG) self.sendPrivMsg(msg=f'[{self.Config.COLORS.green}INFORMATION{self.Config.COLORS.nogc}] >> Defender is ready', channel=self.Config.SERVICE_CHANLOG)
self.INIT = 0 self.INIT = 0
# Send EOF to other modules
for classe_name, classe_object in self.loaded_classes.items():
classe_object.cmd(original_response)
# Stop here When EOS
return None
case _: case _:
pass pass
@@ -1063,8 +1003,7 @@ class Irc:
arg.remove(f':{self.Config.SERVICE_PREFIX}') arg.remove(f':{self.Config.SERVICE_PREFIX}')
if not arg[0].lower() in self.commands: if not arg[0].lower() in self.commands:
self.Base.logs.debug(f"This command {arg[0]} is not available") self.Base.logs.debug(f"This command {arg[0]} is not available")
self.sendNotice(f"This command [{self.Config.COLORS.bold}{arg[0]}{self.Config.COLORS.bold}] is not available", user_trigger) return False
return None
cmd_to_send = convert_to_string.replace(':','') cmd_to_send = convert_to_string.replace(':','')
self.Base.log_cmd(user_trigger, cmd_to_send) self.Base.log_cmd(user_trigger, cmd_to_send)
@@ -1100,7 +1039,7 @@ class Irc:
ping_response = current_unixtime - recieved_unixtime ping_response = current_unixtime - recieved_unixtime
self.send2socket(f'PONG :{recieved_unixtime}') self.send2socket(f'PONG :{recieved_unixtime}')
self.send2socket(f':{dnickname} NOTICE {user_trigger} :\x01PING {ping_response} secs\x01') self.send2socket(f':{dnickname} NOTICE {user_trigger} :\x01PING {recieved_unixtime} secs\x01')
return False return False
if not arg[0].lower() in self.commands: if not arg[0].lower() in self.commands:
@@ -1409,21 +1348,14 @@ class Irc:
batch_commands = ' | '.join(groupe) batch_commands = ' | '.join(groupe)
self.send2socket(f':{dnickname} NOTICE {fromuser} : {batch_commands}') self.send2socket(f':{dnickname} NOTICE {fromuser} : {batch_commands}')
self.send2socket(f':{dnickname} NOTICE {fromuser} : ')
count_level_definition += 1 count_level_definition += 1
self.send2socket(f':{dnickname} NOTICE {fromuser} : ')
self.send2socket(f':{dnickname} NOTICE {fromuser} : ***************** FIN DES COMMANDES *****************') self.send2socket(f':{dnickname} NOTICE {fromuser} : ***************** FIN DES COMMANDES *****************')
case 'load': case 'load':
try:
# Load a module ex: .load mod_defender self.load_module(fromuser, str(cmd[1]))
mod_name = str(cmd[1])
self.load_module(fromuser, mod_name)
except KeyError as ke:
self.Base.logs.error(f"Key Error: {ke} - list recieved: {cmd}")
except Exception as err:
self.Base.logs.error(f"General Error: {ke} - list recieved: {cmd}")
case 'unload': case 'unload':
# unload mod_defender # unload mod_defender
@@ -1434,10 +1366,50 @@ class Irc:
self.Base.logs.error(f"General Error: {err}") self.Base.logs.error(f"General Error: {err}")
case 'reload': case 'reload':
# reload mod_defender # reload mod_dktmb
try: try:
module_name = str(cmd[1]).lower() # ==> mod_defender module_name = str(cmd[1]).lower() # ==> mod_defender
self.reload_module(from_user=fromuser, mod_name=module_name) class_name = module_name.split('_')[1].capitalize() # ==> Defender
if 'mods.' + module_name in sys.modules:
self.Base.logs.info('Unload the module ...')
self.loaded_classes[class_name].unload()
self.Base.logs.info('Module Already Loaded ... reloading the module ...')
the_module = sys.modules['mods.' + module_name]
importlib.reload(the_module)
# Supprimer la class déja instancier
if class_name in self.loaded_classes:
# Supprimer les commandes déclarer dans la classe
for level, command in self.loaded_classes[class_name].commands_level.items():
# Supprimer la commande de la variable commands
for c in self.loaded_classes[class_name].commands_level[level]:
self.commands.remove(c)
self.commands_level[level].remove(c)
del self.loaded_classes[class_name]
my_class = getattr(the_module, class_name, None)
new_instance = my_class(self.ircObject)
self.loaded_classes[class_name] = new_instance
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} rechargé")
return False
else:
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} n'est pas chargé !")
except TypeError as te:
self.Base.logs.error(f"A TypeError raised: {te}")
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :A TypeError raised: {te}")
self.Base.db_delete_module(module_name)
except AttributeError as ae:
self.Base.logs.error(f"Missing Attribute: {ae}")
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Missing Attribute: {ae}")
self.Base.db_delete_module(module_name)
except KeyError as ke:
self.Base.logs.error(f"Key Error: {ke}")
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Key Error: {ke}")
self.Base.db_delete_module(module_name)
except Exception as e: except Exception as e:
self.Base.logs.error(f"Something went wrong with a module you want to reload: {e}") self.Base.logs.error(f"Something went wrong with a module you want to reload: {e}")
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Something went wrong with the module: {e}") self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Something went wrong with the module: {e}")
@@ -1488,24 +1460,24 @@ class Irc:
self.Base.logs.debug(self.loaded_classes) self.Base.logs.debug(self.loaded_classes)
all_modules = self.Base.get_all_modules() all_modules = self.Base.get_all_modules()
loaded = False
results = self.Base.db_execute_query(f'SELECT datetime, user, module_name FROM {self.Config.table_module}') results = self.Base.db_execute_query(f'SELECT module_name FROM {self.Config.table_module}')
results = results.fetchall() results = results.fetchall()
found = False
for module in all_modules: for module in all_modules:
for loaded_mod in results: for loaded_mod in results:
if module == loaded_mod[2]: if module == loaded_mod[0]:
loaded_datetime = loaded_mod[0] found = True
loaded_user = loaded_mod[1]
loaded = True
if loaded: if found:
self.send2socket(f":{dnickname} NOTICE {fromuser} :{module} - {self.Config.COLORS.green}Loaded{self.Config.COLORS.nogc} by {loaded_user} on {loaded_datetime}") self.send2socket(f":{dnickname} NOTICE {fromuser} :{module} - {self.Config.COLORS.green}Loaded{self.Config.COLORS.nogc}")
loaded = False
else: else:
self.send2socket(f":{dnickname} NOTICE {fromuser} :{module} - {self.Config.COLORS.red}Not Loaded{self.Config.COLORS.nogc}") self.send2socket(f":{dnickname} NOTICE {fromuser} :{module} - {self.Config.COLORS.red}Not Loaded{self.Config.COLORS.nogc}")
found = False
case 'show_timers': case 'show_timers':
if self.Base.running_timers: if self.Base.running_timers:

View File

@@ -60,7 +60,6 @@ class Clone():
self.Base.db_query_channel(action='add', module_name=self.module_name, channel_name=self.Config.CLONE_CHANNEL) self.Base.db_query_channel(action='add', module_name=self.module_name, channel_name=self.Config.CLONE_CHANNEL)
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} JOIN {self.Config.CLONE_CHANNEL}") self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} JOIN {self.Config.CLONE_CHANNEL}")
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} SAMODE {self.Config.CLONE_CHANNEL} +o {self.Config.SERVICE_NICKNAME}")
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} MODE {self.Config.CLONE_CHANNEL} +nts") self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} MODE {self.Config.CLONE_CHANNEL} +nts")
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} MODE {self.Config.CLONE_CHANNEL} +k {self.Config.CLONE_CHANNEL_PASSWORD}") self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} MODE {self.Config.CLONE_CHANNEL} +k {self.Config.CLONE_CHANNEL_PASSWORD}")
@@ -127,8 +126,6 @@ class Clone():
self.Irc.send2socket(f':{self.Config.SERVICE_NICKNAME} PRIVMSG {clone} :KILL') self.Irc.send2socket(f':{self.Config.SERVICE_NICKNAME} PRIVMSG {clone} :KILL')
self.Base.db_query_channel(action='del', module_name=self.module_name, channel_name=self.Config.CLONE_CHANNEL) self.Base.db_query_channel(action='del', module_name=self.module_name, channel_name=self.Config.CLONE_CHANNEL)
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} MODE {self.Config.CLONE_CHANNEL} -nts")
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} MODE {self.Config.CLONE_CHANNEL} -k {self.Config.CLONE_CHANNEL_PASSWORD}")
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} PART {self.Config.CLONE_CHANNEL}") self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} PART {self.Config.CLONE_CHANNEL}")
return None return None

View File

@@ -150,7 +150,6 @@ class Command():
try: try:
message = ' '.join(cmd[3:]) message = ' '.join(cmd[3:])
self.Irc.send2socket(f":{dnickname} NOTICE {self.user_to_notice} :[{red}ERROR MSG{nogc}] {message}") self.Irc.send2socket(f":{dnickname} NOTICE {self.user_to_notice} :[{red}ERROR MSG{nogc}] {message}")
self.Base.logs.error(f"{cmd[1]} - {message}")
except KeyError as ke: except KeyError as ke:
self.Base.logs.error(ke) self.Base.logs.error(ke)
except Exception as err: except Exception as err:
@@ -213,7 +212,6 @@ class Command():
dnickname = self.Config.SERVICE_NICKNAME dnickname = self.Config.SERVICE_NICKNAME
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
dchanlog = self.Config.SERVICE_CHANLOG dchanlog = self.Config.SERVICE_CHANLOG
self.user_to_notice = user
fromuser = user fromuser = user
fromchannel = channel fromchannel = channel

View File

@@ -111,6 +111,9 @@ class Defender():
self.__load_module_configuration() self.__load_module_configuration()
# End of mandatory methods you can start your customization # # End of mandatory methods you can start your customization #
# # Rejoindre les salons
# self.join_saved_channels()
self.timeout = self.Config.API_TIMEOUT self.timeout = self.Config.API_TIMEOUT
# Listes qui vont contenir les ip a scanner avec les différentes API # Listes qui vont contenir les ip a scanner avec les différentes API
@@ -147,8 +150,7 @@ class Defender():
self.Base.create_thread(func=self.thread_reputation_timer) self.Base.create_thread(func=self.thread_reputation_timer)
if self.ModConfig.reputation == 1: if self.ModConfig.reputation == 1:
self.Irc.send2socket(f":{self.Config.SERVEUR_ID} SJOIN {self.Base.get_unixtime()} {self.Config.SALON_JAIL} + :{self.Config.SERVICE_NICKNAME}") self.Irc.send2socket(f":{self.Config.SERVICE_ID} SAMODE {self.Config.SALON_JAIL} +{self.Config.SERVICE_UMODES} {self.Config.SERVICE_NICKNAME}")
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} SAMODE {self.Config.SALON_JAIL} +o {self.Config.SERVICE_NICKNAME}")
return None return None
@@ -247,6 +249,40 @@ class Defender():
self.reputationTimer_isRunning:bool = False self.reputationTimer_isRunning:bool = False
return None return None
def add_defender_channel(self, channel:str) -> bool:
"""Cette fonction ajoute les salons de join de Defender
Args:
channel (str): le salon à enregistrer.
"""
mes_donnees = {'channel': channel}
response = self.Base.db_execute_query("SELECT id FROM def_channels WHERE channel = :channel", mes_donnees)
isChannelExist = response.fetchone()
if isChannelExist is None:
mes_donnees = {'datetime': self.Base.get_datetime(), 'channel': channel}
insert = self.Base.db_execute_query(f"INSERT INTO def_channels (datetime, channel) VALUES (:datetime, :channel)", mes_donnees)
return True
else:
return False
def delete_defender_channel(self, channel:str) -> bool:
"""Cette fonction supprime les salons de join de Defender
Args:
channel (str): le salon à enregistrer.
"""
mes_donnes = {'channel': channel}
response = self.Base.db_execute_query("DELETE FROM def_channels WHERE channel = :channel", mes_donnes)
affected_row = response.rowcount
if affected_row > 0:
return True
else:
return False
def reputation_insert(self, reputationModel: ReputationModel) -> bool: def reputation_insert(self, reputationModel: ReputationModel) -> bool:
response = False response = False
@@ -336,7 +372,7 @@ class Defender():
def join_saved_channels(self) -> None: def join_saved_channels(self) -> None:
result = self.Base.db_execute_query(f"SELECT distinct channel_name FROM {self.Config.table_channel}") result = self.Base.db_execute_query("SELECT id, channel FROM def_channels")
channels = result.fetchall() channels = result.fetchall()
jail_chan = self.Config.SALON_JAIL jail_chan = self.Config.SALON_JAIL
jail_chan_mode = self.Config.SALON_JAIL_MODES jail_chan_mode = self.Config.SALON_JAIL_MODES
@@ -347,7 +383,7 @@ class Defender():
unixtime = self.Base.get_unixtime() unixtime = self.Base.get_unixtime()
for channel in channels: for channel in channels:
chan = channel[0] id, chan = channel
self.Irc.send2socket(f":{self.Config.SERVEUR_ID} SJOIN {unixtime} {chan} + :{self.Config.SERVICE_ID}") self.Irc.send2socket(f":{self.Config.SERVEUR_ID} SJOIN {unixtime} {chan} + :{self.Config.SERVICE_ID}")
if chan == jail_chan: if chan == jail_chan:
self.Irc.send2socket(f":{service_id} SAMODE {jail_chan} +{dumodes} {dnickname}") self.Irc.send2socket(f":{service_id} SAMODE {jail_chan} +{dumodes} {dnickname}")
@@ -964,206 +1000,190 @@ class Defender():
self.Logs.error(f"Thread_cloudfilt_scan Error : {ve}") self.Logs.error(f"Thread_cloudfilt_scan Error : {ve}")
def cmd(self, data: list) -> None: def cmd(self, data: list) -> None:
try:
service_id = self.Config.SERVICE_ID # Defender serveur id
cmd = list(data).copy()
match cmd[1]: service_id = self.Config.SERVICE_ID # Defender serveur id
cmd = list(data).copy()
case 'REPUTATION': if len(cmd) < 2:
# :001 REPUTATION 91.168.141.239 118 return None
try:
self.reputation_first_connexion['ip'] = cmd[2]
self.reputation_first_connexion['score'] = cmd[3]
if str(cmd[3]).find('*') != -1:
# If the reputation changed, we do not need to scan the IP
return None
if not self.Base.is_valid_ip(cmd[2]): match cmd[1]:
return None
# Possibilité de déclancher les bans a ce niveau. case 'EOS':
except IndexError as ie: if self.Irc.INIT == 0:
self.Logs.error(f'cmd reputation: index error: {ie}') self.Irc.send2socket(f":{service_id} SAMODE {self.Config.SALON_JAIL} +{self.Config.SERVICE_UMODES} {self.Config.SERVICE_NICKNAME}")
if len(cmd) < 3: case 'REPUTATION':
return None # :001 REPUTATION 91.168.141.239 118
try:
match cmd[2]: self.reputation_first_connexion['ip'] = cmd[2]
self.reputation_first_connexion['score'] = cmd[3]
case 'MODE': if str(cmd[3]).find('*') != -1:
# ['...', ':001XSCU0Q', 'MODE', '#jail', '+b', '~security-group:unknown-users'] # If the reputation changed, we do not need to scan the IP
channel = str(cmd[3])
mode = str(cmd[4])
group_to_check = str(cmd[5:])
group_to_unban = '~security-group:unknown-users'
if self.Config.SALON_JAIL == channel:
if mode == '+b' and group_to_unban in group_to_check:
self.Irc.send2socket(f":{service_id} MODE {self.Config.SALON_JAIL} -b ~security-group:unknown-users")
self.Irc.send2socket(f":{service_id} MODE {self.Config.SALON_JAIL} -eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
case 'PRIVMSG':
cmd.pop(0)
user_trigger = str(cmd[0]).replace(':','')
channel = cmd[2]
find_nickname = self.User.get_nickname(user_trigger)
self.flood(find_nickname, channel)
case 'UID':
# If Init then do nothing
if self.Irc.INIT == 1:
return None return None
# Supprimer la premiere valeur et finir le code normalement if not self.Base.is_valid_ip(cmd[2]):
cmd.pop(0) return None
# Get User information # Possibilité de déclancher les bans a ce niveau.
_User = self.User.get_User(str(cmd[7])) except IndexError as ie:
self.Logs.error(f'cmd reputation: index error: {ie}')
# If user is not service or IrcOp then scan them match cmd[2]:
case 'PRIVMSG':
cmd.pop(0)
user_trigger = str(cmd[0]).replace(':','')
channel = cmd[2]
find_nickname = self.User.get_nickname(user_trigger)
self.flood(find_nickname, channel)
case 'UID':
# If Init then do nothing
if self.Irc.INIT == 1:
return None
# Supprimer la premiere valeur et finir le code normalement
cmd.pop(0)
# Get User information
_User = self.User.get_User(str(cmd[7]))
# If user is not service or IrcOp then scan them
if not re.match(fr'^.*[S|o?].*$', _User.umodes):
self.abuseipdb_UserModel.append(_User) if self.ModConfig.abuseipdb_scan == 1 and not _User.remote_ip in self.Config.WHITELISTED_IP else None
self.freeipapi_UserModel.append(_User) if self.ModConfig.freeipapi_scan == 1 and not _User.remote_ip in self.Config.WHITELISTED_IP else None
self.cloudfilt_UserModel.append(_User) if self.ModConfig.cloudfilt_scan == 1 and not _User.remote_ip in self.Config.WHITELISTED_IP else None
self.psutil_UserModel.append(_User) if self.ModConfig.psutil_scan == 1 and not _User.remote_ip in self.Config.WHITELISTED_IP else None
self.localscan_UserModel.append(_User) if self.ModConfig.local_scan == 1 and not _User.remote_ip in self.Config.WHITELISTED_IP else None
if _User is None:
self.Logs.critical(f'This UID: [{cmd[7]}] is not available please check why')
return None
reputation_flag = self.ModConfig.reputation
reputation_seuil = self.ModConfig.reputation_seuil
if self.Irc.INIT == 0:
# Si le user n'es pas un service ni un IrcOP
if not re.match(fr'^.*[S|o?].*$', _User.umodes): if not re.match(fr'^.*[S|o?].*$', _User.umodes):
self.abuseipdb_UserModel.append(_User) if self.ModConfig.abuseipdb_scan == 1 and not _User.remote_ip in self.Config.WHITELISTED_IP else None if reputation_flag == 1 and _User.score_connexion <= reputation_seuil:
self.freeipapi_UserModel.append(_User) if self.ModConfig.freeipapi_scan == 1 and not _User.remote_ip in self.Config.WHITELISTED_IP else None currentDateTime = self.Base.get_datetime()
self.cloudfilt_UserModel.append(_User) if self.ModConfig.cloudfilt_scan == 1 and not _User.remote_ip in self.Config.WHITELISTED_IP else None self.reputation_insert(
self.psutil_UserModel.append(_User) if self.ModConfig.psutil_scan == 1 and not _User.remote_ip in self.Config.WHITELISTED_IP else None self.ReputationModel(
self.localscan_UserModel.append(_User) if self.ModConfig.local_scan == 1 and not _User.remote_ip in self.Config.WHITELISTED_IP else None uid=_User.uid, nickname=_User.nickname, username=_User.username, realname=_User.realname,
hostname=_User.hostname, umodes=_User.umodes, vhost=_User.vhost, ip=_User.remote_ip, score=_User.score_connexion,
if _User is None: secret_code=self.Base.get_random(8), isWebirc=_User.isWebirc, isWebsocket=_User.isWebsocket, connected_datetime=currentDateTime,
self.Logs.critical(f'This UID: [{cmd[7]}] is not available please check why') updated_datetime=currentDateTime
return None
reputation_flag = self.ModConfig.reputation
reputation_seuil = self.ModConfig.reputation_seuil
if self.Irc.INIT == 0:
# Si le user n'es pas un service ni un IrcOP
if not re.match(fr'^.*[S|o?].*$', _User.umodes):
if reputation_flag == 1 and _User.score_connexion <= reputation_seuil:
currentDateTime = self.Base.get_datetime()
self.reputation_insert(
self.ReputationModel(
uid=_User.uid, nickname=_User.nickname, username=_User.username, realname=_User.realname,
hostname=_User.hostname, umodes=_User.umodes, vhost=_User.vhost, ip=_User.remote_ip, score=_User.score_connexion,
secret_code=self.Base.get_random(8), isWebirc=_User.isWebirc, isWebsocket=_User.isWebsocket, connected_datetime=currentDateTime,
updated_datetime=currentDateTime
)
) )
# self.Irc.send2socket(f":{service_id} WHOIS {nickname}") )
if self.reputation_check(_User.uid): # self.Irc.send2socket(f":{service_id} WHOIS {nickname}")
if reputation_flag == 1 and _User.score_connexion <= reputation_seuil: if self.reputation_check(_User.uid):
self.system_reputation(_User.uid) if reputation_flag == 1 and _User.score_connexion <= reputation_seuil:
self.Logs.info('Démarrer le systeme de reputation') self.system_reputation(_User.uid)
self.Logs.info('Démarrer le systeme de reputation')
case 'SJOIN': case 'SJOIN':
# ['@msgid=F9B7JeHL5pj9nN57cJ5pEr;time=2023-12-28T20:47:24.305Z', ':001', 'SJOIN', '1702138958', '#welcome', ':0015L1AHL'] # ['@msgid=F9B7JeHL5pj9nN57cJ5pEr;time=2023-12-28T20:47:24.305Z', ':001', 'SJOIN', '1702138958', '#welcome', ':0015L1AHL']
try: try:
cmd.pop(0)
parsed_chan = cmd[3]
if self.ModConfig.reputation == 1:
parsed_UID = cmd[4]
pattern = fr'^:[@|%|\+|~|\*]*'
parsed_UID = re.sub(pattern, '', parsed_UID)
get_reputation = self.reputation_get_Reputation(parsed_UID)
if parsed_chan != self.Config.SALON_JAIL:
self.Irc.send2socket(f":{service_id} MODE {parsed_chan} +b ~security-group:unknown-users")
self.Irc.send2socket(f":{service_id} MODE {parsed_chan} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
if not get_reputation is None:
isWebirc = get_reputation.isWebirc
if not isWebirc:
if parsed_chan != self.Config.SALON_JAIL:
self.Irc.send2socket(f":{service_id} SAPART {get_reputation.nickname} {parsed_chan}")
if self.ModConfig.reputation_ban_all_chan == 1 and not isWebirc:
if parsed_chan != self.Config.SALON_JAIL:
self.Irc.send2socket(f":{service_id} MODE {parsed_chan} +b {get_reputation.nickname}!*@*")
self.Irc.send2socket(f":{service_id} KICK {parsed_chan} {get_reputation.nickname}")
self.Logs.debug(f'SJOIN parsed_uid : {parsed_UID}')
except KeyError as ke:
self.Logs.error(f"key error SJOIN : {ke}")
case 'SLOG':
# self.Base.scan_ports(cmd[7])
cmd.pop(0) cmd.pop(0)
parsed_chan = cmd[3]
if not self.Base.is_valid_ip(cmd[7]): if self.ModConfig.reputation == 1:
return None parsed_UID = cmd[4]
pattern = fr'^:[@|%|\+|~|\*]*'
parsed_UID = re.sub(pattern, '', parsed_UID)
# if self.ModConfig.local_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: get_reputation = self.reputation_get_Reputation(parsed_UID)
# self.localscan_remote_ip.append(cmd[7])
# if self.ModConfig.psutil_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: self.Irc.send2socket(f":{service_id} MODE {parsed_chan} +b ~security-group:unknown-users")
# self.psutil_remote_ip.append(cmd[7]) self.Irc.send2socket(f":{service_id} MODE {parsed_chan} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
# if self.ModConfig.abuseipdb_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: if not get_reputation is None:
# self.abuseipdb_remote_ip.append(cmd[7]) isWebirc = get_reputation.isWebirc
# if self.ModConfig.freeipapi_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: if not isWebirc:
# self.freeipapi_remote_ip.append(cmd[7]) if parsed_chan != self.Config.SALON_JAIL:
self.Irc.send2socket(f":{service_id} SAPART {get_reputation.nickname} {parsed_chan}")
# if self.ModConfig.cloudfilt_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: if self.ModConfig.reputation_ban_all_chan == 1 and not isWebirc:
# self.cloudfilt_remote_ip.append(cmd[7]) if parsed_chan != self.Config.SALON_JAIL:
self.Irc.send2socket(f":{service_id} MODE {parsed_chan} +b {get_reputation.nickname}!*@*")
self.Irc.send2socket(f":{service_id} KICK {parsed_chan} {get_reputation.nickname}")
case 'NICK': self.Logs.debug(f'SJOIN parsed_uid : {parsed_UID}')
# :0010BS24L NICK [NEWNICK] 1697917711 except KeyError as ke:
# Changement de nickname self.Logs.error(f"key error SJOIN : {ke}")
try:
cmd.pop(0)
uid = str(cmd[0]).replace(':','')
get_Reputation = self.reputation_get_Reputation(uid)
jail_salon = self.Config.SALON_JAIL
service_id = self.Config.SERVICE_ID
if get_Reputation is None: case 'SLOG':
self.Logs.debug(f'This UID: {uid} is not listed in the reputation dataclass') # self.Base.scan_ports(cmd[7])
return None cmd.pop(0)
# Update the new nickname if not self.Base.is_valid_ip(cmd[7]):
oldnick = get_Reputation.nickname return None
newnickname = cmd[2]
get_Reputation.nickname = newnickname
# If ban in all channel is ON then unban old nickname an ban the new nickname # if self.ModConfig.local_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
if self.ModConfig.reputation_ban_all_chan == 1: # self.localscan_remote_ip.append(cmd[7])
for chan in self.Channel.UID_CHANNEL_DB:
if chan.name != jail_salon:
self.Irc.send2socket(f":{service_id} MODE {chan.name} -b {oldnick}!*@*")
self.Irc.send2socket(f":{service_id} MODE {chan.name} +b {newnickname}!*@*")
except KeyError as ke: # if self.ModConfig.psutil_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
self.Logs.error(f'cmd - NICK - KeyError: {ke}') # self.psutil_remote_ip.append(cmd[7])
case 'QUIT': # if self.ModConfig.abuseipdb_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
# :001N1WD7L QUIT :Quit: free_znc_1 # self.abuseipdb_remote_ip.append(cmd[7])
# if self.ModConfig.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:
# self.cloudfilt_remote_ip.append(cmd[7])
case 'NICK':
# :0010BS24L NICK [NEWNICK] 1697917711
# Changement de nickname
try:
cmd.pop(0) cmd.pop(0)
ban_all_chan = self.Base.int_if_possible(self.ModConfig.reputation_ban_all_chan) uid = str(cmd[0]).replace(':','')
user_id = str(cmd[0]).replace(':','') get_Reputation = self.reputation_get_Reputation(uid)
final_UID = user_id
jail_salon = self.Config.SALON_JAIL jail_salon = self.Config.SALON_JAIL
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
get_user_reputation = self.reputation_get_Reputation(final_UID) if get_Reputation is None:
self.Logs.debug(f'This UID: {uid} is not listed in the reputation dataclass')
return None
if not get_user_reputation is None: # Update the new nickname
final_nickname = get_user_reputation.nickname oldnick = get_Reputation.nickname
newnickname = cmd[2]
get_Reputation.nickname = newnickname
# If ban in all channel is ON then unban old nickname an ban the new nickname
if self.ModConfig.reputation_ban_all_chan == 1:
for chan in self.Channel.UID_CHANNEL_DB: for chan in self.Channel.UID_CHANNEL_DB:
if chan.name != jail_salon and ban_all_chan == 1: if chan.name != jail_salon:
self.Irc.send2socket(f":{service_id} MODE {chan.name} -b {final_nickname}!*@*") self.Irc.send2socket(f":{service_id} MODE {chan.name} -b {oldnick}!*@*")
self.reputation_delete(final_UID) self.Irc.send2socket(f":{service_id} MODE {chan.name} +b {newnickname}!*@*")
except KeyError as ke: except KeyError as ke:
self.Logs.error(f"{ke} / {cmd} / length {str(len(cmd))}") self.Logs.error(f'cmd - NICK - KeyError: {ke}')
except IndexError as ie:
self.Logs.error(f"{ie} / {cmd} / length {str(len(cmd))}") case 'QUIT':
except Exception as err: # :001N1WD7L QUIT :Quit: free_znc_1
self.Logs.error(f"General Error: {err}") cmd.pop(0)
ban_all_chan = self.Base.int_if_possible(self.ModConfig.reputation_ban_all_chan)
user_id = str(cmd[0]).replace(':','')
final_UID = user_id
jail_salon = self.Config.SALON_JAIL
service_id = self.Config.SERVICE_ID
get_user_reputation = self.reputation_get_Reputation(final_UID)
if not get_user_reputation is None:
final_nickname = get_user_reputation.nickname
for chan in self.Channel.UID_CHANNEL_DB:
if chan.name != jail_salon and ban_all_chan == 1:
self.Irc.send2socket(f":{service_id} MODE {chan.name} -b {final_nickname}!*@*")
self.reputation_delete(final_UID)
def _hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None: def _hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None:

View File

@@ -10,7 +10,8 @@ class Jsonrpc():
class ModConfModel: class ModConfModel:
"""The Model containing the module parameters """The Model containing the module parameters
""" """
jsonrpc: int = 0 param_exemple1: str
param_exemple2: int
def __init__(self, ircInstance:Irc) -> None: def __init__(self, ircInstance:Irc) -> None:
@@ -58,22 +59,10 @@ class Jsonrpc():
self.__load_module_configuration() self.__load_module_configuration()
# End of mandatory methods you can start your customization # # End of mandatory methods you can start your customization #
# self.UnrealIrcdRpcLive: Live = Live( self.UnrealIrcdRpcLive: Live = Live(path_to_socket_file=self.Config.JSONRPC_PATH_TO_SOCKET_FILE,
# req_method='unixsocket', callback_object_instance=self,
# path_to_socket_file=self.Config.JSONRPC_PATH_TO_SOCKET_FILE, callback_method_name='callback_sent_to_irc'
# callback_object_instance=self, )
# callback_method_name='callback_sent_to_irc'
# )
self.UnrealIrcdRpcLive: Live = Live(
req_method='websocket',
url=self.Config.JSONRPC_URL,
username=self.Config.JSONRPC_USER,
password=self.Config.JSONRPC_PASSWORD,
callback_object_instance=self,
callback_method_name='callback_sent_to_irc',
debug_level=10
)
self.Rpc: Loader = Loader( self.Rpc: Loader = Loader(
req_method=self.Config.JSONRPC_METHOD, req_method=self.Config.JSONRPC_METHOD,
@@ -90,9 +79,6 @@ class Jsonrpc():
if self.UnrealIrcdRpcLive.Error.code != 0: if self.UnrealIrcdRpcLive.Error.code != 0:
self.Irc.sendPrivMsg(f"[{self.Config.COLORS.red}ERROR{self.Config.COLORS.nogc}] {self.UnrealIrcdRpcLive.Error.message}", self.Config.SERVICE_CHANLOG) self.Irc.sendPrivMsg(f"[{self.Config.COLORS.red}ERROR{self.Config.COLORS.nogc}] {self.UnrealIrcdRpcLive.Error.message}", self.Config.SERVICE_CHANLOG)
if self.ModConfig.jsonrpc == 1:
self.Base.create_thread(self.thread_start_jsonrpc, run_once=True)
return None return None
def __set_commands(self, commands:dict[int, list[str]]) -> None: def __set_commands(self, commands:dict[int, list[str]]) -> None:
@@ -165,10 +151,10 @@ class Jsonrpc():
""" """
try: try:
# Build the default configuration model (Mandatory) # Build the default configuration model (Mandatory)
self.ModConfig = self.ModConfModel(jsonrpc=0) self.ModConfig = self.ModConfModel(param_exemple1='param value 1', param_exemple2=1)
# Sync the configuration with core configuration (Mandatory) # Sync the configuration with core configuration (Mandatory)
self.Base.db_sync_core_config(self.module_name, self.ModConfig) #self.Base.db_sync_core_config(self.module_name, self.ModConfig)
return None return None
@@ -197,7 +183,6 @@ class Jsonrpc():
command = str(cmd[0]).lower() command = str(cmd[0]).lower()
dnickname = self.Config.SERVICE_NICKNAME dnickname = self.Config.SERVICE_NICKNAME
dchannel = self.Config.SERVICE_CHANLOG
fromuser = user fromuser = user
fromchannel = str(channel) if not channel is None else None fromchannel = str(channel) if not channel is None else None
@@ -214,19 +199,10 @@ class Jsonrpc():
match option: match option:
case 'on': case 'on':
for thread in self.Base.running_threads:
if thread.getName() == 'thread_start_jsonrpc':
if thread.is_alive():
self.Irc.sendPrivMsg(f"Thread {thread.getName()} is running", dchannel)
else:
self.Irc.sendPrivMsg(f"Thread {thread.getName()} is not running, wait untill the process will be cleaned up", dchannel)
self.Base.create_thread(self.thread_start_jsonrpc, run_once=True) self.Base.create_thread(self.thread_start_jsonrpc, run_once=True)
self.__update_configuration('jsonrpc', 1)
case 'off': case 'off':
self.UnrealIrcdRpcLive.unsubscribe() self.UnrealIrcdRpcLive.unsubscribe()
self.__update_configuration('jsonrpc', 0)
except IndexError as ie: except IndexError as ie:
self.Logs.error(ie) self.Logs.error(ie)
@@ -275,9 +251,6 @@ class Jsonrpc():
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :VHOST : {UserInfo.user.vhost}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :VHOST : {UserInfo.user.vhost}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :CLIENT PORT : {UserInfo.client_port}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :CLIENT PORT : {UserInfo.client_port}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :SERVER PORT : {UserInfo.server_port}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :SERVER PORT : {UserInfo.server_port}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :CERTFP : {UserInfo.tls.certfp}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :CIPHER : {UserInfo.tls.cipher}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :IDLE SINCE : {UserInfo.idle_since}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :IDLE SINCE : {UserInfo.idle_since}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :CONNECTED SINCE : {UserInfo.connected_since}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :CONNECTED SINCE : {UserInfo.connected_since}')

View File

@@ -124,16 +124,8 @@ class Test():
return None return None
def cmd(self, data:list) -> None: def cmd(self, data:list) -> None:
try:
cmd = list(data).copy()
return None return None
except KeyError as ke:
self.Base.logs.error(f"Key Error: {ke}")
except IndexError as ie:
self.Base.logs.error(f"{ie} / {cmd} / length {str(len(cmd))}")
except Exception as err:
self.Base.logs.error(f"General Error: {err}")
def _hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None: def _hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None:

View File

@@ -242,16 +242,15 @@ class Votekick():
return None return None
def cmd(self, data:list) -> None: def cmd(self, data:list) -> None:
try: cmd = list(data).copy()
cmd = list(data).copy()
return None
except KeyError as ke: match cmd[2]:
self.Base.logs.error(f"Key Error: {ke}") case 'SJOIN':
except IndexError as ie: pass
self.Base.logs.error(f"{ie} / {cmd} / length {str(len(cmd))}") case _:
except Exception as err: pass
self.Base.logs.error(f"General Error: {err}")
return None
def _hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None: def _hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None:
# cmd is the command starting from the user command # cmd is the command starting from the user command

View File

@@ -1,9 +1,3 @@
{ {
"version": "5.4.0", "version": "5.3.4"
"requests": "2.32.3",
"psutil": "6.0.0",
"unrealircd_rpc_py": "1.0.6",
"sqlalchemy": "2.0.35",
"faker": "30.1.0"
} }