From f034eabdd6dd79e5dded3edf944ca23d740f82df Mon Sep 17 00:00:00 2001 From: Thore Cimbal Date: Wed, 12 Aug 2026 12:00:00 +0000 Subject: [PATCH] feat(wiki-config): disable local login after bootstrap (Variante B) Nobody should log in manually. The job disables the local strategy as its final step (with a still-valid JWT), so the login page offers only Authentik OIDC. Re-runs without a DB reset find local disabled -> login returns None -> the job exits cleanly (already configured). Break-glass = DB reset (finalize re-enables local). Verified live: local login is BLOCKED after the run. --- apps/production/wikijs-config.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/apps/production/wikijs-config.py b/apps/production/wikijs-config.py index 602bc80..5dff204 100644 --- a/apps/production/wikijs-config.py +++ b/apps/production/wikijs-config.py @@ -111,22 +111,23 @@ def finalize(): sys.exit("Normalmodus nicht erreicht") -def login() -> str: +def login(): + # Gibt JWT zurück, oder None, wenn local deaktiviert ist (Variante B, bereits + # konfiguriert) — dann ist nichts zu tun. d = gql( 'mutation($u:String!,$p:String!){authentication{login(username:$u,password:$p,' 'strategy:"local"){responseResult{succeeded message} jwt}}}', variables={"u": ADMIN_EMAIL, "p": ADMIN_PW}, )["authentication"]["login"] - if not d["responseResult"]["succeeded"]: - sys.exit(f"Login fehlgeschlagen: {d['responseResult']['message']}") - return d["jwt"] + return d["jwt"] if d["responseResult"]["succeeded"] else None -def _set_strategies(jwt: str, oidc_config: list): +def _set_strategies(jwt: str, oidc_config: list, local_enabled: bool = True): strategies = [ - { # local muss in der Liste bleiben (Admin nutzt es), sonst Fehler. + { # local bleibt in der Liste (nicht löschbar, Admin hängt dran), wird aber + # am Ende deaktiviert (Variante B): kein manuelles Login mehr im Alltag. "key": "local", "strategyKey": "local", "displayName": "Local", - "order": 0, "isEnabled": True, "selfRegistration": False, + "order": 0, "isEnabled": local_enabled, "selfRegistration": False, "domainWhitelist": [], "autoEnrollGroups": [], "config": [], }, { @@ -158,8 +159,9 @@ def ensure_oidc(jwt: str): "groupsClaim": "groups", "mapGroups": True, } oidc_config = [{"key": k, "value": json.dumps({"v": v})} for k, v in cfg.items()] - _set_strategies(jwt, oidc_config) - log("OIDC-Strategy gesetzt") + # letzter updateStrategies-Aufruf: OIDC setzen UND local deaktivieren. + _set_strategies(jwt, oidc_config, local_enabled=False) + log("OIDC-Strategy gesetzt, local-Login deaktiviert") def group_id(jwt: str, name: str): @@ -195,13 +197,17 @@ def main(): if in_setup_mode(): finalize() jwt = login() + if jwt is None: + log("lokaler Login nicht möglich (local deaktiviert) — bereits konfiguriert, Ende.") + return log("eingeloggt") - ensure_oidc(jwt) + # Erst Gruppen (Schreibvorgänge), DANN OIDC — ensure_oidc deaktiviert zuletzt local. # authentik Admins: alles lesen+schreiben. wiki-anwender: nur /anwender lesen. ensure_group(jwt, "authentik Admins", ADMIN_PERMS, [rule("adm", False, ["read:pages", "write:pages", "manage:pages"], "")]) ensure_group(jwt, "wiki-anwender", READER_PERMS, [rule("anw", False, READER_PERMS, "anwender")]) # Guests (id 2) alle Rechte entziehen — Login-Pflicht, keine öffentliche Sicht. gql('mutation{groups{update(id:2,name:"Guests",redirectOnLogin:"/",permissions:[],pageRules:[]){responseResult{succeeded}}}}', jwt) + ensure_oidc(jwt) log("fertig — Wiki.js konfiguriert")