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:
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
@@ -112,8 +119,9 @@ def finalize():
|
||||
|
||||
|
||||
def login():
|
||||
# Gibt JWT zurück, oder None, wenn local deaktiviert ist (Variante B, bereits
|
||||
# konfiguriert) — dann ist nichts zu tun.
|
||||
# Gibt JWT zurück. local bleibt bewusst aktiviert (Break-Glass + der Job loggt sich
|
||||
# damit ein) — None nur, falls local doch mal deaktiviert wurde, dann kann der Job
|
||||
# nichts tun.
|
||||
d = gql(
|
||||
'mutation($u:String!,$p:String!){authentication{login(username:$u,password:$p,'
|
||||
'strategy:"local"){responseResult{succeeded message} jwt}}}',
|
||||
@@ -122,12 +130,13 @@ def login():
|
||||
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 = [
|
||||
{ # 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.
|
||||
{ # local bleibt aktiviert: der Konfig-Job loggt sich damit ein und es ist der
|
||||
# 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",
|
||||
"order": 0, "isEnabled": local_enabled, "selfRegistration": False,
|
||||
"order": 0, "isEnabled": True, "selfRegistration": False,
|
||||
"domainWhitelist": [], "autoEnrollGroups": [], "config": [],
|
||||
},
|
||||
{
|
||||
@@ -159,9 +168,19 @@ def ensure_oidc(jwt: str):
|
||||
"groupsClaim": "groups", "mapGroups": True,
|
||||
}
|
||||
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, local_enabled=False)
|
||||
log("OIDC-Strategy gesetzt, local-Login deaktiviert")
|
||||
_set_strategies(jwt, oidc_config)
|
||||
log("OIDC-Strategy gesetzt (local bleibt aktiv als Break-Glass)")
|
||||
|
||||
|
||||
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):
|
||||
@@ -198,7 +217,7 @@ def main():
|
||||
finalize()
|
||||
jwt = login()
|
||||
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
|
||||
log("eingeloggt")
|
||||
# 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.
|
||||
gql('mutation{groups{update(id:2,name:"Guests",redirectOnLogin:"/",permissions:[],pageRules:[]){responseResult{succeeded}}}}', jwt)
|
||||
ensure_oidc(jwt)
|
||||
set_hide_local(jwt)
|
||||
log("fertig — Wiki.js konfiguriert")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user