Skip dead apps in login propagation chain
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 46s

Health-check each app via internal URL before redirecting.
Dead apps are silently skipped so the chain doesn't break.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
giles
2026-02-23 12:41:15 +00:00
parent 6275049025
commit 1cd11b9a2d

View File

@@ -242,22 +242,44 @@ def register(url_prefix="/auth"):
"""Chain through each client app's OAuth login to propagate the
account session. Each app does its OAuth flow (instant since
account is already logged in) then redirects back here. When
the chain is empty, redirect to the original target."""
the chain is empty, redirect to the original target.
Dead apps are skipped via internal health check."""
import os, aiohttp
from urllib.parse import quote
chain = qsession.get("sso_chain", [])
final = qsession.get("sso_final", account_url("/"))
if not chain or not g.get("user"):
if not g.get("user"):
qsession.pop("sso_chain", None)
qsession.pop("sso_final", None)
return redirect(final)
next_app = chain.pop(0)
qsession["sso_chain"] = chain
from urllib.parse import quote
comeback = account_url("/auth/propagate")
login_url = app_url(next_app, f"/auth/login?next={quote(comeback, safe='')}")
return redirect(login_url)
while chain:
next_app = chain.pop(0)
qsession["sso_chain"] = chain
# Health check via internal URL before redirecting
internal = (os.getenv(f"INTERNAL_URL_{next_app.upper()}") or f"http://{next_app}:8000").rstrip("/")
try:
async with aiohttp.ClientSession() as http:
async with http.head(
internal,
timeout=aiohttp.ClientTimeout(total=2),
allow_redirects=True,
) as resp:
if resp.status < 500:
login = app_url(next_app, f"/auth/login?next={quote(comeback, safe='')}")
return redirect(login)
except Exception:
current_app.logger.warning("[propagate] skipping dead app: %s", next_app)
continue
qsession.pop("sso_chain", None)
qsession.pop("sso_final", None)
return redirect(final)
@auth_bp.post("/logout/")
async def logout():