feat(flow): auto-resolve authentik sub and improve admin dropdown UX
This commit is contained in:
@@ -83,7 +83,11 @@ def _sync_member_to_authentik(
|
|||||||
display_name=display_name,
|
display_name=display_name,
|
||||||
is_active=is_active,
|
is_active=is_active,
|
||||||
)
|
)
|
||||||
return {"authentik_user_id": result.user_id, "sync_action": result.action}
|
return {
|
||||||
|
"authentik_user_id": result.user_id,
|
||||||
|
"sync_action": result.action,
|
||||||
|
"authentik_sub": result.authentik_sub or "",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.get("/systems")
|
@router.get("/systems")
|
||||||
@@ -332,17 +336,25 @@ def upsert_member(
|
|||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
) -> MemberItem:
|
) -> MemberItem:
|
||||||
users_repo = UsersRepository(db)
|
users_repo = UsersRepository(db)
|
||||||
|
resolved_sub = payload.authentik_sub
|
||||||
authentik_user_id = None
|
authentik_user_id = None
|
||||||
if payload.sync_to_authentik:
|
if payload.sync_to_authentik:
|
||||||
|
seed_sub = payload.authentik_sub or (payload.email or "")
|
||||||
|
if not seed_sub:
|
||||||
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="authentik_sub_or_email_required")
|
||||||
sync = _sync_member_to_authentik(
|
sync = _sync_member_to_authentik(
|
||||||
authentik_sub=payload.authentik_sub,
|
authentik_sub=seed_sub,
|
||||||
email=payload.email,
|
email=payload.email,
|
||||||
display_name=payload.display_name,
|
display_name=payload.display_name,
|
||||||
is_active=payload.is_active,
|
is_active=payload.is_active,
|
||||||
)
|
)
|
||||||
authentik_user_id = int(sync["authentik_user_id"])
|
authentik_user_id = int(sync["authentik_user_id"])
|
||||||
|
if sync.get("authentik_sub"):
|
||||||
|
resolved_sub = str(sync["authentik_sub"])
|
||||||
|
if not resolved_sub:
|
||||||
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="authentik_sub_required")
|
||||||
row = users_repo.upsert_by_sub(
|
row = users_repo.upsert_by_sub(
|
||||||
authentik_sub=payload.authentik_sub,
|
authentik_sub=resolved_sub,
|
||||||
email=payload.email,
|
email=payload.email,
|
||||||
display_name=payload.display_name,
|
display_name=payload.display_name,
|
||||||
is_active=payload.is_active,
|
is_active=payload.is_active,
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class MemberItem(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class MemberUpsertRequest(BaseModel):
|
class MemberUpsertRequest(BaseModel):
|
||||||
authentik_sub: str
|
authentik_sub: str | None = None
|
||||||
email: str | None = None
|
email: str | None = None
|
||||||
display_name: str | None = None
|
display_name: str | None = None
|
||||||
is_active: bool = True
|
is_active: bool = True
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ from app.core.config import Settings
|
|||||||
class AuthentikSyncResult:
|
class AuthentikSyncResult:
|
||||||
user_id: int
|
user_id: int
|
||||||
action: str
|
action: str
|
||||||
|
authentik_sub: str | None = None
|
||||||
|
|
||||||
|
|
||||||
class AuthentikAdminService:
|
class AuthentikAdminService:
|
||||||
@@ -66,10 +67,14 @@ class AuthentikAdminService:
|
|||||||
patch_resp = client.patch(f"/api/v3/core/users/{user_pk}/", json=payload)
|
patch_resp = client.patch(f"/api/v3/core/users/{user_pk}/", json=payload)
|
||||||
if patch_resp.status_code >= 400:
|
if patch_resp.status_code >= 400:
|
||||||
raise HTTPException(status_code=502, detail="authentik_update_failed")
|
raise HTTPException(status_code=502, detail="authentik_update_failed")
|
||||||
return AuthentikSyncResult(user_id=user_pk, action="updated")
|
return AuthentikSyncResult(user_id=user_pk, action="updated", authentik_sub=existing.get("uid"))
|
||||||
|
|
||||||
create_resp = client.post("/api/v3/core/users/", json=payload)
|
create_resp = client.post("/api/v3/core/users/", json=payload)
|
||||||
if create_resp.status_code >= 400:
|
if create_resp.status_code >= 400:
|
||||||
raise HTTPException(status_code=502, detail="authentik_create_failed")
|
raise HTTPException(status_code=502, detail="authentik_create_failed")
|
||||||
created = create_resp.json()
|
created = create_resp.json()
|
||||||
return AuthentikSyncResult(user_id=int(created["pk"]), action="created")
|
return AuthentikSyncResult(
|
||||||
|
user_id=int(created["pk"]),
|
||||||
|
action="created",
|
||||||
|
authentik_sub=created.get("uid"),
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user