V6.1.5 i forgot

This commit is contained in:
adator
2025-03-10 20:47:53 +01:00
parent befe452df8
commit 8cac3316fb
16 changed files with 755 additions and 187 deletions

View File

@@ -37,6 +37,9 @@ class Admin:
result = False
if not self.is_exist(uid):
return result
for record in self.UID_ADMIN_DB:
if record.uid == uid:
# If the admin exist, update and do not go further
@@ -46,7 +49,7 @@ class Admin:
return result
if not result:
self.Logs.critical(f'The new nickname {newNickname} was not updated, uid = {uid}')
self.Logs.critical(f'Admin: The new nickname {newNickname} was not updated, uid = {uid}')
return result
@@ -124,4 +127,18 @@ class Admin:
if record.uid == uidornickname:
nickname = record.nickname
self.Logs.debug(f'The value {uidornickname} -- {nickname}')
return nickname
return nickname
def is_exist(self, uidornickname: str) -> bool:
"""Check if this uid or nickname is logged in as an admin
Args:
uidornickname (str): The UID or the Nickname
Returns:
bool: True if the Nickname or UID is an admin
"""
if self.get_Admin(uidornickname) is None:
return False
else:
return True

View File

@@ -90,6 +90,7 @@ class Channel:
if self.Base.clean_uid(userid) == self.Base.clean_uid(uid):
chanObj.uids.remove(userid)
result = True
self.Logs.debug(f"The UID: {userid} has been removed from the {channel_name}")
self.clean_channel()

View File

@@ -219,7 +219,7 @@ class Client:
account_to_check_result = account_to_check_query.fetchone()
if account_to_check_result:
self.Logs.error(f"Account ({account}) already exist")
self.Logs.debug(f"Account ({account}) already exist")
return True
return False

View File

@@ -245,6 +245,33 @@ class Unrealircd6:
self.__Irc.Channel.insert(self.__Irc.Loader.Definition.MChannel(name=channel, uids=[self.__Config.SERVICE_ID]))
return None
def send_svs_nick(self, oldnickname: str, newnickname: str) -> None:
unixtime = self.__Base.get_unixtime()
self.send2socket(f':{self.__Config.SERVEUR_ID} SVSNICK {oldnickname} {newnickname} {unixtime}')
user_obj = self.__Irc.User.get_User(oldnickname)
self.__Irc.User.update_nickname(user_obj.uid, newnickname)
return None
def send_sjoin(self, uid_to_join: str, channel: str) -> None:
"""UID will join a channel with pre defined umodes
Args:
channel (str): Channel to join
"""
if not self.__Irc.Channel.Is_Channel(channel):
self.__Base.logs.error(f"The channel [{channel}] is not valid")
return None
self.send2socket(f":{self.__Config.SERVEUR_ID} SJOIN {self.__Base.get_unixtime()} {channel} {self.__Config.SERVICE_UMODES} :{uid_to_join}")
self.send2socket(f":{self.__Config.SERVICE_ID} MODE {channel} {self.__Config.SERVICE_UMODES} {uid_to_join}")
# Add defender to the channel uids list
self.__Irc.Channel.insert(self.__Irc.Loader.Definition.MChannel(name=channel, uids=[uid_to_join]))
return None
def send_sapart(self, nick_to_sapart: str, channel_name: str) -> None:
"""_summary_
@@ -326,7 +353,26 @@ class Unrealircd6:
except Exception as err:
self.__Base.logs.error(f"{__name__} - General Error: {err}")
def send_quit(self, uid: str, reason: str, print_log: True) -> None:
def send_svs2mode(self, service_uid: str, nickname: str, user_mode: str) -> None:
try:
user_obj = self.__Irc.User.get_User(uidornickname=nickname)
service_uid = service_uid
if user_obj is None:
# User not exist: leave
return None
self.send2socket(f':{service_uid} SVS2MODE {nickname} {user_mode}')
# Update new mode
self.__Irc.User.update_mode(user_obj.uid, user_mode)
return None
except Exception as err:
self.__Base.logs.error(f"{__name__} - General Error: {err}")
def send_quit(self, uid: str, reason: str, print_log: bool = True) -> None:
"""Send quit message
- Delete uid from User object
- Delete uid from Clone object
@@ -469,6 +515,22 @@ class Unrealircd6:
self.send2socket(f":{self.__Config.SERVICE_NICKNAME} MODE {channel_name} {channel_mode}")
return None
def send_topic_chan(self, channel_name: str, topic_msg: str) -> None:
"""Set a channel topic
Args:
channel_name (str): Channel name starting with #
topic_msg (str): The message of the topic
"""
if self.__Irc.Channel.Is_Channel(channel_name) is None:
self.__Base.logs.error(f"The channel {channel_name} is not valid")
return None
self.send2socket(f":{self.__Config.SERVICE_NICKNAME} TOPIC {channel_name} :{topic_msg}")
return None
def send_raw(self, raw_command: str) -> None:
self.send2socket(f":{self.__Config.SERVICE_NICKNAME} {raw_command}")
@@ -715,7 +777,7 @@ class Unrealircd6:
# ['@unrealircd.org/geoip=FR;unrealircd.org/userhost=50d6492c@80.214.73.44;unrealircd.org/userip=50d6492c@80.214.73.44;msgid=YSIPB9q4PcRu0EVfC9ci7y-/mZT0+Gj5FLiDSZshH5NCw;time=2024-08-15T15:35:53.772Z',
# ':001EPFBRD', 'PART', '#welcome', ':WEB', 'IRC', 'Paris']
uid = str(serverMsg[1]).lstrip(':')
uid = str(serverMsg[1]).replace(':', '')
channel = str(serverMsg[3]).lower()
self.__Irc.Channel.delete_user_from_channel(channel, uid)
@@ -839,29 +901,23 @@ class Unrealircd6:
isWebirc = True if 'webirc' in serverMsg[0] else False
isWebsocket = True if 'websocket' in serverMsg[0] else False
uid = str(serverMsg[8])
nickname = str(serverMsg[3])
hopcount = str(serverMsg[4])
timestamp = str(serverMsg[5])
username = str(serverMsg[6])
hostname = str(serverMsg[7])
uid = str(serverMsg[8])
servicestamp = str(serverMsg[9])
umodes = str(serverMsg[10])
vhost = str(serverMsg[11])
if not 'S' in umodes:
remote_ip = self.__Base.decode_ip(str(serverMsg[13]))
else:
remote_ip = '127.0.0.1'
# extract realname
cloacked_host = str(serverMsg[12])
remote_ip = self.__Base.decode_ip(str(serverMsg[13])) if 'S' in umodes else '127.0.0.1'
realname = ' '.join(serverMsg[14:]).lstrip(':')
# Extract Geoip information
pattern = r'^.*geoip=cc=(\S{2}).*$'
geoip_match = match(pattern, serverMsg[0])
if geoip_match:
geoip = geoip_match.group(1)
else:
geoip = None
geoip = geoip_match.group(1) if geoip_match else None
score_connexion = self.__Irc.first_score
@@ -874,6 +930,10 @@ class Unrealircd6:
hostname=hostname,
umodes=umodes,
vhost=vhost,
hopcount=hopcount,
timestamp=timestamp,
servicestamp=servicestamp,
cloacked_host=cloacked_host,
isWebirc=isWebirc,
isWebsocket=isWebsocket,
remote_ip=remote_ip,
@@ -940,7 +1000,7 @@ class Unrealircd6:
fromchannel = str(cmd[2]).lower() if self.__Irc.Channel.Is_Channel(cmd[2]) else None
self.__Irc.hcmds(user_trigger, fromchannel, arg, cmd)
if cmd[2] == self.__Config.SERVICE_ID:
if cmd[2] == self.__Config.SERVICE_ID or cmd[2] == self.__Settings.NICKSERV_UID:
pattern = fr'^:.*?:(.*)$'
hcmds = search(pattern, ' '.join(cmd))

View File

@@ -13,3 +13,5 @@ class Settings:
PROTOCTL_USER_MODES: list[str] = []
PROTOCTL_PREFIX: list[str] = []
NICKSERV_UID: str = None

View File

@@ -6,14 +6,18 @@ from os import sep
@dataclass
class MClient:
"""Model Client for registred nickname"""
uid: str = None
account: str = None
uid: str = None
nickname: str = None
username: str = None
realname: str = None
hostname: str = None
umodes: str = None
vhost: str = None
hopcount: str = None
timestamp: str = None
servicestamp: str = None
cloacked_host: str = None
isWebirc: bool = False
isWebsocket: bool = False
remote_ip: str = None
@@ -32,6 +36,10 @@ class MUser:
hostname: str = None
umodes: str = None
vhost: str = None
hopcount: str = None
timestamp: str = None
servicestamp: str = None
cloacked_host: str = None
isWebirc: bool = False
isWebsocket: bool = False
remote_ip: str = None
@@ -50,6 +58,10 @@ class MAdmin:
hostname: str = None
umodes: str = None
vhost: str = None
hopcount: str = None
timestamp: str = None
servicestamp: str = None
cloacked_host: str = None
isWebirc: bool = False
isWebsocket: bool = False
remote_ip: str = None

View File

@@ -97,7 +97,7 @@ class Irc:
self.build_command(0, 'core', 'uptime', 'Give you since when the service is connected')
self.build_command(0, 'core', 'firstauth', 'First authentication of the Service')
self.build_command(0, 'core', 'register', f'Register your nickname /msg {self.Config.SERVICE_NICKNAME} REGISTER <password> <email>')
self.build_command(0, 'core', 'identify', f'Identify yourself with your password /msg {self.Config.SERVICE_NICKNAME} IDENTIFY <account> <password>')
# self.build_command(0, 'core', 'identify', f'Identify yourself with your password /msg {self.Config.SERVICE_NICKNAME} IDENTIFY <account> <password>')
self.build_command(0, 'core', 'logout', 'Reverse the effect of the identify command')
self.build_command(1, 'core', 'load', 'Load an existing module')
self.build_command(1, 'core', 'unload', 'Unload a module')
@@ -321,7 +321,7 @@ class Irc:
except AssertionError as ae:
self.Logs.error(f"Assertion error : {ae}")
def unload(self) -> None:
def unload(self, reloading: bool = False) -> None:
# This is only to reference the method
return None
@@ -616,7 +616,7 @@ class Irc:
if 'mods.' + module_name in sys.modules:
self.Logs.info('Unload the module ...')
self.loaded_classes[class_name].unload()
self.loaded_classes[class_name].unload(reloading=True)
self.Logs.info('Module Already Loaded ... reloading the module ...')
the_module = sys.modules['mods.' + module_name]
importlib.reload(the_module)
@@ -854,7 +854,7 @@ class Irc:
self.Logs.debug(f"** handle {parsed_protocol}")
case 'PART':
self.Protocol.on_part(serverMsg=parsed_protocol)
self.Protocol.on_part(serverMsg=original_response)
self.Logs.debug(f"** handle {parsed_protocol}")
case 'VERSION':
@@ -1233,154 +1233,6 @@ class Irc:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Impossible de supprimer l'utilisateur.")
self.Logs.warning(f":{dnickname} NOTICE {fromuser} : Impossible de supprimer l'utilisateur.")
case 'register':
# Register PASSWORD EMAIL
try:
if len(cmd) < 3:
self.Protocol.send_notice(
nick_from=dnickname,
nick_to=fromuser,
msg=f'/msg {self.Config.SERVICE_NICKNAME} {command.upper()} <PASSWORD> <EMAIL>'
)
return None
password = cmd[1]
email = cmd[2]
if not self.Base.is_valid_email(email_to_control=email):
self.Protocol.send_notice(
nick_from=dnickname,
nick_to=fromuser,
msg='The email is not valid. You must provide a valid email address (first.name@email.extension)'
)
return None
user_obj = self.User.get_User(fromuser)
if user_obj is None:
self.Logs.error(f"Nickname ({fromuser}) doesn't exist, it is impossible to register this nickname")
return None
# If the account already exist.
if self.Client.db_is_account_exist(fromuser):
self.Protocol.send_notice(
nick_from=dnickname,
nick_to=fromuser,
msg=f"Your account already exist, please try to login instead /msg {self.Config.SERVICE_NICKNAME} IDENTIFY <account> <password>"
)
return None
# If the account doesn't exist then insert into database
data_to_record = {
'createdOn': self.Base.get_datetime(), 'account': fromuser,
'nickname': user_obj.nickname, 'hostname': user_obj.hostname, 'vhost': user_obj.vhost, 'realname': user_obj.realname, 'email': email,
'password': self.Base.crypt_password(password=password), 'level': 0
}
insert_to_db = self.Base.db_execute_query(f"""
INSERT INTO {self.Config.TABLE_CLIENT}
(createdOn, account, nickname, hostname, vhost, realname, email, password, level)
VALUES
(:createdOn, :account, :nickname, :hostname, :vhost, :realname, :email, :password, :level)
""", data_to_record)
if insert_to_db.rowcount > 0:
self.Protocol.send_notice(
nick_from=dnickname,
nick_to=fromuser,
msg=f"You have register your nickname successfully"
)
return None
except ValueError as ve:
self.Logs.error(f"Value Error : {ve}")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {self.Config.SERVICE_PREFIX}{command.upper()} <PASSWORD> <EMAIL>")
case 'identify':
# Identify ACCOUNT PASSWORD
try:
if len(cmd) < 3:
self.Protocol.send_notice(
nick_from=dnickname,
nick_to=fromuser,
msg=f'/msg {self.Config.SERVICE_NICKNAME} {command.upper()} <ACCOUNT> <PASSWORD>'
)
return None
account = str(cmd[1]) # account
encrypted_password = self.Base.crypt_password(cmd[2])
user_obj = self.User.get_User(fromuser)
client_obj = self.Client.get_Client(user_obj.uid)
if client_obj is not None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You are already logged in")
return None
db_query = f"SELECT account FROM {self.Config.TABLE_CLIENT} WHERE account = :account AND password = :password"
db_param = {'account': account, 'password': encrypted_password}
exec_query = self.Base.db_execute_query(
db_query,
db_param
)
result_query = exec_query.fetchone()
if result_query:
account = result_query[0]
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You are now logged in")
client = self.Loader.Definition.MClient(
uid=user_obj.uid, account=account, nickname=fromuser,
username=user_obj.username, realname=user_obj.realname, hostname=user_obj.hostname, umodes=user_obj.umodes, vhost=user_obj.vhost,
isWebirc=user_obj.isWebirc, isWebsocket=user_obj.isWebsocket, remote_ip=user_obj.remote_ip, score_connexion=user_obj.score_connexion,
geoip=user_obj.geoip, connexion_datetime=user_obj.connexion_datetime
)
self.Client.insert(client)
self.Protocol.send_svs_mode(nickname=fromuser, user_mode='+r')
else:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Wrong password or account")
return None
except ValueError as ve:
self.Logs.error(f"Value Error: {ve}")
self.Protocol.send_notice(
nick_from=dnickname,
nick_to=fromuser,
msg=f'/msg {self.Config.SERVICE_NICKNAME} {command.upper()} <ACCOUNT> <PASSWORD>'
)
except Exception as err:
self.Logs.error(f"General Error: {err}")
case 'logout':
try:
# LOGOUT <account>
if len(cmd) < 2:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} <account>")
return None
user_obj = self.User.get_User(fromuser)
if user_obj is None:
self.Logs.error(f"The User [{fromuser}] is not available in the database")
return None
client_obj = self.Client.get_Client(user_obj.uid)
if client_obj is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="Nothing to logout. please login first")
return None
self.Protocol.send_svs_mode(nickname=fromuser, user_mode='-r')
self.Client.delete(user_obj.uid)
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You have been logged out successfully")
except ValueError as ve:
self.Logs.error(f"Value Error: {ve}")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} <account>")
except Exception as err:
self.Logs.error(f"General Error: {err}")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} <account>")
case 'help':
self.generate_help_menu(nickname=fromuser)