{# VERBATIM COPY of ivatar's own ivatar/ivataraccount/templates/login.html at the image digest pinned in vars.yaml (upstream commit eff913c6), PLUS one "Login with SSO" control. Nothing else differs — diff against upstream before refreshing that pin. WHY A WHOLE-FILE COPY. Upstream renders exactly one social button, behind a `with_fedora` context flag its LoginView computes from SOCIAL_AUTH_FEDORA_KEY (ivatar/ivataraccount/views.py); there is no loop over the configured backends and no block to extend, so a control for any other backend has to come from a template that SHADOWS this one. WHY THIS PATH SHADOWS. settings.py puts BASE_DIR/templates (= /app/templates) in TEMPLATES[0]["DIRS"] with APP_DIRS=True, and Django consults the filesystem loader BEFORE the app-directories loader — so /app/templates/ login.html wins over ivatar/ivataraccount/templates/login.html. Upstream ships no login.html at that path, so this adds a file rather than replacing one. WHY A FORM AND NOT A LINK. social-auth-app-django 6.0.0 decorates its `begin` view with @require_POST (login-CSRF hardening), so GET /auth/login// answers 405 — MEASURED against this image. The Fedora `` two rows down has the same defect upstream; it is left byte-identical rather than silently diverging, and it never renders here because SOCIAL_AUTH_FEDORA_KEY is unset. The POST target is a SIBLING form, reached via the button's `form=` attribute, because HTML forbids nesting a form inside the login form this button visually belongs to. NO CONTEXT GATE. compose.yaml bind-mounts this file only when an `oidc` plug is attached (or vars.keycloak.issuer is set), so the control can be unconditional: where the mount exists, /auth/login/oidc/ is wired. #} e1e2914ae925 :: Login to yourivatar account

Login

{# "oidc" is social_core.backends.open_id_connect.OpenIdConnectAuth.name, the backend config_local.py appends to AUTHENTICATION_BACKENDS. `next` rides along as POST data because social_core's do_auth reads the redirect field out of strategy.request_data(), which is request.POST here — so a deep link survives the round trip to the IdP. #}