Moving modules in separate folders

This commit is contained in:
adator
2025-08-08 17:38:45 +02:00
parent 7a50bc9632
commit 0a655b2df0
13 changed files with 138 additions and 127 deletions

View File

@@ -391,7 +391,7 @@ class Base:
result = response.fetchall() result = response.fetchall()
for param, value in result: for param, value in result:
if type(getattr(dataclassObj, param)) == list: if isinstance(getattr(dataclassObj, param), list):
value = ast.literal_eval(value) value = ast.literal_eval(value)
setattr(dataclassObj, param, self.int_if_possible(value)) setattr(dataclassObj, param, self.int_if_possible(value))

View File

@@ -1,6 +1,6 @@
from re import match, findall, search from re import match, findall, search
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING, Union from typing import TYPE_CHECKING, Optional, Union
from ssl import SSLEOFError, SSLError from ssl import SSLEOFError, SSLError
if TYPE_CHECKING: if TYPE_CHECKING:
@@ -17,14 +17,21 @@ class Unrealircd6:
self.__Base = ircInstance.Base self.__Base = ircInstance.Base
self.__Settings = ircInstance.Base.Settings self.__Settings = ircInstance.Base.Settings
self.known_protocol = ['SJOIN', 'UID', 'MD', 'QUIT', 'SQUIT', self.known_protocol: set[str] = {'SJOIN', 'UID', 'MD', 'QUIT', 'SQUIT',
'EOS', 'PRIVMSG', 'MODE', 'UMODE2', 'EOS', 'PRIVMSG', 'MODE', 'UMODE2',
'VERSION', 'REPUTATION', 'SVS2MODE', 'VERSION', 'REPUTATION', 'SVS2MODE',
'SLOG', 'NICK', 'PART', 'PONG' 'SLOG', 'NICK', 'PART', 'PONG'}
]
self.__Base.logs.info(f"** Loading protocol [{__name__}]") self.__Base.logs.info(f"** Loading protocol [{__name__}]")
def get_ircd_protocol_poisition(self, cmd: list[str]) -> tuple[int, Optional[str]]:
for index, token in enumerate(cmd):
if token.upper() in self.known_protocol:
return index, token.upper()
return (-1, None)
def send2socket(self, message: str, print_log: bool = True) -> None: def send2socket(self, message: str, print_log: bool = True) -> None:
"""Envoit les commandes à envoyer au serveur. """Envoit les commandes à envoyer au serveur.

View File

@@ -1,10 +1,26 @@
from datetime import datetime from datetime import datetime
from dataclasses import dataclass, field from json import dumps
from typing import Literal from dataclasses import dataclass, field, asdict, fields
from typing import Literal, Any
from os import sep from os import sep
@dataclass @dataclass
class MClient: class MainModel:
"""Parent Model contains important methods"""
def to_dict(self) -> dict[str, Any]:
"""Return the fields of a dataclass instance as a new dictionary mapping field names to field values."""
return asdict(self)
def to_json(self) -> str:
"""Return the object of a dataclass a json str."""
return dumps(self.to_dict())
def get_attributes(self) -> list[str]:
"""Return a list of attributes name"""
return [f.name for f in fields(self)]
@dataclass
class MClient(MainModel):
"""Model Client for registred nickname""" """Model Client for registred nickname"""
uid: str = None uid: str = None
account: str = None account: str = None
@@ -22,7 +38,7 @@ class MClient:
connexion_datetime: datetime = field(default=datetime.now()) connexion_datetime: datetime = field(default=datetime.now())
@dataclass @dataclass
class MUser: class MUser(MainModel):
"""Model User""" """Model User"""
uid: str = None uid: str = None
@@ -40,7 +56,7 @@ class MUser:
connexion_datetime: datetime = field(default=datetime.now()) connexion_datetime: datetime = field(default=datetime.now())
@dataclass @dataclass
class MAdmin: class MAdmin(MainModel):
"""Model Admin""" """Model Admin"""
uid: str = None uid: str = None
@@ -59,7 +75,7 @@ class MAdmin:
level: int = 0 level: int = 0
@dataclass @dataclass
class MReputation: class MReputation(MainModel):
"""Model Reputation""" """Model Reputation"""
uid: str = None uid: str = None
nickname: str = None nickname: str = None
@@ -77,7 +93,7 @@ class MReputation:
secret_code: str = None secret_code: str = None
@dataclass @dataclass
class MChannel: class MChannel(MainModel):
"""Model Channel""" """Model Channel"""
name: str = None name: str = None
@@ -92,7 +108,7 @@ class MChannel:
""" """
@dataclass @dataclass
class ColorModel: class ColorModel(MainModel):
white: str = "\x0300" white: str = "\x0300"
black: str = "\x0301" black: str = "\x0301"
blue: str = "\x0302" blue: str = "\x0302"
@@ -104,7 +120,7 @@ class ColorModel:
underline: str = "\x1F" underline: str = "\x1F"
@dataclass @dataclass
class MConfig: class MConfig(MainModel):
"""Model Configuration""" """Model Configuration"""
SERVEUR_IP: str = "127.0.0.1" SERVEUR_IP: str = "127.0.0.1"
@@ -305,7 +321,7 @@ class MConfig:
"""0: utf-8 | 1: iso-8859-1""" """0: utf-8 | 1: iso-8859-1"""
@dataclass @dataclass
class MClone: class MClone(MainModel):
"""Model Clone""" """Model Clone"""
connected: bool = False connected: bool = False
uid: str = None uid: str = None

View File

@@ -494,6 +494,7 @@ class Irc:
try: try:
# module_name : mod_voice # module_name : mod_voice
module_name = module_name.lower() module_name = module_name.lower()
module_folder = module_name.split('_')[1].lower() # ==> voice
class_name = module_name.split('_')[1].capitalize() # ==> Voice class_name = module_name.split('_')[1].capitalize() # ==> Voice
# print(self.loaded_classes) # print(self.loaded_classes)
@@ -511,7 +512,7 @@ class Irc:
) )
return False return False
the_module = sys.modules['mods.' + module_name] the_module = sys.modules[f'mods.{module_folder}.{module_name}']
importlib.reload(the_module) importlib.reload(the_module)
my_class = getattr(the_module, class_name, None) my_class = getattr(the_module, class_name, None)
new_instance = my_class(self.ircObject) new_instance = my_class(self.ircObject)
@@ -529,7 +530,7 @@ class Irc:
return False return False
# Charger le module # Charger le module
loaded_module = importlib.import_module(f"mods.{module_name}") 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 my_class = getattr(loaded_module, class_name, None) # Récuperer le nom de classe
create_instance_of_the_class = my_class(self.ircObject) # Créer une nouvelle instance de la classe create_instance_of_the_class = my_class(self.ircObject) # Créer une nouvelle instance de la classe
@@ -612,13 +613,14 @@ class Irc:
def reload_module(self, from_user: str, mod_name: str) -> bool: def reload_module(self, from_user: str, mod_name: str) -> bool:
try: try:
module_name = mod_name.lower() # ==> mod_defender module_name = mod_name.lower() # ==> mod_defender
module_folder = module_name.split('_')[1].lower() # ==> defender
class_name = module_name.split('_')[1].capitalize() # ==> Defender class_name = module_name.split('_')[1].capitalize() # ==> Defender
if 'mods.' + module_name in sys.modules: if 'mods.' + module_name in sys.modules:
self.Logs.info('Unload the module ...') self.Logs.info('Unload the module ...')
self.loaded_classes[class_name].unload() self.loaded_classes[class_name].unload()
self.Logs.info('Module Already Loaded ... reloading the module ...') self.Logs.info('Module Already Loaded ... reloading the module ...')
the_module = sys.modules['mods.' + module_name] the_module = sys.modules[f'mods.{module_folder}.{module_name}']
importlib.reload(the_module) importlib.reload(the_module)
# Supprimer la class déja instancier # Supprimer la class déja instancier

View File

@@ -2,53 +2,19 @@ import socket
import json import json
import time import time
import re import re
from webbrowser import get
import psutil import psutil
import requests import requests
from dataclasses import dataclass
from datetime import datetime from datetime import datetime
from typing import Union, TYPE_CHECKING from typing import Union, TYPE_CHECKING
import core.definition as df
# Le module crée devra réspecter quelques conditions import core.definition as df
# 1. Le nom de la classe devra toujours s'appeler comme le module. Exemple => nom de class Defender | nom du module mod_defender import mods.defender.schemas as schemas
# 2. la methode __init__ devra toujours avoir les parametres suivant (self, irc:object)
# 1 . Créer la variable Irc dans le module
# 2 . Récuperer la configuration dans une variable
# 3 . Définir et enregistrer les nouvelles commandes
# 4 . Créer vos tables, en utilisant toujours le nom des votre classe en minuscule ==> defender_votre-table
# 3. Methode suivantes:
# cmd(self, data:list)
# hcmds(self, user:str, cmd: list)
# unload(self)
if TYPE_CHECKING: if TYPE_CHECKING:
from core.irc import Irc from core.irc import Irc
class Defender(): class Defender():
@dataclass
class ModConfModel:
reputation: int
reputation_timer: int
reputation_seuil: int
reputation_score_after_release: int
reputation_ban_all_chan: int
reputation_sg: int
local_scan: int
psutil_scan: int
abuseipdb_scan: int
freeipapi_scan: int
cloudfilt_scan: int
flood: int
flood_message: int
flood_time: int
flood_timer: int
autolimit: int
autolimit_amount: int
autolimit_interval: int
def __init__(self, ircInstance: 'Irc') -> None: def __init__(self, ircInstance: 'Irc') -> None:
# Module name (Mandatory) # Module name (Mandatory)
@@ -81,6 +47,9 @@ class Defender():
# Add Reputation object to the module (Optional) # Add Reputation object to the module (Optional)
self.Reputation = ircInstance.Reputation self.Reputation = ircInstance.Reputation
# Add module schemas
self.Schemas = schemas
# Create module commands (Mandatory) # Create module commands (Mandatory)
self.Irc.build_command(0, self.module_name, 'code', 'Display the code or key for access') self.Irc.build_command(0, self.module_name, 'code', 'Display the code or key for access')
self.Irc.build_command(1, self.module_name, 'info', 'Provide information about the channel or server') self.Irc.build_command(1, self.module_name, 'info', 'Provide information about the channel or server')
@@ -97,7 +66,7 @@ class Defender():
self.__init_module() self.__init_module()
# Log the module # Log the module
self.Logs.debug(f'-- Module {self.module_name} loaded ...') self.Logs.debug(f'-- Module {self.module_name} V2 loaded ...')
def __init_module(self) -> None: def __init_module(self) -> None:
@@ -179,24 +148,14 @@ class Defender():
def __load_module_configuration(self) -> None: def __load_module_configuration(self) -> None:
"""### Load Module Configuration """### Load Module Configuration
""" """
try:
# Variable qui va contenir les options de configuration du module Defender # Variable qui va contenir les options de configuration du module Defender
self.ModConfig = self.ModConfModel( self.ModConfig = self.Schemas.ModConfModel()
reputation=0, reputation_timer=1, reputation_seuil=26, reputation_score_after_release=27,
reputation_ban_all_chan=0,reputation_sg=1,
local_scan=0, psutil_scan=0, abuseipdb_scan=0, freeipapi_scan=0, cloudfilt_scan=0,
flood=0, flood_message=5, flood_time=1, flood_timer=20,
autolimit=1, autolimit_amount=3, autolimit_interval=3
)
# 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
except TypeError as te:
self.Logs.critical(te)
def __update_configuration(self, param_key: str, param_value: str): def __update_configuration(self, param_key: str, param_value: str):
self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value) self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value)
@@ -415,8 +374,6 @@ class Defender():
Args: Args:
action (str): _description_ action (str): _description_
timer (int): _description_
nickname (str): _description_
channel (str): _description_ channel (str): _description_
Returns: Returns:
@@ -973,10 +930,17 @@ class Defender():
def cmd(self, data: list[str]) -> None: def cmd(self, data: list[str]) -> None:
try: try:
service_id = self.Config.SERVICE_ID # Defender serveur id if not data or len(data) < 2:
cmd = list(data).copy() return None
match cmd[1]: service_id = self.Config.SERVICE_ID
p = self.Protocol
cmd = data.copy() if isinstance(data, list) else list(data).copy()
index, command = p.get_ircd_protocol_poisition(cmd)
if index == -1:
return None
match command:
case 'REPUTATION': case 'REPUTATION':
# :001 REPUTATION 8.8.8.8 118 # :001 REPUTATION 8.8.8.8 118
@@ -994,11 +958,6 @@ class Defender():
except IndexError as ie: except IndexError as ie:
self.Logs.error(f'cmd reputation: index error: {ie}') self.Logs.error(f'cmd reputation: index error: {ie}')
if len(cmd) < 3:
return None
match cmd[2]:
case 'MODE': case 'MODE':
# ['...', ':001XSCU0Q', 'MODE', '#jail', '+b', '~security-group:unknown-users'] # ['...', ':001XSCU0Q', 'MODE', '#jail', '+b', '~security-group:unknown-users']
# ['@unrealircd.org/...', ':001C0MF01', 'MODE', '#services', '+l', '1'] # ['@unrealircd.org/...', ':001C0MF01', 'MODE', '#services', '+l', '1']
@@ -1011,19 +970,22 @@ class Defender():
if self.ModConfig.autolimit == 1: if self.ModConfig.autolimit == 1:
if mode == '+l' or mode == '-l': if mode == '+l' or mode == '-l':
chan = self.Channel.get_Channel(channel) chan = self.Channel.get_Channel(channel)
self.Protocol.send2socket(f":{self.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + self.ModConfig.autolimit_amount}") p.send2socket(f":{self.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + self.ModConfig.autolimit_amount}")
if self.Config.SALON_JAIL == channel: if self.Config.SALON_JAIL == channel:
if mode == '+b' and group_to_unban in group_to_check: if mode == '+b' and group_to_unban in group_to_check:
self.Protocol.send2socket(f":{service_id} MODE {self.Config.SALON_JAIL} -b ~security-group:unknown-users") p.send2socket(f":{service_id} MODE {self.Config.SALON_JAIL} -b ~security-group:unknown-users")
self.Protocol.send2socket(f":{service_id} MODE {self.Config.SALON_JAIL} -eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users") p.send2socket(f":{service_id} MODE {self.Config.SALON_JAIL} -eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
return None
case 'PRIVMSG': case 'PRIVMSG':
cmd.pop(0) # ['@mtag....',':python', 'PRIVMSG', '#defender', ':zefzefzregreg', 'regg', 'aerg']
user_trigger = str(cmd[0]).replace(':','') user_trigger = str(cmd[1]).replace(':','')
channel = cmd[2] channel = cmd[3]
find_nickname = self.User.get_nickname(user_trigger) find_nickname = self.User.get_nickname(user_trigger)
self.flood(find_nickname, channel) self.flood(find_nickname, channel)
return None
case 'UID': case 'UID':
# If Init then do nothing # If Init then do nothing
@@ -1036,6 +998,10 @@ class Defender():
# Get User information # Get User information
_User = self.User.get_User(str(cmd[7])) _User = self.User.get_User(str(cmd[7]))
if _User is None:
self.Logs.critical(f'This UID: [{cmd[7]}] is not available please check why')
return None
# If user is not service or IrcOp then scan them # If user is not service or IrcOp then scan them
if not re.match(r'^.*[S|o?].*$', _User.umodes): if not re.match(r'^.*[S|o?].*$', _User.umodes):
self.abuseipdb_UserModel.append(_User) if self.ModConfig.abuseipdb_scan == 1 and _User.remote_ip not in self.Config.WHITELISTED_IP else None self.abuseipdb_UserModel.append(_User) if self.ModConfig.abuseipdb_scan == 1 and _User.remote_ip not in self.Config.WHITELISTED_IP else None
@@ -1044,10 +1010,6 @@ class Defender():
self.psutil_UserModel.append(_User) if self.ModConfig.psutil_scan == 1 and _User.remote_ip not in self.Config.WHITELISTED_IP else None self.psutil_UserModel.append(_User) if self.ModConfig.psutil_scan == 1 and _User.remote_ip not in self.Config.WHITELISTED_IP else None
self.localscan_UserModel.append(_User) if self.ModConfig.local_scan == 1 and _User.remote_ip not in self.Config.WHITELISTED_IP else None self.localscan_UserModel.append(_User) if self.ModConfig.local_scan == 1 and _User.remote_ip not 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_flag = self.ModConfig.reputation
reputation_seuil = self.ModConfig.reputation_seuil reputation_seuil = self.ModConfig.reputation_seuil
@@ -1058,12 +1020,8 @@ class Defender():
# currentDateTime = self.Base.get_datetime() # currentDateTime = self.Base.get_datetime()
self.Reputation.insert( self.Reputation.insert(
self.Loader.Definition.MReputation( self.Loader.Definition.MReputation(
**_User.__dict__, **_User.to_dict(),
secret_code=self.Base.get_random(8) secret_code=self.Base.get_random(8)
# 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
) )
) )
if self.Reputation.is_exist(_User.uid): if self.Reputation.is_exist(_User.uid):
@@ -1071,42 +1029,46 @@ class Defender():
self.system_reputation(_User.uid) self.system_reputation(_User.uid)
self.Logs.info('Démarrer le systeme de reputation') self.Logs.info('Démarrer le systeme de reputation')
return None
case 'SJOIN': case 'SJOIN':
# ['@msgid=F9B7JeHL5pj9nN57cJ5pEr;time=2023-12-28T20:47:24.305Z', ':001', 'SJOIN', '1702138958', '#welcome', ':0015L1AHL'] # ['@msgid=F9B7JeHL5pj9nN57cJ5pEr..', ':001', 'SJOIN', '1702138958', '#welcome', ':0015L1AHL']
try: try:
cmd.pop(0) parsed_chan = cmd[4] if self.Channel.Is_Channel(cmd[4]) else None
parsed_chan = cmd[3] if self.Channel.Is_Channel(cmd[3]) else None parsed_UID = self.User.clean_uid(cmd[5])
if self.ModConfig.reputation == 1: if self.ModConfig.reputation == 1:
parsed_UID = self.User.clean_uid(cmd[4])
get_reputation = self.Reputation.get_Reputation(parsed_UID) get_reputation = self.Reputation.get_Reputation(parsed_UID)
if parsed_chan != self.Config.SALON_JAIL: if parsed_chan != self.Config.SALON_JAIL:
self.Protocol.send2socket(f":{service_id} MODE {parsed_chan} +b ~security-group:unknown-users") p.send2socket(f":{service_id} MODE {parsed_chan} +b ~security-group:unknown-users")
self.Protocol.send2socket(f":{service_id} MODE {parsed_chan} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users") p.send2socket(f":{service_id} MODE {parsed_chan} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
if get_reputation is not None: if get_reputation is not None:
isWebirc = get_reputation.isWebirc isWebirc = get_reputation.isWebirc
if not isWebirc: if not isWebirc:
if parsed_chan != self.Config.SALON_JAIL: if parsed_chan != self.Config.SALON_JAIL:
self.Protocol.send_sapart(nick_to_sapart=get_reputation.nickname, channel_name=parsed_chan) p.send_sapart(nick_to_sapart=get_reputation.nickname, channel_name=parsed_chan)
if self.ModConfig.reputation_ban_all_chan == 1 and not isWebirc: if self.ModConfig.reputation_ban_all_chan == 1 and not isWebirc:
if parsed_chan != self.Config.SALON_JAIL: if parsed_chan != self.Config.SALON_JAIL:
self.Protocol.send2socket(f":{service_id} MODE {parsed_chan} +b {get_reputation.nickname}!*@*") p.send2socket(f":{service_id} MODE {parsed_chan} +b {get_reputation.nickname}!*@*")
self.Protocol.send2socket(f":{service_id} KICK {parsed_chan} {get_reputation.nickname}") p.send2socket(f":{service_id} KICK {parsed_chan} {get_reputation.nickname}")
self.Logs.debug(f'SJOIN parsed_uid : {parsed_UID}') self.Logs.debug(f'SJOIN parsed_uid : {parsed_UID}')
return None
except KeyError as ke: except KeyError as ke:
self.Logs.error(f"key error SJOIN : {ke}") self.Logs.error(f"key error SJOIN : {ke}")
case 'SLOG': case 'SLOG':
# self.Base.scan_ports(cmd[7]) ['@unrealircd...', ':001', 'SLOG', 'info', 'blacklist', 'BLACKLIST_HIT', ':[Blacklist]', 'IP', '162.x.x.x', 'matches', 'blacklist', 'dronebl', '(dnsbl.dronebl.org/reply=6)']
cmd.pop(0)
if not self.Base.is_valid_ip(cmd[8]):
return None
if not self.Base.is_valid_ip(cmd[7]):
return None return None
# if self.ModConfig.local_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: # if self.ModConfig.local_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
@@ -1125,11 +1087,10 @@ class Defender():
# self.cloudfilt_remote_ip.append(cmd[7]) # self.cloudfilt_remote_ip.append(cmd[7])
case 'NICK': case 'NICK':
# :0010BS24L NICK [NEWNICK] 1697917711 # ['@unrealircd.org...', ':001MZQ0RB', 'NICK', 'halow', '1754663712']
# Changement de nickname # Changement de nickname
try: try:
cmd.pop(0) uid = self.User.clean_uid(str(cmd[1]))
uid = str(cmd[0]).replace(':','')
get_Reputation = self.Reputation.get_Reputation(uid) get_Reputation = self.Reputation.get_Reputation(uid)
jail_salon = self.Config.SALON_JAIL jail_salon = self.Config.SALON_JAIL
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
@@ -1140,38 +1101,41 @@ class Defender():
# Update the new nickname # Update the new nickname
oldnick = get_Reputation.nickname oldnick = get_Reputation.nickname
newnickname = cmd[2] newnickname = cmd[3]
get_Reputation.nickname = newnickname get_Reputation.nickname = newnickname
# If ban in all channel is ON then unban old nickname an ban the new nickname # If ban in all channel is ON then unban old nickname an ban the new nickname
if self.ModConfig.reputation_ban_all_chan == 1: 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: if chan.name != jail_salon:
self.Protocol.send2socket(f":{service_id} MODE {chan.name} -b {oldnick}!*@*") p.send2socket(f":{service_id} MODE {chan.name} -b {oldnick}!*@*")
self.Protocol.send2socket(f":{service_id} MODE {chan.name} +b {newnickname}!*@*") p.send2socket(f":{service_id} MODE {chan.name} +b {newnickname}!*@*")
return None
except KeyError as ke: except KeyError as ke:
self.Logs.error(f'cmd - NICK - KeyError: {ke}') self.Logs.error(f'cmd - NICK - KeyError: {ke}')
case 'QUIT': case 'QUIT':
# :001N1WD7L QUIT :Quit: free_znc_1 # ['@unrealircd.org...', ':001MZQ0RB', 'QUIT', ':Quit:', '....']
cmd.pop(0)
ban_all_chan = self.Base.int_if_possible(self.ModConfig.reputation_ban_all_chan) ban_all_chan = self.Base.int_if_possible(self.ModConfig.reputation_ban_all_chan)
user_id = str(cmd[0]).replace(':','') final_UID = self.User.clean_uid(str(cmd[1]))
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) get_user_reputation = self.Reputation.get_Reputation(final_UID)
if get_user_reputation is not None: if get_user_reputation is not None:
final_nickname = get_user_reputation.nickname final_nickname = get_user_reputation.nickname
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 and ban_all_chan == 1:
self.Protocol.send2socket(f":{service_id} MODE {chan.name} -b {final_nickname}!*@*") p.send2socket(f":{service_id} MODE {chan.name} -b {final_nickname}!*@*")
self.Reputation.delete(final_UID) self.Reputation.delete(final_UID)
return None
case _:
return None
except KeyError as ke: except KeyError as ke:
self.Logs.error(f"{ke} / {cmd} / length {str(len(cmd))}") self.Logs.error(f"{ke} / {cmd} / length {str(len(cmd))}")
except IndexError as ie: except IndexError as ie:
@@ -1183,8 +1147,7 @@ class Defender():
command = str(cmd[0]).lower() command = str(cmd[0]).lower()
fromuser = user fromuser = user
fromchannel = channel if self.Channel.Is_Channel(channel) else None channel = fromchannel = channel if self.Channel.Is_Channel(channel) else None
channel = fromchannel
dnickname = self.Config.SERVICE_NICKNAME # Defender nickname dnickname = self.Config.SERVICE_NICKNAME # Defender nickname
dchanlog = self.Config.SERVICE_CHANLOG # Defender chan log dchanlog = self.Config.SERVICE_CHANLOG # Defender chan log
@@ -1816,16 +1779,17 @@ class Defender():
case 'sentinel': case 'sentinel':
# .sentinel on # .sentinel on
activation = str(cmd[1]).lower() activation = str(cmd[1]).lower()
service_id = self.Config.SERVICE_ID
channel_to_dont_quit = [self.Config.SALON_JAIL, self.Config.SERVICE_CHANLOG] channel_to_dont_quit = [self.Config.SALON_JAIL, self.Config.SERVICE_CHANLOG]
if activation == 'on': if activation == 'on':
for chan in self.Channel.UID_CHANNEL_DB: for chan in self.Channel.UID_CHANNEL_DB:
if chan.name not in channel_to_dont_quit: if chan.name not in channel_to_dont_quit:
self.Protocol.send_join_chan(uidornickname=dnickname, channel=chan.name) self.Protocol.send_join_chan(uidornickname=dnickname, channel=chan.name)
return None
if activation == 'off': if activation == 'off':
for chan in self.Channel.UID_CHANNEL_DB: for chan in self.Channel.UID_CHANNEL_DB:
if chan.name not in channel_to_dont_quit: if chan.name not in channel_to_dont_quit:
self.Protocol.part(uidornickname=dnickname, channel=chan.name) self.Protocol.send_part_chan(uidornickname=dnickname, channel=chan.name)
self.join_saved_channels() self.join_saved_channels()
return None

22
mods/defender/schemas.py Normal file
View File

@@ -0,0 +1,22 @@
from core.definition import MainModel, dataclass
@dataclass
class ModConfModel(MainModel):
reputation: int = 0
reputation_timer: int = 1
reputation_seuil: int = 26
reputation_score_after_release: int = 27
reputation_ban_all_chan: int = 0
reputation_sg: int = 1
local_scan: int = 0
psutil_scan: int = 0
abuseipdb_scan: int = 0
freeipapi_scan: int = 0
cloudfilt_scan: int = 0
flood: int = 0
flood_message: int = 5
flood_time: int = 1
flood_timer: int = 20
autolimit: int = 0
autolimit_amount: int = 3
autolimit_interval: int = 3

0
mods/defender/utils.py Normal file
View File

View File

@@ -3,7 +3,7 @@
"requests": "2.32.3", "requests": "2.32.3",
"psutil": "6.0.0", "psutil": "6.0.0",
"unrealircd_rpc_py": "2.0.0", "unrealircd_rpc_py": "2.0.1",
"sqlalchemy": "2.0.35", "sqlalchemy": "2.0.35",
"faker": "30.1.0" "faker": "30.1.0"
} }