From ce90a2bd32d0dda1d95b37271a53696972980aaa Mon Sep 17 00:00:00 2001 From: mscadm Date: Mon, 13 Jul 2026 15:43:10 +0000 Subject: [PATCH] feat: Nutzerdetails (Telefon/Adresse) + Formular-Fix bei Passwortfehler in /admin/users --- app.py | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 96 insertions(+), 11 deletions(-) diff --git a/app.py b/app.py index e1af4ef..3df999f 100644 --- a/app.py +++ b/app.py @@ -790,7 +790,11 @@ def _role_pill(role): return '%s' % (html.escape(role), html.escape(role)) -def _users_body(tenant_id, notice=""): +def _users_body(tenant_id, notice="", form_vals=None): + # form_vals: bei einem fehlgeschlagenen POST die eingegebenen Werte (ausser + # Passwoerter), damit das Formular nicht komplett geleert wird (Nutzer- + # Vorgabe 2026-07-13, analog zum gleichen Fix bei /setup/new). + fv = form_vals or {} users = db.list_users(tenant_id) rows = [] for u in users: @@ -802,13 +806,17 @@ def _users_body(tenant_id, notice=""): '' % (r, "selected" if r == u["role"] else "", r) for r in ("admin", "agent") ) + name = " ".join(x for x in (u["vorname"], u["nachname"]) if x) or "--" rows.append(""" %s +%s %s %s %s %s +%s +Details
@@ -817,29 +825,46 @@ def _users_body(tenant_id, notice=""): """ % ( - html.escape(u["email"]), _role_pill(u["role"]), status_pill, - html.escape(u["auth_source"]), + html.escape(u["email"]), html.escape(name), _role_pill(u["role"]), status_pill, + html.escape(u["telefon"] or ""), html.escape(u["auth_source"]), u["last_login_at"].strftime("%Y-%m-%d %H:%M") if u["last_login_at"] else "nie", - u["id"], role_opts, u["id"], toggle_label, + u["id"], u["id"], role_opts, u["id"], toggle_label, )) table = """ - -%s
E-MailRolleStatusQuelleLetzte AnmeldungAktionen
""" % ("".join(rows) or "Keine Benutzer.") +E-MailNameRolleStatusTelefonQuelleLetzte AnmeldungAktionen +%s""" % ("".join(rows) or "Keine Benutzer.") add_form = """

Neuen Benutzer anlegen

Manuelle Verwaltung. Eine AD/LDAP-Anbindung ist als naechste Ausbaustufe vorgesehen (Spalte "Quelle" zeigt dann "ldap" statt "local").
-
-
+
+
Mindestens 10 Zeichen. Der Benutzer sollte das Passwort nach der ersten Anmeldung selbst aendern.
+

Details (optional)

+
+
+
+
+
+
+
+
+
-
""" +""" % ( + html.escape(fv.get("email", "")), + "selected" if fv.get("role") == "agent" or not fv.get("role") else "", + "selected" if fv.get("role") == "admin" else "", + html.escape(fv.get("vorname", "")), html.escape(fv.get("nachname", "")), + html.escape(fv.get("telefon", "")), html.escape(fv.get("abteilung", "")), + html.escape(fv.get("adresse", "")), + ) return '

Benutzerverwaltung

' + notice + table + add_form @@ -851,6 +876,7 @@ def admin_users_route(): return r tenant_id = session["tenant_id"] notice = "" + form_vals = {} if request.method == "POST": email = request.form.get("email", "").strip().lower() role = request.form.get("role", "agent").strip() @@ -858,6 +884,13 @@ def admin_users_route(): role = "agent" pw = request.form.get("password", "") pw2 = request.form.get("password2", "") + vorname = request.form.get("vorname", "").strip() + nachname = request.form.get("nachname", "").strip() + telefon = request.form.get("telefon", "").strip() + abteilung = request.form.get("abteilung", "").strip() + adresse = request.form.get("adresse", "").strip() + form_vals = {"email": email, "role": role, "vorname": vorname, "nachname": nachname, + "telefon": telefon, "abteilung": abteilung, "adresse": adresse} if not email or "@" not in email: notice = "

Bitte eine gueltige E-Mail-Adresse angeben.

" elif len(pw) < 10: @@ -867,11 +900,63 @@ def admin_users_route(): elif db.email_exists(email): notice = "

Diese E-Mail-Adresse ist bereits registriert.

" else: - uid = db.create_user(tenant_id, email, generate_password_hash(pw), role=role) + uid = db.create_user(tenant_id, email, generate_password_hash(pw), role=role, + vorname=vorname or None, nachname=nachname or None, + telefon=telefon or None, abteilung=abteilung or None, + adresse=adresse or None) db.log_audit(tenant_id, session["user_id"], "user_created", "user", str(uid), {"email": email, "role": role, "auth_source": "local"}, _client_ip()) notice = "

Benutzer angelegt.

" - return _shell("/admin/users", "Benutzerverwaltung", _users_body(tenant_id, notice)) + form_vals = {} + return _shell("/admin/users", "Benutzerverwaltung", _users_body(tenant_id, notice, form_vals)) + + +@app.route("/admin/users//edit", methods=["GET", "POST"]) +def admin_users_edit_route(user_id): + r = _require_admin() + if r: + return r + tenant_id = session["tenant_id"] + u = db.get_user(tenant_id, user_id) + if not u: + abort(404) + error = None + if request.method == "POST": + vorname = request.form.get("vorname", "").strip() + nachname = request.form.get("nachname", "").strip() + telefon = request.form.get("telefon", "").strip() + abteilung = request.form.get("abteilung", "").strip() + adresse = request.form.get("adresse", "").strip() + db.update_user_profile(tenant_id, user_id, vorname or None, nachname or None, + telefon or None, abteilung or None, adresse or None) + db.log_audit(tenant_id, session["user_id"], "user_profile_updated", "user", str(user_id), + None, _client_ip()) + u = dict(u) + u.update({"vorname": vorname, "nachname": nachname, "telefon": telefon, + "abteilung": abteilung, "adresse": adresse}) + error = "Gespeichert." + err_html = ("

%s

" % html.escape(error)) if error else "" + body = """

Benutzerdetails

+
%s
+
%s
+
+
+
+
+
+
+
+
+
+ +
+Zurueck zur Benutzerverwaltung""" % ( + html.escape(u["email"]), err_html, + html.escape(u["vorname"] or ""), html.escape(u["nachname"] or ""), + html.escape(u["telefon"] or ""), html.escape(u["abteilung"] or ""), + html.escape(u["adresse"] or ""), + ) + return _shell("/admin/users", "Benutzerdetails", body) @app.route("/admin/users//role", methods=["POST"])