Commit Graph

22 Commits

Author SHA1 Message Date
serversdown 41ab900c33 feat(auth): login/logout/change-password routes + pages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 19:38:55 +00:00
serversdown 2879abb355 feat(auth): deny-by-default gate middleware + require_role
Adds operator_gate Starlette HTTP middleware that gates every route
except an explicit allow-list. Flag defaults OFF so all existing
behaviour and tests are unchanged. wire_operator_auth helper in
conftest lets tests monkeypatch the module-global SessionLocal and
flag, keeping the gate's own DB session pointed at the test engine.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 19:27:41 +00:00
serversdown e8fe4845aa feat(auth): authenticate + lockout + operator data helpers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 19:19:36 +00:00
serversdown a6e1cb4f87 feat(auth): operator session cookie + current_operator DB re-validation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 19:11:41 +00:00
serversdown 4abfcbc293 feat(auth): OperatorUser model + role ladder
Add OperatorUser SQLAlchemy model (operator_users table, auto-created by
create_all) with email uniqueness, default active/must_change_password/
failed_login_count, and sessions_valid_from truncated to whole seconds.
Add backend/operator_auth.py with feature flag, cookie constants, _ROLE_RANK
map, role_at_least(), and _norm_email() helpers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:08:18 +00:00
serversdown 8e817ec48d feat(auth): generic HMAC signed-cookie module for operator auth
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 19:05:56 +00:00
serversdown 766f64f35f refactor: final-review cleanup
- delete dead magic-link helpers (resolve_token, ensure_project_client,
  mint_link_token, provision_preview_session) + now-unused datetime import
- key brute-force lockout on link_token alone (IP term only enabled a
  source-IP-rotation bypass; behind the proxy all clients share one IP)
- drop unused PORTAL_BASE_URL from the retired CLI
- add WebSocket ownership tests (unauth + cross-project both close 1008)
2026-06-16 00:28:23 +00:00
serversdown 20f62a5c0a feat: env-driven Secure flag on portal session cookie
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 00:16:54 +00:00
serversdown 01180d5725 fix: retire portal_admin mint-link (dead /portal/enter URL); refresh docstrings; assert revoke route gone 2026-06-16 00:15:09 +00:00
serversdown f0a13ea2ff refactor: retire interim magic-link/open-link in favor of password gate
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 00:06:02 +00:00
serversdown 25a4a28433 feat: operator portal-access endpoints (enable/password/disable/state)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 23:55:10 +00:00
serversdown b8e4718318 fix: link project to its portal client (project.client_id) so the portal isn't empty
Caught by adversarial review of the scope test: portal_client_for_project minted a
dedicated client but never set project.client_id, so the client-scoped routes found
no projects — every location 404'd, including the client's own (empty portal). Now
links the project + adds a positive-case test.
2026-06-15 23:53:19 +00:00
serversdown c3eb900b7e test: portal session is isolated to its own project (404 on others)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 23:48:08 +00:00
serversdown c74dada8b3 fix: treat enabled-but-passwordless portal as inactive (no dead form / self-lockout) 2026-06-15 23:46:14 +00:00
serversdown d75f405857 feat: per-project portal password gate (/portal/p/{token}) + lockout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 23:41:37 +00:00
serversdown 446d8704f9 refactor: hoist Project import to top; drop unused test import 2026-06-15 23:39:14 +00:00
serversdown c04830a0ad feat: per-project portal session mint + link-token resolve + lockout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 23:35:48 +00:00
serversdown b11e1a554f feat: add per-project portal gate columns + migration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 23:32:41 +00:00
serversdown ad6de946b5 refactor: simplify verify_password except clause; drop unused import 2026-06-15 23:31:14 +00:00
serversdown d44625374d feat: argon2 password hashing helpers for the portal 2026-06-15 23:29:26 +00:00
serversdown 33069a070d test: tidy conftest fixtures per review (drop dead try/finally, scope override cleanup, rm unused import) 2026-06-15 23:28:16 +00:00
serversdown ec5d986ac5 test: stand up pytest harness + add argon2-cffi
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 23:23:41 +00:00