maid/proxy/routes/admin.py
2025-08-08 08:42:40 +02:00

98 lines
3.9 KiB
Python

from flask import Blueprint, request, render_template, redirect, url_for
from auth import requires_auth
from db import (
delete_key,
add_or_update_key_metadata,
add_access_window,
delete_access_window,
get_all_keys_with_windows,
get_token_usage_per_key
)
admin_bp = Blueprint('admin', __name__)
@admin_bp.route("/admin", methods=["GET", "POST"])
@requires_auth
def admin_panel():
error = None
form_data = {}
# Handle form submission (add/delete windows, keys)
if request.method == "POST":
action = request.form.get("action")
form_data = request.form.to_dict()
try:
if action == "add_window":
# Add a new access window for a key
key = request.form.get("key", "").strip()
start = request.form.get("start_datetime")
end = request.form.get("end_datetime")
if not key or not start or not end:
raise ValueError("Alla fält måste fyllas i.")
if end < start:
raise ValueError("Sluttid måste vara efter starttid.")
add_access_window(key, start, end)
elif action == "delete_key":
# Delete a key and all its associated data
delete_key(request.form.get("key"))
elif action == "delete_window":
# Delete a specific time window
delete_access_window(request.form.get("window_id"))
elif action == "bulk_add_full":
# Bulk add multiple keys and assign them all time windows
keys_raw = request.form.get("bulk_keys", "")
if not keys_raw.strip():
raise ValueError("Inga nycklar angivna.")
slots = request.form.to_dict(flat=False)
slot_keys = [k for k in slots if k.startswith("slots[")]
slot_indices = sorted(set(int(k.split("[")[1].split("]")[0]) for k in slot_keys if "][" in k))
# Parse all time slots
time_windows = []
for i in slot_indices:
start = request.form.get(f"slots[{i}][start]")
end = request.form.get(f"slots[{i}][end]")
if not start or not end:
raise ValueError("Tidsfönster saknar start eller slut.")
if end < start:
raise ValueError(f"Tidsfönster {i+1} har en sluttid före starttid.")
time_windows.append((start, end))
# Parse and validate key-label entries
keys_data = []
for line in keys_raw.strip().splitlines():
if ',' not in line:
raise ValueError(f"Ogiltig rad: '{line}'. Format ska vara nyckel,etikett.")
parts = line.split(",")
if len(parts) < 2:
raise ValueError(f"Ofullständig rad: '{line}'")
key = parts[0].strip()
label = parts[1].strip()
keys_data.append((key, label))
# Save keys and assign all time windows to each
for key, label in keys_data:
add_or_update_key_metadata(key, label)
for start, end in time_windows:
add_access_window(key, start, end)
return redirect(url_for("admin.admin_panel"))
except Exception as e:
error = str(e)
# Prepare data to render admin dashboard
keys = get_all_keys_with_windows()
usage_by_key = get_token_usage_per_key()
for key in keys:
usage = usage_by_key.get(key["key"], {})
key["tokens_input"] = usage.get("input", 0)
key["tokens_output"] = usage.get("output", 0)
key["tokens_total"] = usage.get("total", 0)
return render_template("admin.html", keys=keys, error=error, form_data=form_data)