Wires the OIDC client landed in #67 (PR1) into verifier/serve.py and the SPA. Tracks the second of the two flowsheet-side PRs called out in plans/oidc-auth.md.
Scope
- Tri-modal middleware install (OIDC > BasicAuth > none) and the
_SessionCookieMiddleware that gates every non-public route on the signed flowsheet_session cookie.
- Four new auth routes:
/auth/login, /auth/callback, /auth/logout, /auth/me.
Depends(get_reviewer) on /api/save + server-authority overwrite of verified_by. A client cannot spoof another reviewer.
reviewer_id TEXT column on jobs.db (late-column ALTER TABLE migration), threaded through mark_verified.
VerifiedBy schema + PageResult.verified_by on disk (Optional, default None — backwards-compatible with every pre-OIDC verified.json).
- SPA changes:
/auth/me fetched on load to render the reviewer's name; authFetch wrapper that redirects to /auth/login on 401.
Out of scope (deferred per plan)
- Refresh tokens (12h re-login by signature TTL is acceptable).
- Single-logout against api.wxyc.org.
- Per-reviewer queues, leaderboards, or quality flagging — separate work on top of this identity foundation.
- Backend-Service
buildTrustedClients() refactor — separate PR in the auth repo.
Test plan
- Full
pytest run passes (554 tests, 8 skipped per existing markers).
ruff check, ruff format --check, mypy core cli.py all green.
- Manual smoke against
localhost:8082/auth once the Backend-Service trustedClient lands: /auth/login → consent screen → /auth/callback → land back on /verifier/, name renders in header, save writes verified_by block + jobs.reviewer_id.
Depends on #67 (which adds core/auth.py consumed by this PR).
Plan: plans/oidc-auth.md.
Wires the OIDC client landed in #67 (PR1) into
verifier/serve.pyand the SPA. Tracks the second of the two flowsheet-side PRs called out in plans/oidc-auth.md.Scope
_SessionCookieMiddlewarethat gates every non-public route on the signedflowsheet_sessioncookie./auth/login,/auth/callback,/auth/logout,/auth/me.Depends(get_reviewer)on/api/save+ server-authority overwrite ofverified_by. A client cannot spoof another reviewer.reviewer_id TEXTcolumn onjobs.db(late-column ALTER TABLE migration), threaded throughmark_verified.VerifiedByschema +PageResult.verified_byon disk (Optional, default None — backwards-compatible with every pre-OIDCverified.json)./auth/mefetched on load to render the reviewer's name;authFetchwrapper that redirects to/auth/loginon 401.Out of scope (deferred per plan)
buildTrustedClients()refactor — separate PR in the auth repo.Test plan
pytestrun passes (554 tests, 8 skipped per existing markers).ruff check,ruff format --check,mypy core cli.pyall green.localhost:8082/authonce the Backend-ServicetrustedClientlands:/auth/login→ consent screen →/auth/callback→ land back on/verifier/, name renders in header, save writesverified_byblock +jobs.reviewer_id.Depends on #67 (which adds
core/auth.pyconsumed by this PR).Plan: plans/oidc-auth.md.