From af308535feb7320dace64e55956e30b5da82e00e Mon Sep 17 00:00:00 2001 From: Erik Thiele Date: Fri, 4 Sep 2026 11:59:58 +0200 Subject: [PATCH] fix: Standort ueber Seiten ohne Standortbezug hinweg merken Wer von Stuttgart aus das Admin-Dashboard oeffnete, sah im Header ploetzlich Karlsruhe - und landete beim Zurueckgehen ueber die Standortauswahl dort. Grund: Dashboard, Hilfe, User-Verwaltung und die MFA-Seiten setzten current_site fest auf get_site_list(cfg)[0], also den global ersten Standort. Der Context-Processor tat dasselbe, fuer angemeldete User sogar unabhaengig davon, ob sie auf diesen Standort ueberhaupt zugreifen duerfen. - remember_site() legt den zuletzt besuchten Standort in der Session ab; aufgerufen aus admin(), admin_priority() und add_customer(). - current_site_for() liefert diesen Standort, sonst den ersten *zugaenglichen*. Verwendet vom Context-Processor und den genannten Seiten. Co-Authored-By: Claude Opus 5 --- app.py | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/app.py b/app.py index 8d2cd5f..b8336b7 100755 --- a/app.py +++ b/app.py @@ -58,6 +58,27 @@ app = Flask(__name__) app.secret_key = "CHANGE_THIS_SECRET!!!" app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1) +def remember_site(site): + """Merkt den zuletzt besuchten Standort in der Session.""" + if site: + session["last_site"] = site + + +def current_site_for(cfg, user=None): + """Standort für Seiten ohne eigenen Standortbezug (Dashboard, Hilfe, + User-Verwaltung, MFA). + + Nimmt den zuletzt besuchten Standort, sonst den ersten *zugänglichen*. + Ohne das springt die Standortanzeige im Header auf den global ersten + Standort - und der "Übersicht"-Link führt anschliessend dorthin statt + zurück zu dem Standort, von dem man kam.""" + sites = get_accessible_sites(cfg, user) if (user is not None and user.is_authenticated) else get_site_list(cfg) + letzter = session.get("last_site") + if letzter in sites: + return letzter + return sites[0] if sites else "" + + @app.context_processor def inject_globals(): """Stellt globale Template-Variablen für Header/Footer bereit.""" @@ -67,7 +88,7 @@ def inject_globals(): from flask_login import current_user if current_user.is_authenticated: site_list = get_accessible_sites(cfg, current_user) - current_site_val = get_site_list(cfg)[0] if get_site_list(cfg) else "" + current_site_val = current_site_for(cfg, current_user) else: site_list = get_site_list(cfg) current_site_val = site_list[0] if site_list else "" @@ -863,11 +884,11 @@ def mfa_setup(): save_users(users_data) add_history_entry("mfa_enabled", f"User '{email}' hat MFA aktiviert", email) return render_template("mfa_recovery.html", codes=recovery, email=email, - site_list=site_list, current_site=site_list[0] if site_list else "", + site_list=site_list, current_site=current_site_for(cfg, current_user), brand_subtitle="MFA", site_dropdown_url_prefix="/admin/") return render_template("mfa_setup.html", error="Code ungültig. Bitte versuche es erneut.", email=email, secret=secret, qr_data=None, - site_list=site_list, current_site=site_list[0] if site_list else "", + site_list=site_list, current_site=current_site_for(cfg, current_user), brand_subtitle="MFA", site_dropdown_url_prefix="/admin/") uri = totp.provisioning_uri(name=email, issuer_name="CANCOM Signage") @@ -879,7 +900,7 @@ def mfa_setup(): return render_template("mfa_setup.html", error=None if not error_param else "Passwort ist falsch", email=email, secret=secret, qr_data=qr_b64, recovered=recovered, disabled=disabled, - site_list=site_list, current_site=site_list[0] if site_list else "", + site_list=site_list, current_site=current_site_for(cfg, current_user), brand_subtitle="MFA", site_dropdown_url_prefix="/admin/") @@ -947,6 +968,8 @@ def add_customer(): if site and not current_user.can_access_site(site): abort(403) + remember_site(site) + if request.method == "POST": customer_names = [ request.form.get("customer_name_1", "").strip(), @@ -1404,6 +1427,7 @@ def admin(site): Admin-Dashboard für einen Standort. Zeigt alle Screens als Cards mit Tabler-Tabs (Playlist, Einstellungen, Medien). """ + remember_site(site) cfg = load_config() site_list = get_accessible_sites(cfg, current_user) @@ -1545,6 +1569,7 @@ def admin(site): @site_access_required def admin_priority(site): """Zeigt die Priority-Playlist-Seite mit Tabs (Playlist + Medien).""" + remember_site(site) cfg = load_config() site_list = get_accessible_sites(cfg, current_user) priority_files = load_priority_files(site) @@ -2087,7 +2112,7 @@ def admin_dashboard(): superuser_trend=superuser_trend, history=history, site_list=get_accessible_sites(cfg, current_user), - current_site=get_site_list(cfg)[0] if get_site_list(cfg) else "", + current_site=current_site_for(cfg, current_user), version=APP_VERSION, year=datetime.now().year, hostname=os.uname().nodename, @@ -2103,7 +2128,7 @@ def admin_help(): return render_template( "help.html", site_list=get_accessible_sites(cfg, current_user), - current_site=get_site_list(cfg)[0] if get_site_list(cfg) else "", + current_site=current_site_for(cfg, current_user), version=APP_VERSION, year=datetime.now().year, hostname=os.uname().nodename, @@ -2136,7 +2161,7 @@ def admin_users(): "user_list.html", users=sorted(users_list, key=lambda u: (u["last_name"].lower(), u["first_name"].lower())), site_list=get_accessible_sites(cfg, current_user), - current_site=get_site_list(cfg)[0] if get_site_list(cfg) else "", + current_site=current_site_for(cfg, current_user), version=APP_VERSION, year=datetime.now().year, hostname=os.uname().nodename,