diff --git a/README.md b/README.md index 68de29f..148db91 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,17 @@ Aktion (Buttons, Toggle-Switches, Formulare) ist an das jeweilige Recht gekoppelt — im Frontend ausgeblendet **und** im Backend serverseitig durchgesetzt, unabhängig vom Frontend. +**Bewusst ohne granulare Rechte, exklusiv Admins vorbehalten:** Benutzer, +Gruppen, Systemeinstellungen (Prüfintervall), Im-/Export, Änderungslog, +Live-Log und der manuelle „Jetzt prüfen“-Trigger. Für diese Bereiche gibt es +keine sinnvolle Teilmenge unterhalb von „Admin“ — Gruppenverwaltung steuert +direkt das Rechtesystem selbst (Delegation wäre eine Privilegien-Eskalation), +Systemeinstellungen/Import-Export/manuelle Prüfung wirken sich global aus, +und das Änderungslog protokolliert alle Benutzer systemweit. Live-Log und +`/get_log` waren zwischenzeitlich nur über `@login_required` statt echter +Admin-Prüfung abgesichert (die Sidebar blendete den Punkt zwar korrekt aus, +die Route selbst nicht) — inzwischen serverseitig nachgezogen. + Datenmodell: `groups` (inkl. `is_default`-Flag), `group_permissions` (Gruppe → Recht), `user_groups` (Benutzer → Gruppe). Bestehende Datenbanken werden beim App-Start automatisch migriert (`_ensure_schema()` in `app.py`, diff --git a/srv/poe_manager/app.py b/srv/poe_manager/app.py index 2a4079d..fe00e4a 100644 --- a/srv/poe_manager/app.py +++ b/srv/poe_manager/app.py @@ -1626,6 +1626,8 @@ def _ssh_terminal_inner(ws): @app.route("/get_log") @login_required def get_log(): + if not current_user.is_admin: + return "Keine Berechtigung.", 403 latest_log = _latest_log_file() if not latest_log: return "Keine Logfiles gefunden." @@ -1645,6 +1647,9 @@ def get_log(): @app.route("/logs") @login_required def logs(): + if not current_user.is_admin: + flash("Nur Admins dürfen das Live-Log einsehen.", "danger") + return redirect(url_for("index")) interval = int(get_setting("interval", 5)) latest_log = _latest_log_file()