Skip to content

feat(auth): principal-resolver chain for session-or-bearer auth (#163) - #168

Merged
antosubash merged 16 commits into
mainfrom
worktree-issue-163-principal-resolver-spec
May 22, 2026
Merged

feat(auth): principal-resolver chain for session-or-bearer auth (#163)#168
antosubash merged 16 commits into
mainfrom
worktree-issue-163-principal-resolver-spec

Conversation

@antosubash

Copy link
Copy Markdown
Owner

Summary

  • Adds app.state.auth.principal_resolvers — an extension point for plugging in non-cookie auth (PAT bearer tokens, API keys, JWT, etc.). Closessimple_module_auth: expose a principal resolver that handles session cookie OR PAT bearer token #163.
  • users.AuthMiddleware now falls through session cookie → registered resolvers → unauthenticated. Unauthenticated /api/* returns 401 {"detail": "Not authenticated"}; view paths still 302 to /users/login with the original URL stashed in session["next"].
  • New authoritative doc at docs/framework/principal-resolvers.md with the contract, ordering rules, and a worked Bearer-token example. Pointer added from docs/framework-conventions.md.

Notable behaviour change

  • Unauthenticated XHR to a private /api/* route now returns 401 {"detail": "Not authenticated"} JSON instead of 302 → /users/login HTML. This is strictly better for scripted callers and frontend XHR handling. Three pre-existing tests in modules/users/tests/test_api_admin.py that asserted the old 302 behaviour have been updated to assert the new 401 contract.

Test plan

  • uv run pytest modules/auth/tests/test_resolver_registry.py -v
  • uv run pytest modules/users/tests/test_users_middleware.py modules/users/tests/test_users_middleware_resolvers.py -v
  • uv run pytest tests/test_principal_resolver_integration.py -v
  • make lint
  • make doctor
  • make test-py

Design for an extension-point that lets downstream modules (e.g. smpy_gis)
plug in a bearer-token / PAT resolver without upstreaming PAT storage.
Step-by-step TDD plan covering type alias, AuthState registry,
AuthModule hook, middleware fall-through + 401-for-/api/* branch,
integration test, and framework docs.
@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented May 21, 2026

Copy link
Copy Markdown

Deploying simple-module-python with Cloudflare Pages Cloudflare Pages

Latest commit:a00cd18
Status: ✅ Deploy successful!
Preview URL:https://40a83663.simple-module-python.pages.dev
Branch Preview URL:https://worktree-issue-163-principal.simple-module-python.pages.dev

View logs

- _middleware_support: drop hand-rolled _sign_session, use framework's
simple_module_test.forge_session_cookie (eliminates duplication).
- integration test: import UserContext from `auth` (the documented
public re-export) so the symbol's public-surface contract is
exercised by an actual test.
- middleware: extract _API_PATH_PREFIX and _UNAUTH_DETAIL constants
alongside _LOGIN_REDIRECT — single-source the wire format.
- principal-resolvers doc: document that resolvers run on public paths
too (telemetry use case), plus add per-request DB-cost caveat with
LRU caching guidance for high-traffic deployments.
- test docstring: drop drive-by reference to an unrelated fixture bug.
@antosubash
antosubash merged commit e630495 into mainMay 22, 2026
12 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

simple_module_auth: expose a principal resolver that handles session cookie OR PAT bearer token

1 participant

@antosubash