fix(wiki-config): hide local login via hideLocal, keep strategy enabled
Disabling local (previous approach) left the login page empty: Wiki.js needs a form strategy to render the provider list, so with only OIDC the card was blank and login hung. Keep local ENABLED and instead set the built-in authHideLocal site config, which removes local from the provider list on the login page — only "Login with Authentik" shows. local stays usable because the config job logs in through it, and it is the break-glass path, reachable via /login?all (Wiki.js honors ?all to bypass hideLocal). Verified live end-to-end: job runs idempotently, both strategies enabled, authHideLocal=true.
This commit is contained in:
@@ -7,8 +7,15 @@ stdlib. Alle Verträge wurden am 2026-08-12 live gegen die laufende Instanz gepr
|
|||||||
|
|
||||||
Ablauf:
|
Ablauf:
|
||||||
warten -> (falls Setup) /finalize mit SOPS-Admin -> warten auf Normalmodus
|
warten -> (falls Setup) /finalize mit SOPS-Admin -> warten auf Normalmodus
|
||||||
-> login -> OIDC-Strategy setzen -> Gruppen + Seitenregeln (Abschottung).
|
-> login -> Gruppen + Seitenregeln (Abschottung) -> OIDC-Strategy setzen
|
||||||
|
-> local auf der Login-Seite ausblenden (hideLocal).
|
||||||
Idempotent: jeder Schritt prüft erst den Ist-Zustand.
|
Idempotent: jeder Schritt prüft erst den Ist-Zustand.
|
||||||
|
|
||||||
|
Variante B ("kein manuelles Login"): local wird NICHT deaktiviert, sondern nur per
|
||||||
|
Wiki.js-eigenem hideLocal aus der Login-Seite ausgeblendet. Grund: (a) local ist
|
||||||
|
nicht löschbar und Wiki.js braucht eine Formular-Strategie, sonst rendert die
|
||||||
|
Login-Seite leer; (b) der Job selbst loggt sich über local ein; (c) Break-Glass
|
||||||
|
bleibt über /login?all erreichbar.
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
@@ -112,8 +119,9 @@ def finalize():
|
|||||||
|
|
||||||
|
|
||||||
def login():
|
def login():
|
||||||
# Gibt JWT zurück, oder None, wenn local deaktiviert ist (Variante B, bereits
|
# Gibt JWT zurück. local bleibt bewusst aktiviert (Break-Glass + der Job loggt sich
|
||||||
# konfiguriert) — dann ist nichts zu tun.
|
# damit ein) — None nur, falls local doch mal deaktiviert wurde, dann kann der Job
|
||||||
|
# nichts tun.
|
||||||
d = gql(
|
d = gql(
|
||||||
'mutation($u:String!,$p:String!){authentication{login(username:$u,password:$p,'
|
'mutation($u:String!,$p:String!){authentication{login(username:$u,password:$p,'
|
||||||
'strategy:"local"){responseResult{succeeded message} jwt}}}',
|
'strategy:"local"){responseResult{succeeded message} jwt}}}',
|
||||||
@@ -122,12 +130,13 @@ def login():
|
|||||||
return d["jwt"] if d["responseResult"]["succeeded"] else None
|
return d["jwt"] if d["responseResult"]["succeeded"] else None
|
||||||
|
|
||||||
|
|
||||||
def _set_strategies(jwt: str, oidc_config: list, local_enabled: bool = True):
|
def _set_strategies(jwt: str, oidc_config: list):
|
||||||
strategies = [
|
strategies = [
|
||||||
{ # local bleibt in der Liste (nicht löschbar, Admin hängt dran), wird aber
|
{ # local bleibt aktiviert: der Konfig-Job loggt sich damit ein und es ist der
|
||||||
# am Ende deaktiviert (Variante B): kein manuelles Login mehr im Alltag.
|
# Break-Glass-Zugang (/login?all). Auf der Login-Seite wird es per hideLocal
|
||||||
|
# ausgeblendet (siehe set_hide_local) — kein manuelles Login im Alltag.
|
||||||
"key": "local", "strategyKey": "local", "displayName": "Local",
|
"key": "local", "strategyKey": "local", "displayName": "Local",
|
||||||
"order": 0, "isEnabled": local_enabled, "selfRegistration": False,
|
"order": 0, "isEnabled": True, "selfRegistration": False,
|
||||||
"domainWhitelist": [], "autoEnrollGroups": [], "config": [],
|
"domainWhitelist": [], "autoEnrollGroups": [], "config": [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -159,9 +168,19 @@ def ensure_oidc(jwt: str):
|
|||||||
"groupsClaim": "groups", "mapGroups": True,
|
"groupsClaim": "groups", "mapGroups": True,
|
||||||
}
|
}
|
||||||
oidc_config = [{"key": k, "value": json.dumps({"v": v})} for k, v in cfg.items()]
|
oidc_config = [{"key": k, "value": json.dumps({"v": v})} for k, v in cfg.items()]
|
||||||
# letzter updateStrategies-Aufruf: OIDC setzen UND local deaktivieren.
|
_set_strategies(jwt, oidc_config)
|
||||||
_set_strategies(jwt, oidc_config, local_enabled=False)
|
log("OIDC-Strategy gesetzt (local bleibt aktiv als Break-Glass)")
|
||||||
log("OIDC-Strategy gesetzt, local-Login deaktiviert")
|
|
||||||
|
|
||||||
|
def set_hide_local(jwt: str):
|
||||||
|
# Variante B ohne local zu deaktivieren: Wiki.js' eingebautes hideLocal entfernt den
|
||||||
|
# local-Provider aus der Login-Seite (nur noch "Login with Authentik" sichtbar).
|
||||||
|
# Break-Glass bleibt über /login?all. authHideLocal ist ein Site-Config-Feld.
|
||||||
|
r = gql('mutation{site{updateConfig(authHideLocal:true){responseResult{succeeded message}}}}',
|
||||||
|
jwt)["site"]["updateConfig"]["responseResult"]
|
||||||
|
if not r["succeeded"]:
|
||||||
|
sys.exit(f"authHideLocal setzen fehlgeschlagen: {r['message']}")
|
||||||
|
log("Login-Seite: local ausgeblendet (hideLocal=true; Break-Glass via /login?all)")
|
||||||
|
|
||||||
|
|
||||||
def group_id(jwt: str, name: str):
|
def group_id(jwt: str, name: str):
|
||||||
@@ -198,7 +217,7 @@ def main():
|
|||||||
finalize()
|
finalize()
|
||||||
jwt = login()
|
jwt = login()
|
||||||
if jwt is None:
|
if jwt is None:
|
||||||
log("lokaler Login nicht möglich (local deaktiviert) — bereits konfiguriert, Ende.")
|
log("lokaler Login nicht möglich (local wurde deaktiviert) — kann nicht konfigurieren, Ende.")
|
||||||
return
|
return
|
||||||
log("eingeloggt")
|
log("eingeloggt")
|
||||||
# Erst Gruppen (Schreibvorgänge), DANN OIDC — ensure_oidc deaktiviert zuletzt local.
|
# Erst Gruppen (Schreibvorgänge), DANN OIDC — ensure_oidc deaktiviert zuletzt local.
|
||||||
@@ -208,6 +227,7 @@ def main():
|
|||||||
# Guests (id 2) alle Rechte entziehen — Login-Pflicht, keine öffentliche Sicht.
|
# 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)
|
gql('mutation{groups{update(id:2,name:"Guests",redirectOnLogin:"/",permissions:[],pageRules:[]){responseResult{succeeded}}}}', jwt)
|
||||||
ensure_oidc(jwt)
|
ensure_oidc(jwt)
|
||||||
|
set_hide_local(jwt)
|
||||||
log("fertig — Wiki.js konfiguriert")
|
log("fertig — Wiki.js konfiguriert")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user