[+] New history system

Now every server related event is logged.
Users will soon be able to access their server's history on the front as well.

Co-authored-by: Antoninop <antoninopiraino70@gmail.com>
This commit is contained in:
Charles Le Maux 2024-08-20 18:56:43 +02:00
parent 23c17ffbc9
commit 91e4258d3b
4 changed files with 41 additions and 2 deletions

2
app.py
View File

@ -9,7 +9,6 @@ import firebase_manager
import generic_executor import generic_executor
app = Flask(__name__) app = Flask(__name__)
CORS(app)
cors = CORS(app, origins="*") cors = CORS(app, origins="*")
apiBP = Blueprint('apiBP', 'BPapi') apiBP = Blueprint('apiBP', 'BPapi')
@ -82,6 +81,7 @@ route_handlers = {
'SetSubdomain': generic_executor.set_subdomain, 'SetSubdomain': generic_executor.set_subdomain,
'FetchServers': generic_executor.fetch_servers, 'FetchServers': generic_executor.fetch_servers,
'FetchLogs': generic_executor.fetch_logs, 'FetchLogs': generic_executor.fetch_logs,
'FetchHistory': generic_executor.fetch_history,
'AccountCreate': generic_executor.account_create, 'AccountCreate': generic_executor.account_create,
'ServerCreate': generic_executor.server_create, 'ServerCreate': generic_executor.server_create,
'ServerDelete': generic_executor.server_delete, 'ServerDelete': generic_executor.server_delete,

View File

@ -1,3 +1,5 @@
import datetime
import json
import logging import logging
import os import os
import shutil import shutil
@ -70,6 +72,20 @@ async def log_error(error_type: str, error_message: str):
logger.error(f'{error_type}: {error_message}') logger.error(f'{error_type}: {error_message}')
def log_action(user_id: str, name: str, action: str, details: str = None):
log_file = f"users/{user_id}/{name}/history.log"
event_log = {
"timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"type": action,
"details": details,
}
try:
with open(log_file, "a+") as log_file:
log_file.write(json.dumps(event_log) + "\n")
except Exception as e:
log_error(type(e).__name__, str(e)+" error trying to access history file on not existing server.")
def kebab_to_camel_case(s: str) -> str: def kebab_to_camel_case(s: str) -> str:
parts = s.split('-') parts = s.split('-')
return parts[0] + ''.join(part.title() for part in parts[1:]) return parts[0] + ''.join(part.title() for part in parts[1:])

View File

@ -77,6 +77,22 @@ def fetch_logs(user: UserRecord, name: str) -> tuple[HTTPStatus, Union[str, None
return HTTPStatus.OK, str(logs) return HTTPStatus.OK, str(logs)
except FileNotFoundError: except FileNotFoundError:
return HTTPStatus.NOT_FOUND, "Log file not found." return HTTPStatus.NOT_FOUND, "Log file not found."
except Exception as e:
file_manager.log_error(type(e).__name__, str(e))
def fetch_history(user: UserRecord, name: str) -> tuple[HTTPStatus, Union[str, None]]:
user_id: str = user.uid
history = f"users/{user_id}/{name}/history.log"
try:
with open(history, "r") as f:
logs = f.readlines()
return HTTPStatus.OK, str(logs)
except FileNotFoundError:
return HTTPStatus.NOT_FOUND, "History file not found."
except Exception as e:
file_manager.log_error(type(e).__name__, str(e))
return HTTPStatus.INTERNAL_SERVER_ERROR, "Unknown error."
def account_create(user: UserRecord) -> tuple[HTTPStatus, Union[str, None]]: def account_create(user: UserRecord) -> tuple[HTTPStatus, Union[str, None]]:
@ -125,6 +141,7 @@ def server_create(user: UserRecord, name: str, version: str, framework: str = "p
file_manager.update_server_property(prop_path, "server-port", port) file_manager.update_server_property(prop_path, "server-port", port)
file_manager.update_server_property(prop_path, "query.port", port) file_manager.update_server_property(prop_path, "query.port", port)
file_manager.update_server_property(prop_path, "enable-query", "true") file_manager.update_server_property(prop_path, "enable-query", "true")
file_manager.log_action(user_id, name, "ServerCreate")
return HTTPStatus.CREATED, f"Successfully created server '{name}'." return HTTPStatus.CREATED, f"Successfully created server '{name}'."
except Exception as e: except Exception as e:
file_manager.log_error(type(e).__name__, str(e)) file_manager.log_error(type(e).__name__, str(e))
@ -183,6 +200,7 @@ def server_run(user: UserRecord, name: str) -> tuple[HTTPStatus, Union[str, None
except Exception as e: except Exception as e:
return HTTPStatus.INTERNAL_SERVER_ERROR, (f"Error updating server {name}'s running state in database. " return HTTPStatus.INTERNAL_SERVER_ERROR, (f"Error updating server {name}'s running state in database. "
f"{type(e).__name__}{str(e)}.") f"{type(e).__name__}{str(e)}.")
file_manager.log_action(user_id, name, "ServerRun")
return HTTPStatus.ACCEPTED, f"Successfully started server '{name}'." return HTTPStatus.ACCEPTED, f"Successfully started server '{name}'."
except Exception as e: except Exception as e:
file_manager.log_error(type(e).__name__, str(e)) file_manager.log_error(type(e).__name__, str(e))
@ -209,6 +227,7 @@ def server_stop(user: UserRecord, name: str) -> tuple[HTTPStatus, Union[str, Non
if port: if port:
mc_manager.stop_server_forcefully(port) mc_manager.stop_server_forcefully(port)
firebase_manager.update_server_running_state(user_id, name, False) firebase_manager.update_server_running_state(user_id, name, False)
file_manager.log_action(user_id, name, "ServerStop")
return HTTPStatus.OK, f"Successfully stopped server '{name}'." return HTTPStatus.OK, f"Successfully stopped server '{name}'."
return HTTPStatus.INTERNAL_SERVER_ERROR, f"Error occurred when stopping server '{name}'." return HTTPStatus.INTERNAL_SERVER_ERROR, f"Error occurred when stopping server '{name}'."
@ -239,6 +258,7 @@ def update_properties(user: UserRecord, name: str, props: list[tuple[str, str]])
errors.append(message) errors.append(message)
if len(errors) > 0: if len(errors) > 0:
return HTTPStatus.IM_A_TEAPOT, str(errors) return HTTPStatus.IM_A_TEAPOT, str(errors)
file_manager.log_action(user.uid, name, "UpdateProperties")
return HTTPStatus.OK, f"Successfully updated server '{name}'." return HTTPStatus.OK, f"Successfully updated server '{name}'."
@ -248,6 +268,7 @@ def run_command(user: UserRecord, command: str, name: str) -> tuple[HTTPStatus,
if port is None: if port is None:
return HTTPStatus.NOT_FOUND, f"Server '{name}' not found in firestore." return HTTPStatus.NOT_FOUND, f"Server '{name}' not found in firestore."
mc_manager.execute_server_command(port, command) mc_manager.execute_server_command(port, command)
file_manager.log_action(user.uid, name, "Command", command)
return HTTPStatus.OK, f"Command '{command}' executed successfully." return HTTPStatus.OK, f"Command '{command}' executed successfully."
except Exception as e: except Exception as e:
file_manager.log_error(type(e).__name__, str(e)) file_manager.log_error(type(e).__name__, str(e))

View File

@ -1,3 +1,4 @@
import file_manager
import firebase_manager import firebase_manager
@ -10,4 +11,5 @@ def ban_user(user_id: str):
if __name__ == '__main__': if __name__ == '__main__':
ban_user("MpkbDMOO8PQddQgB5VgBQdTMWF53") #ban_user("MpkbDMOO8PQddQgB5VgBQdTMWF53")
file_manager.log_action("gqZN3eCHF3V2er3Py3rlgk8u2t83", "test", "DeleteServer")