feat/lc-22-bunyip-rp-cutover #346

Merged
YousifShkara merged 3 commits from feat/lc-22-bunyip-rp-cutover into main 2026-06-18 05:19:54 +02:00
Owner
No description provided.
Replaces lets-chat's local username + password / TOTP / password-reset surface with a Bunyip OIDC RP (`/auth/bunyip/{start,callback}`) as the sole sign-in path. Mirrors the drillmark + mokosh series posture so lets-chat stops being the odd-one-out in the PSA stack.

Implementation spec lives at docs/lets-chat/sso/bunyip-only/ (overview, architecture, prerequisites, account provisioning, server cutover, rollout + testing). The four `LETS_CHAT_BUNYIP_SSO_{ISSUER,CLIENT_ID,CLIENT_SECRET,REDIRECT_URI}` env vars are mandatory at startup; lets-chat refuses to start without a working OP (no flag, no fallback).

Added: `server/src/oidc/` (config + RP client + EdDSA verifier + PKCE primitives), `server/src/routes/bunyip_sso.rs` (start + callback only, no settings-Connect/Disconnect dance), `server/src/db/oidc_pending.rs`, `server/src/db/auth.rs` bunyip helpers (find_user_id_by_bunyip_sub, get_user_auth_flags_by_bunyip_sub, create_user_from_bunyip, username_exists). Login template rewritten as a "Sign in with Bunyip" shell.

Deleted: routes/{auth password handlers, two_factor, password_reset, login_alerts, email_verification}, db/{two_factor, password_reset, login_alerts, email_verification}, templates/auth/{register, forgot, reset, verify_email_result, form_errors}, settings page's change-password + 2FA + email-verification sections, settings POST /settings/password handler.

Migrations: 0029 adds `users.bunyip_sub` (NOT NULL DEFAULT ''), 0030 hard-cuts every pre-cutover row (operator must snapshot beforehand per docs/.../05-rollout-and-testing.md §5.1), 0031 creates the UNIQUE index now that no empty strings remain, 0032 creates `oidc_pending`, 0033 NULLs/empties the legacy password + TOTP + email-verification data on any rows that survived (v2 drops the columns themselves).

The `saas` build is untouched (its `saas_auth.rs` JWT path stays); the cutover applies to the standalone build only. Bots + API tokens are orthogonal and unaffected.

#LC-22

Operator-Action: Land the bunyip-api oauth_clients seed migration first, set the four `LETS_CHAT_BUNYIP_SSO_*` env vars on every deployment, take a pre-deploy snapshot of auth.db (the hard-cut migration is irreversible), then deploy. Existing local users cannot sign in post-cutover; operator manually re-grafts their authored content if a pre-cutover user comes back via Bunyip.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`enforce_2fa_enrollment` was harmful post-cutover: every Bunyip-provisioned user has `totp_enabled = 0` and the middleware 303'd them to `/settings/2fa/setup`, which the cutover deleted. Delete the middleware; Bunyip owns 2FA upstream.

The admin Anti-Spam page still exposed `rate_limit_registrations`, `rate_limit_logins`, `rate_limit_password_resets` form fields; the handlers they fed are gone with the password path. Strip the form fields, the view struct fields, and the template inputs. The `rate_limit_messages` knob (the only surface lets-chat still owns) stays.

`enforce_maintenance_mode` exempt-path list trimmed: `/forgot`, `/reset/`, `/login/` (the 2FA challenge subroute) are dead; `/auth/bunyip/` added so users can complete the SSO dance during maintenance windows.

#LC-22

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
test(sso): adapt fixtures for users.bunyip_sub UNIQUE constraint (LC-22)
Some checks failed
check-secrets / TruffleHog (push) Successful in 3s
check-secrets / Nosey parker (push) Successful in 4s
check-secrets / Kingfisher (push) Successful in 4s
check-secrets / TruffleHog (pull_request) Successful in 3s
check-secrets / Nosey parker (pull_request) Successful in 4s
check-secrets / Kingfisher (pull_request) Successful in 5s
Create release / Create release from merged PR (pull_request) Has been skipped
Check / clippy + fmt + tests (pull_request) Failing after 44s
d0602f0bfe
`server/tests/db_enclave.rs::insert_user` did raw `INSERT INTO users` without a `bunyip_sub` column. With the 0031 unique index in place every test that inserted more than one user hit `UNIQUE constraint failed: users.bunyip_sub`. Synthesize a per-row placeholder in the test helper, matching the pattern in `db::auth::create_user`.

`server/tests/routes_maintenance.rs::password_reset_surface_stays_reachable_during_maintenance` hit `/forgot` and `/reset/...`, both deleted. Rewrite as `login_surface_stays_reachable_during_maintenance` against `/login`. The `/auth/bunyip/*` paths are also exempted by the maintenance middleware but cannot be hit in tests (the SSO client is `None` and the handler panics by design).

#LC-22

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
YousifShkara deleted branch feat/lc-22-bunyip-rp-cutover 2026-06-18 05:19:54 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!346
No description provided.