feat: Fusion ACC-3.2 — pont SSO draco_session (/auth/draco), liens sub → compte (migration 51) (#21)
This commit is contained in:
+64
-1
@@ -102,7 +102,8 @@ body{background:#191919;color:#fff;font-family:-apple-system,BlinkMacSystemFont,
|
||||
<div class="oauth-section" id="oauth-section">
|
||||
<p style="font-size:13px;color:rgba(255,255,255,.4);margin-bottom:8px;">Or continue with</p>
|
||||
<button class="oauth-btn" onclick="window.location='/auth/login?provider=gitea'" style="margin-bottom:8px">🔗 <span id="gitea-btn-label">Login</span> with Gitea</button>
|
||||
<button class="oauth-btn" onclick="window.location='/auth/login?provider=github'">🐙 <span id="github-btn-label">Login</span> with GitHub</button>
|
||||
<button class="oauth-btn" onclick="window.location='/auth/login?provider=github'" style="margin-bottom:8px">🐙 <span id="github-btn-label">Login</span> with GitHub</button>
|
||||
<button class="oauth-btn" onclick="window.location='https://og.dracodev.net/sso/authorize?return_to=https%3A%2F%2Fflowdeck.dracodev.net%2Fauth%2Fdraco'">🧭 Login with ObsiGate (SSO)</button>
|
||||
</div>
|
||||
<!-- SSO / SAML + OIDC (v6.7.0) — buttons injected by loadSsoProviders() -->
|
||||
<div class="oauth-section" id="sso-section" style="display:none">
|
||||
@@ -451,6 +452,63 @@ async def callback(
|
||||
return response
|
||||
|
||||
|
||||
# ── Fusion ACC-3.2 — pont SSO draco_session ──────────────────────────────
|
||||
|
||||
@router.get("/draco")
|
||||
def draco_bridge(request: Request, next: str = "/workspaces"):
|
||||
"""Convertit le cookie SSO ``draco_session`` (ObsiGate) en session.
|
||||
|
||||
Point de retour de ``GET /sso/authorize`` de l'émettrice : si le
|
||||
cookie est valide et résolu vers un compte local, une session
|
||||
Flowdeck native est créée ; sinon, retour à la connexion locale.
|
||||
"""
|
||||
from app.services import draco
|
||||
|
||||
user = draco.user_for_draco(request)
|
||||
if user is None:
|
||||
return RedirectResponse(url="/auth/login?provider=local", status_code=302)
|
||||
session = SessionManager.create_session(user, request)
|
||||
_log_login(user["id"], request)
|
||||
cible = next if next.startswith("/") and not next.startswith("//") else "/workspaces"
|
||||
response = RedirectResponse(url=cible, status_code=302)
|
||||
response.set_cookie("flowdeck_session", session, httponly=True,
|
||||
max_age=86400 * 7, samesite="lax", path="/")
|
||||
return response
|
||||
|
||||
|
||||
@router.get("/draco-link")
|
||||
def draco_link_get(request: Request):
|
||||
"""Sub draco associé au compte courant (ou null)."""
|
||||
from app.services import draco
|
||||
|
||||
user = _session_user_or_401(request)
|
||||
return {"sub": draco.current_link(user["id"])}
|
||||
|
||||
|
||||
@router.post("/draco-link")
|
||||
def draco_link_post(request: Request):
|
||||
"""(Ré)associe le sub du cookie draco de la requête au compte."""
|
||||
from fastapi import HTTPException
|
||||
|
||||
from app.services import draco
|
||||
|
||||
user = _session_user_or_401(request)
|
||||
sub = draco.relink(request, user)
|
||||
if sub is None:
|
||||
raise HTTPException(400, "Cookie draco_session absent, invalide ou déjà lié ailleurs")
|
||||
return {"sub": sub}
|
||||
|
||||
|
||||
@router.delete("/draco-link")
|
||||
def draco_link_delete(request: Request):
|
||||
"""Dissocie le compte (pierre tombale anti re-création automatique)."""
|
||||
from app.services import draco
|
||||
|
||||
user = _session_user_or_401(request)
|
||||
draco.unlink(user["id"])
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@router.get("/logout")
|
||||
def logout(request: Request):
|
||||
"""Clear session and redirect to login page.
|
||||
@@ -479,6 +537,11 @@ def current_user(request: Request):
|
||||
user = gcu(request)
|
||||
if not user:
|
||||
return {"authenticated": False}
|
||||
# Fusion ACC-3.2 : si un cookie draco valide accompagne la session
|
||||
# native, l'association sub ↔ compte se crée à cette occasion.
|
||||
from app.services import draco
|
||||
|
||||
draco.maybe_link(request, user)
|
||||
return {"authenticated": True, "user": public_user(user)}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user