Setup-Skript: Launch-URLs auf die SSO-Startpunkte der Tools setzen
Ein Klick auf die Kachel meldet damit direkt über die bestehende Authentik-Sitzung an, statt auf der Anmeldeseite der App zu landen. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
2f7184a8fd
commit
dfcba39bdd
2 files changed
+30
-6
No files matched your search
@@ -28,7 +28,7 @@ Eigene Icons können in Authentik hochgeladen werden, sonst nimmt das Portal sei
|
|||||||
|
|
||||||
## Neues Tool ins Portal aufnehmen
|
## Neues Tool ins Portal aufnehmen
|
||||||
|
|
||||||
1. In Authentik eine Application anlegen (Name, Slug, Launch-URL).
|
1. In Authentik eine Application anlegen (Name, Slug, Launch-URL). Als Launch-URL den **SSO-Startpunkt** der App nehmen (z.B. `https://vvl.handy-insel.de/auth/login`), nicht die Startseite. Dann ist man nach dem Klick auf die Kachel direkt angemeldet, statt erst auf der Anmeldeseite der App zu landen. Die Launch-URLs der eigenen Tools stehen in `LAUNCH_URLS` im Setup-Skript.
|
||||||
2. Slug in `APP_ACCESS` eintragen und `scripts/authentik-setup.py --apply` laufen lassen (oder die Gruppe in Authentik direkt binden).
|
2. Slug in `APP_ACCESS` eintragen und `scripts/authentik-setup.py --apply` laufen lassen (oder die Gruppe in Authentik direkt binden).
|
||||||
3. Optional: Icon `public/icons/<slug>.svg` und Reihenfolge in `APP_ORDER`.
|
3. Optional: Icon `public/icons/<slug>.svg` und Reihenfolge in `APP_ORDER`.
|
||||||
4. Kopfleiste im Tool einbinden (siehe unten).
|
4. Kopfleiste im Tool einbinden (siehe unten).
|
||||||
|
|||||||
@@ -40,6 +40,16 @@ APP_ACCESS = {
|
|||||||
"zeit-dev": ["HI-Admin"],
|
"zeit-dev": ["HI-Admin"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Launch-URL = SSO-Startpunkt der App. Mit bestehender Authentik-Sitzung ist man nach dem
|
||||||
|
# Klick auf die Kachel ohne Zwischenschritt angemeldet (statt auf der Anmeldeseite der App).
|
||||||
|
LAUNCH_URLS = {
|
||||||
|
"vvl": "https://vvl.handy-insel.de/auth/login",
|
||||||
|
"timer": "https://timer.handy-insel.de/auth/login",
|
||||||
|
"zeiterfassung": "https://zeit.handy-insel.de/api/auth/sso/login",
|
||||||
|
"preisliste": "https://preis.handy-insel.de/api/auth/oidc/start",
|
||||||
|
"datenuebertragungen": "https://data.handy-insel.de/api/auth/oidc/start",
|
||||||
|
}
|
||||||
|
|
||||||
SERVICE_ACCOUNT = "hi-portal"
|
SERVICE_ACCOUNT = "hi-portal"
|
||||||
SERVICE_GROUP = "hi-portal-service"
|
SERVICE_GROUP = "hi-portal-service"
|
||||||
SERVICE_ROLE = "Portal: Apps pro Benutzer lesen"
|
SERVICE_ROLE = "Portal: Apps pro Benutzer lesen"
|
||||||
@@ -80,7 +90,7 @@ def step(title):
|
|||||||
|
|
||||||
|
|
||||||
def bind_apps(groups, apps):
|
def bind_apps(groups, apps):
|
||||||
step("1. Apps an Gruppen binden")
|
step("2. Apps an Gruppen binden")
|
||||||
for slug, group_names in APP_ACCESS.items():
|
for slug, group_names in APP_ACCESS.items():
|
||||||
app = apps.get(slug)
|
app = apps.get(slug)
|
||||||
if not app:
|
if not app:
|
||||||
@@ -106,8 +116,21 @@ def bind_apps(groups, apps):
|
|||||||
call("PATCH", f"/core/applications/{slug}/", {"policy_engine_mode": "any"})
|
call("PATCH", f"/core/applications/{slug}/", {"policy_engine_mode": "any"})
|
||||||
|
|
||||||
|
|
||||||
|
def set_launch_urls(apps):
|
||||||
|
step("3. Launch-URLs (Kachel meldet direkt per SSO an)")
|
||||||
|
for slug, url in LAUNCH_URLS.items():
|
||||||
|
app = apps.get(slug)
|
||||||
|
if not app:
|
||||||
|
print(f" - {slug}: App existiert (noch) nicht, übersprungen")
|
||||||
|
elif app.get("meta_launch_url") == url:
|
||||||
|
print(f" = {slug}: {url}")
|
||||||
|
else:
|
||||||
|
call("PATCH", f"/core/applications/{slug}/", {"meta_launch_url": url})
|
||||||
|
print(f" + {slug}: {app.get('meta_launch_url') or '-'} -> {url}")
|
||||||
|
|
||||||
|
|
||||||
def ensure_portal_app(apps):
|
def ensure_portal_app(apps):
|
||||||
step("2. OIDC-Provider und App 'Portal'")
|
step("1. OIDC-Provider und App 'Portal'")
|
||||||
template = next(p for p in results("/providers/oauth2/") if p["name"] == "Preisliste")
|
template = next(p for p in results("/providers/oauth2/") if p["name"] == "Preisliste")
|
||||||
provider = next((p for p in results("/providers/oauth2/") if p["name"] == "Portal"), None)
|
provider = next((p for p in results("/providers/oauth2/") if p["name"] == "Portal"), None)
|
||||||
if provider:
|
if provider:
|
||||||
@@ -144,7 +167,7 @@ def ensure_portal_app(apps):
|
|||||||
|
|
||||||
|
|
||||||
def ensure_service_account(groups):
|
def ensure_service_account(groups):
|
||||||
step("3. Service-Account für die App-Liste")
|
step("4. Service-Account für die App-Liste")
|
||||||
user = next((u for u in results(f"/core/users/?username={SERVICE_ACCOUNT}") if u["username"] == SERVICE_ACCOUNT), None)
|
user = next((u for u in results(f"/core/users/?username={SERVICE_ACCOUNT}") if u["username"] == SERVICE_ACCOUNT), None)
|
||||||
token_key = None
|
token_key = None
|
||||||
if user:
|
if user:
|
||||||
@@ -187,7 +210,7 @@ def ensure_service_account(groups):
|
|||||||
|
|
||||||
|
|
||||||
def branding():
|
def branding():
|
||||||
step("4. Branding")
|
step("5. Branding")
|
||||||
try:
|
try:
|
||||||
urllib.request.urlopen(f"{PORTAL_URL}/icon-192.png", timeout=10)
|
urllib.request.urlopen(f"{PORTAL_URL}/icon-192.png", timeout=10)
|
||||||
except Exception:
|
except Exception:
|
||||||
@@ -203,7 +226,7 @@ def branding():
|
|||||||
|
|
||||||
|
|
||||||
def write_env(path, values):
|
def write_env(path, values):
|
||||||
step(f"5. {path} aktualisieren")
|
step(f"6. {path} aktualisieren")
|
||||||
text = open(path).read() if os.path.exists(path) else ""
|
text = open(path).read() if os.path.exists(path) else ""
|
||||||
for key, value in values.items():
|
for key, value in values.items():
|
||||||
if not value:
|
if not value:
|
||||||
@@ -254,6 +277,7 @@ def main():
|
|||||||
|
|
||||||
provider = ensure_portal_app(apps)
|
provider = ensure_portal_app(apps)
|
||||||
bind_apps(groups, apps)
|
bind_apps(groups, apps)
|
||||||
|
set_launch_urls(apps)
|
||||||
user, token = ensure_service_account(groups)
|
user, token = ensure_service_account(groups)
|
||||||
if not args.skip_branding:
|
if not args.skip_branding:
|
||||||
branding()
|
branding()
|
||||||
|
|||||||
Reference in new issue
Block a user