Add company dashboard improvements and upload/auth features

This commit is contained in:
2026-01-23 20:21:11 +01:00
parent 1394ef6f67
commit ea3d0164f2
14 changed files with 1004 additions and 112 deletions

View File

@@ -6,6 +6,7 @@ from flask import Blueprint, abort, current_app, flash, redirect, render_templat
from flask_login import current_user, login_required, login_user
from ..extensions import db
from ..uploads import abs_upload_path, ensure_company_upload_dir, is_valid_upload_relpath
from ..models import Company, Display, DisplaySession, Playlist, PlaylistItem, User
bp = Blueprint("admin", __name__, url_prefix="/admin")
@@ -20,11 +21,12 @@ def _try_delete_upload(file_path: str | None, upload_folder: str):
"""Best-effort delete of an uploaded media file."""
if not file_path:
return
if not file_path.startswith("uploads/"):
if not is_valid_upload_relpath(file_path):
return
filename = file_path.split("/", 1)[1]
abs_path = os.path.join(upload_folder, filename)
abs_path = abs_upload_path(upload_folder, file_path)
if not abs_path:
return
try:
if os.path.isfile(abs_path):
os.remove(abs_path)
@@ -55,6 +57,13 @@ def create_company():
c = Company(name=name)
db.session.add(c)
db.session.commit()
# Create the per-company upload directory eagerly (best-effort).
try:
ensure_company_upload_dir(current_app.config["UPLOAD_FOLDER"], c.id)
except Exception:
# Upload directory is also created lazily on first upload.
pass
flash("Company created", "success")
return redirect(url_for("admin.company_detail", company_id=c.id))
@@ -193,6 +202,43 @@ def update_user_email(user_id: int):
return redirect(url_for("admin.company_detail", company_id=u.company_id))
@bp.post("/users/<int:user_id>/delete")
@login_required
def delete_user(user_id: int):
"""Admin: delete a non-admin user."""
admin_required()
u = db.session.get(User, user_id)
if not u:
abort(404)
# Safety checks
if u.is_admin:
flash("Cannot delete an admin user", "danger")
return redirect(url_for("admin.dashboard"))
if u.id == current_user.id:
flash("You cannot delete yourself", "danger")
return redirect(url_for("admin.dashboard"))
company_id = u.company_id
company_name = u.company.name if u.company else None
email = u.email
db.session.delete(u)
db.session.commit()
flash(
f"User '{email}' deleted" + (f" from '{company_name}'." if company_name else "."),
"success",
)
if company_id:
return redirect(url_for("admin.company_detail", company_id=company_id))
return redirect(url_for("admin.dashboard"))
@bp.post("/displays/<int:display_id>/name")
@login_required
def update_display_name(display_id: int):