mirror of
https://github.com/partitioncloud/partitioncloud-server.git
synced 2025-04-22 05:33:55 +02:00
Add logs server-side
This commit is contained in:
parent
5a7c3ed09d
commit
191ffebd7e
@ -12,7 +12,7 @@ from flask import Flask, g, redirect, render_template, request, send_file, flash
|
|||||||
from werkzeug.security import generate_password_hash
|
from werkzeug.security import generate_password_hash
|
||||||
|
|
||||||
from .modules.utils import User, Album, get_all_albums
|
from .modules.utils import User, Album, get_all_albums
|
||||||
from .modules import albums, auth, partition, admin, groupe, thumbnails
|
from .modules import albums, auth, partition, admin, groupe, thumbnails, logging
|
||||||
from .modules.auth import admin_required, login_required
|
from .modules.auth import admin_required, login_required
|
||||||
from .modules.db import get_db
|
from .modules.db import get_db
|
||||||
|
|
||||||
@ -33,6 +33,11 @@ def load_config():
|
|||||||
".",
|
".",
|
||||||
os.path.join(app.instance_path, "config.py")
|
os.path.join(app.instance_path, "config.py")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if spec is None:
|
||||||
|
print("[ERROR] Failed to load $INSTANCE_PATH/config.py")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
user_config = importlib.util.module_from_spec(spec)
|
user_config = importlib.util.module_from_spec(spec)
|
||||||
spec.loader.exec_module(user_config)
|
spec.loader.exec_module(user_config)
|
||||||
|
|
||||||
@ -50,6 +55,8 @@ def load_config():
|
|||||||
DATABASE=os.path.join(app.instance_path, f"{__name__}.sqlite"),
|
DATABASE=os.path.join(app.instance_path, f"{__name__}.sqlite"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logging.log_file = os.path.join(app.instance_path, "logs.txt")
|
||||||
|
|
||||||
|
|
||||||
def get_version():
|
def get_version():
|
||||||
try:
|
try:
|
||||||
@ -71,6 +78,8 @@ app.register_blueprint(thumbnails.bp)
|
|||||||
|
|
||||||
__version__ = get_version()
|
__version__ = get_version()
|
||||||
|
|
||||||
|
logging.log([], logging.LogEntry.SERVER_RESTART)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def home():
|
def home():
|
||||||
@ -96,6 +105,12 @@ def add_user():
|
|||||||
if error is None:
|
if error is None:
|
||||||
# Success, go to the login page.
|
# Success, go to the login page.
|
||||||
user = User(name=username)
|
user = User(name=username)
|
||||||
|
|
||||||
|
logging.log(
|
||||||
|
[user.username, user.id, True, current_user.username],
|
||||||
|
logging.LogEntry.NEW_USER
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if album_uuid != "":
|
if album_uuid != "":
|
||||||
user.join_album(album_uuid)
|
user.join_album(album_uuid)
|
||||||
|
@ -13,7 +13,7 @@ from flask import (Blueprint, abort, flash, redirect, render_template,
|
|||||||
from .auth import login_required
|
from .auth import login_required
|
||||||
from .db import get_db
|
from .db import get_db
|
||||||
from .utils import User, Album
|
from .utils import User, Album
|
||||||
from . import search, utils
|
from . import search, utils, logging
|
||||||
|
|
||||||
|
|
||||||
bp = Blueprint("albums", __name__, url_prefix="/albums")
|
bp = Blueprint("albums", __name__, url_prefix="/albums")
|
||||||
@ -116,6 +116,8 @@ def create_album_req():
|
|||||||
db = get_db()
|
db = get_db()
|
||||||
error = None
|
error = None
|
||||||
|
|
||||||
|
user = User(user_id=session["user_id"])
|
||||||
|
|
||||||
if not name or name.strip() == "":
|
if not name or name.strip() == "":
|
||||||
error = "Un nom est requis. L'album n'a pas été créé"
|
error = "Un nom est requis. L'album n'a pas été créé"
|
||||||
|
|
||||||
@ -131,6 +133,8 @@ def create_album_req():
|
|||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
logging.log([album.name, album.uuid, user.username], logging.LogEntry.NEW_ALBUM)
|
||||||
|
|
||||||
if "response" in request.args and request.args["response"] == "json":
|
if "response" in request.args and request.args["response"] == "json":
|
||||||
return {
|
return {
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
@ -217,7 +221,7 @@ def delete_album(uuid):
|
|||||||
@login_required
|
@login_required
|
||||||
def add_partition(album_uuid):
|
def add_partition(album_uuid):
|
||||||
"""
|
"""
|
||||||
Ajouter une partition à un album (par upload)
|
Ajouter une partition à un album (nouveau fichier)
|
||||||
"""
|
"""
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
def get_opt_string(dictionary: dict[T, str], key: T):
|
def get_opt_string(dictionary: dict[T, str], key: T):
|
||||||
@ -265,6 +269,7 @@ def add_partition(album_uuid):
|
|||||||
author = get_opt_string(request.form, "author")
|
author = get_opt_string(request.form, "author")
|
||||||
body = get_opt_string(request.form, "body")
|
body = get_opt_string(request.form, "body")
|
||||||
|
|
||||||
|
partition_uuid: str
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
partition_uuid = str(uuid4())
|
partition_uuid = str(uuid4())
|
||||||
@ -307,6 +312,11 @@ def add_partition(album_uuid):
|
|||||||
except db.IntegrityError:
|
except db.IntegrityError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
logging.log(
|
||||||
|
[request.form["name"], partition_uuid, user.username],
|
||||||
|
logging.LogEntry.NEW_PARTITION
|
||||||
|
)
|
||||||
|
|
||||||
if "response" in request.args and request.args["response"] == "json":
|
if "response" in request.args and request.args["response"] == "json":
|
||||||
return {
|
return {
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
@ -320,7 +330,7 @@ def add_partition(album_uuid):
|
|||||||
@login_required
|
@login_required
|
||||||
def add_partition_from_search():
|
def add_partition_from_search():
|
||||||
"""
|
"""
|
||||||
Ajout d'une partition (depuis la recherche)
|
Ajout d'une partition (depuis la recherche locale)
|
||||||
"""
|
"""
|
||||||
user = User(user_id=session.get("user_id"))
|
user = User(user_id=session.get("user_id"))
|
||||||
error = None
|
error = None
|
||||||
|
@ -12,6 +12,7 @@ from werkzeug.security import check_password_hash, generate_password_hash
|
|||||||
|
|
||||||
from .db import get_db
|
from .db import get_db
|
||||||
from .utils import User
|
from .utils import User
|
||||||
|
from . import logging
|
||||||
|
|
||||||
bp = Blueprint("auth", __name__, url_prefix="/auth")
|
bp = Blueprint("auth", __name__, url_prefix="/auth")
|
||||||
|
|
||||||
@ -120,8 +121,15 @@ def register():
|
|||||||
if error is not None:
|
if error is not None:
|
||||||
flash(error)
|
flash(error)
|
||||||
else:
|
else:
|
||||||
|
user = User(name=username)
|
||||||
|
|
||||||
flash("Utilisateur créé avec succès. Vous pouvez vous connecter.")
|
flash("Utilisateur créé avec succès. Vous pouvez vous connecter.")
|
||||||
|
|
||||||
|
logging.log(
|
||||||
|
[user.username, user.id, False],
|
||||||
|
logging.LogEntry.NEW_USER
|
||||||
|
)
|
||||||
|
|
||||||
return render_template("auth/register.html")
|
return render_template("auth/register.html")
|
||||||
|
|
||||||
|
|
||||||
@ -139,12 +147,16 @@ def login():
|
|||||||
).fetchone()
|
).fetchone()
|
||||||
|
|
||||||
if (user is None) or not check_password_hash(user["password"], password):
|
if (user is None) or not check_password_hash(user["password"], password):
|
||||||
|
logging.log([username], logging.LogEntry.FAILED_LOGIN)
|
||||||
error = "Nom d'utilisateur ou mot de passe incorrect."
|
error = "Nom d'utilisateur ou mot de passe incorrect."
|
||||||
|
|
||||||
if error is None:
|
if error is None:
|
||||||
# store the user id in a new session and return to the index
|
# store the user id in a new session and return to the index
|
||||||
session.clear()
|
session.clear()
|
||||||
session["user_id"] = user["id"]
|
session["user_id"] = user["id"]
|
||||||
|
|
||||||
|
logging.log([username], logging.LogEntry.LOGIN)
|
||||||
|
|
||||||
return redirect(url_for("albums.index"))
|
return redirect(url_for("albums.index"))
|
||||||
|
|
||||||
flash(error)
|
flash(error)
|
||||||
|
@ -9,6 +9,7 @@ from .auth import login_required
|
|||||||
from .db import get_db
|
from .db import get_db
|
||||||
from .utils import User, Album, Groupe
|
from .utils import User, Album, Groupe
|
||||||
from . import utils
|
from . import utils
|
||||||
|
from . import logging
|
||||||
|
|
||||||
bp = Blueprint("groupe", __name__, url_prefix="/groupe")
|
bp = Blueprint("groupe", __name__, url_prefix="/groupe")
|
||||||
|
|
||||||
@ -63,6 +64,8 @@ def create_groupe():
|
|||||||
db = get_db()
|
db = get_db()
|
||||||
error = None
|
error = None
|
||||||
|
|
||||||
|
user = User(user_id=session["user_id"])
|
||||||
|
|
||||||
if not name or name.strip() == "":
|
if not name or name.strip() == "":
|
||||||
error = "Un nom est requis. Le groupe n'a pas été créé"
|
error = "Un nom est requis. Le groupe n'a pas été créé"
|
||||||
|
|
||||||
@ -93,6 +96,8 @@ def create_groupe():
|
|||||||
except db.IntegrityError:
|
except db.IntegrityError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
logging.log([name, uuid, user.username], logging.LogEntry.NEW_GROUPE)
|
||||||
|
|
||||||
if "response" in request.args and request.args["response"] == "json":
|
if "response" in request.args and request.args["response"] == "json":
|
||||||
return {
|
return {
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
@ -194,6 +199,8 @@ def create_album_req(groupe_uuid):
|
|||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
logging.log([album.name, album.uuid, user.username], logging.LogEntry.NEW_ALBUM)
|
||||||
|
|
||||||
if "response" in request.args and request.args["response"] == "json":
|
if "response" in request.args and request.args["response"] == "json":
|
||||||
return {
|
return {
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
|
61
partitioncloud/modules/logging.py
Normal file
61
partitioncloud/modules/logging.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
from typing import Union
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
global log_file
|
||||||
|
global enabled
|
||||||
|
|
||||||
|
|
||||||
|
class LogEntry(Enum):
|
||||||
|
LOGIN = 1
|
||||||
|
NEW_GROUPE = 2
|
||||||
|
NEW_ALBUM = 3
|
||||||
|
NEW_PARTITION = 4
|
||||||
|
NEW_USER = 5
|
||||||
|
SERVER_RESTART = 6
|
||||||
|
FAILED_LOGIN = 7
|
||||||
|
|
||||||
|
|
||||||
|
def add_entry(entry: str) -> None:
|
||||||
|
date = datetime.now().strftime("%y-%b-%Y %H:%M:%S")
|
||||||
|
|
||||||
|
with open(log_file, 'a', encoding="utf8") as f:
|
||||||
|
f.write(f"[{date}] {entry}\n")
|
||||||
|
|
||||||
|
|
||||||
|
def log(content: list[Union[str, bool, int]], log_type: LogEntry) -> None:
|
||||||
|
description: str = ""
|
||||||
|
|
||||||
|
if log_type not in enabled:
|
||||||
|
return
|
||||||
|
|
||||||
|
match log_type:
|
||||||
|
case LogEntry.LOGIN: # content = (user.name)
|
||||||
|
description = f"Successful login for {content[0]}"
|
||||||
|
|
||||||
|
case LogEntry.NEW_GROUPE: # content = (groupe.name, groupe.id, user.name)
|
||||||
|
description = f"{content[2]} added groupe '{content[0]}' ({content[1]})"
|
||||||
|
|
||||||
|
case LogEntry.NEW_ALBUM: # content = (album.name, album.id, user.name)
|
||||||
|
description = f"{content[2]} added album '{content[0]}' ({content[1]})"
|
||||||
|
|
||||||
|
case LogEntry.NEW_PARTITION: # content = (partition.name, partition.uuid, user.name)
|
||||||
|
description = f"{content[2]} added partition '{content[0]}' ({content[1]})"
|
||||||
|
|
||||||
|
case LogEntry.NEW_USER: # content = (user.name, user.id, from_register_page, admin.name if relevant)
|
||||||
|
if not content[2]:
|
||||||
|
description = f"New user {content[0]}[{content[1]}]"
|
||||||
|
else:
|
||||||
|
description = f"New user {content[0]}[{content[1]}] added by {content[3]}"
|
||||||
|
|
||||||
|
case LogEntry.SERVER_RESTART: # content = ()
|
||||||
|
description = "Server just restarted"
|
||||||
|
|
||||||
|
case LogEntry.FAILED_LOGIN: # content = (user.name)
|
||||||
|
description = f"Failed login for {content[0]}"
|
||||||
|
|
||||||
|
add_entry(description)
|
||||||
|
|
||||||
|
|
||||||
|
log_file = "logs.txt"
|
||||||
|
enabled = [i for i in LogEntry]
|
Loading…
x
Reference in New Issue
Block a user