Files
phython-mimic-smtp-clientse…/Server/ServerLog.py
2025-07-05 14:24:22 +01:00

127 lines
5.2 KiB
Python

from datetime import datetime
import Session
import User
from DBConn import DBConn, get_unix_timestamp
class ServerLog:
"""Class for holding a server log entry from the database"""
def __init__(self, log_id: int = None):
self.__log_id = log_id
self.__session_ref = None
self.__log_action_dir = None
self.__log_action = None
self.__log_client_ip = None
self.__log_date = None
self.__is_valid = False
self.__session: Session.Session or None = None
self.__user: User.User or None = None
# if a log id is provided load the record from the database
if self.__log_id:
self.__load_server_log()
def __load_server_log(self) -> None:
"""Private method for loading a server log from the database with its id"""
db_connection = DBConn()
server_log_details = db_connection.do_select("server_logs", "row", "*", "log_id = :log_id",
[
{
"field": "log_id",
"value": self.__log_id
}
])
if server_log_details is not None and len(server_log_details) > 0:
self.__log_id = server_log_details['log_id']
self.__session_ref = server_log_details['session_ref']
self.__log_action_dir = server_log_details['log_action_dir']
self.__log_action = server_log_details['log_action']
self.__log_client_ip = server_log_details['log_client_ip']
self.__log_date = server_log_details['log_date']
self.__is_valid = True
def server_log_is_valid(self) -> bool:
"""Method to check if a valid server log has been loaded from the database"""
return self.__is_valid
def get_log_action_dir(self) -> str:
"""Method to get the logs direction variable"""
return self.__log_action_dir
def get_log_action(self) -> str:
"""Method to get the log action variable"""
return self.__log_action
def get_log_action_with_dir(self) -> str:
"""Method to return both the log direction and action as a string"""
return f"{self.get_log_action_dir()} {self.get_log_action()}"
def output_log_line(self, output_format_string: str, date_format_string: str = "%d/%m/%y %H:%M") -> str:
"""Method for writing the log as a string in the format given"""
date_time_string = datetime.utcfromtimestamp(self.__log_date).strftime(date_format_string)
# Check if the log has a user and get the user name, otherwise it was an out of session action
if self.get_user():
username = self.get_user().username
else:
username = "N/A"
log_string = output_format_string.format(
date_time_string,
username,
self.__log_client_ip,
self.__log_action_dir,
self.__log_action[0: 40]
)
return log_string
def get_session(self) -> Session.Session or None:
"""Method for getting the session object to use in the session variable"""
if self.__session_ref and self.__session_ref != "":
if not self.__session:
self.__session = Session.Session(self.__session_ref, None)
self.__session.load_session()
return self.__session
else:
return None
def get_user(self) -> User.User or None:
"""Method for getting the user object for the user variable"""
if self.__session_ref and self.__session_ref != "":
if self.get_session():
# Preload the user into the object if not loaded beforehand
if not self.__user:
self.__user = self.__session.get_user()
return self.__user
else:
return None
else:
return None
def create_server_log(self, session_ref: str, direction: str, action: str or bytes, ip: str) -> bool:
"""Method for saving the current server log action to the database"""
result = False
if not self.__is_valid:
if len(direction) > 0 and len(action) > 0 and len(ip) > 0:
db_connection = DBConn()
# Force any byte strings into normal strings before putting it into the DB
try:
action = action.decode()
except (UnicodeDecodeError, AttributeError):
pass
if db_connection.do_insert("server_logs",
[{"field": "session_ref", "value": session_ref},
{"field": "log_action_dir", "value": direction},
{"field": "log_action", "value": action},
{"field": "log_client_ip", "value": ip},
{"field": "log_date", "value": get_unix_timestamp()}]):
self.__load_server_log()
result = True
return result