Wire user-engine HTTP /me for member provisioning (CSOC-WP-0002-T04)
HttpUserEngineClient uses trusted-proxy claims against live user-engine. Offline stub when URL/secret unset. Align default tenant with KeyCape tenant:coulomb; map OIDC tenant/principal_type/groups into the envelope.
This commit is contained in:
parent
a6a380b19f
commit
d88767f05b
13 changed files with 325 additions and 48 deletions
|
|
@ -77,13 +77,7 @@ def oidc_callback(request: HttpRequest) -> HttpResponse:
|
|||
return HttpResponseBadRequest("Token missing subject")
|
||||
|
||||
issuer = raw.get("iss") or settings.OIDC_ISSUER
|
||||
claims = IdentityClaims(
|
||||
issuer=str(issuer),
|
||||
subject=str(sub),
|
||||
email=str(raw.get("email") or ""),
|
||||
name=str(raw.get("name") or ""),
|
||||
preferred_username=str(raw.get("preferred_username") or ""),
|
||||
)
|
||||
claims = _claims_from_oidc_payload(raw, issuer=str(issuer), subject=str(sub))
|
||||
establish_session(request, claims)
|
||||
return redirect(settings.LOGIN_REDIRECT_URL)
|
||||
|
||||
|
|
@ -105,11 +99,52 @@ def dev_login(request: HttpRequest) -> HttpResponse:
|
|||
email=(request.POST.get("email") or "").strip(),
|
||||
name=(request.POST.get("name") or "").strip(),
|
||||
preferred_username=(request.POST.get("preferred_username") or "").strip(),
|
||||
tenant=(request.POST.get("tenant") or settings.DEFAULT_TENANT_ID).strip(),
|
||||
principal_type="human",
|
||||
roles=("user",),
|
||||
authorized_party=settings.USER_ENGINE_APPLICATION_ID,
|
||||
)
|
||||
establish_session(request, claims)
|
||||
return redirect(settings.LOGIN_REDIRECT_URL)
|
||||
|
||||
return render(request, "identity/dev_login.html")
|
||||
return render(
|
||||
request,
|
||||
"identity/dev_login.html",
|
||||
{"default_tenant": settings.DEFAULT_TENANT_ID},
|
||||
)
|
||||
|
||||
|
||||
def _claims_from_oidc_payload(
|
||||
raw: dict, *, issuer: str, subject: str
|
||||
) -> IdentityClaims:
|
||||
aud = raw.get("aud", ())
|
||||
if isinstance(aud, str):
|
||||
audience = (aud,)
|
||||
else:
|
||||
audience = tuple(str(a) for a in (aud or ()))
|
||||
groups = raw.get("groups") or ()
|
||||
if isinstance(groups, str):
|
||||
groups = (groups,)
|
||||
roles = raw.get("roles") or raw.get("tenant_roles") or ()
|
||||
if isinstance(roles, str):
|
||||
roles = (roles,)
|
||||
assurance = raw.get("assurance") if isinstance(raw.get("assurance"), dict) else {}
|
||||
return IdentityClaims(
|
||||
issuer=issuer,
|
||||
subject=subject,
|
||||
email=str(raw.get("email") or ""),
|
||||
name=str(raw.get("name") or ""),
|
||||
preferred_username=str(raw.get("preferred_username") or ""),
|
||||
tenant=str(raw.get("tenant") or settings.DEFAULT_TENANT_ID),
|
||||
principal_type=str(raw.get("principal_type") or "human"),
|
||||
groups=tuple(str(g) for g in groups),
|
||||
roles=tuple(str(r) for r in roles) or ("user",),
|
||||
assurance=dict(assurance),
|
||||
audience=audience,
|
||||
authorized_party=str(
|
||||
raw.get("azp") or raw.get("client_id") or settings.OIDC_CLIENT_ID or ""
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@require_http_methods(["GET", "POST"])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue