Skip to main content

Module oauth_handler

Module oauth_handler 

Source
Expand description

The verb-shaped OAuth HTTP surface (hand-authored, user-owned).

Five verbs, no generic CRUD anywhere on it:

  • POST /oauth/authorize — initiation (write:integrations): returns the provider consent URL bound to a freshly minted account row.
  • GET /oauth/callback — the provider redirect target. PUBLIC (the provider cannot carry the caller’s auth), and side-effect-free by construction: it verifies the signed state and serves a page whose only act is auto-submitting an invisible POST form — a safe method never writes.
  • POST /oauth/complete — the form target (write:integrations): code exchange + identity gauntlet + store + transition. Accepts the RFC-8058-style form body the page submits AND a plain JSON body.
  • POST /oauth/:id/disconnect — revoke credential + terminal account status (delete:integrations).
  • GET /oauth/:id/status — metadata-only account view (any authenticated principal).

Authorization fails closed: every route except the callback sits behind require_principal (401 without a validated principal extension — the composing host’s auth layer inserts it) and enforces its own permission (403 without it). No god flag grants every verb.

Tenancy (ADR-0029): the module’s tables carry no company column — the composing service’s tenancy decorator owns org scoping, so isolation here is the host’s fence plus permission checks, not a company predicate. The principal’s company_id is forwarded only on the verbs that reach the credential STORE (complete / disconnect) — it is the store’s scope key, the documented legacy twin; an unknown value fails closed at the store.

No response ever carries token material — the account row holds none, and the store is reachable only through the service’s port calls.

Structs§

OAuthPrincipal
The validated principal the composing host’s auth layer inserts into the request extensions. Present ⇒ authenticated; the permission list carries the module-scope grants (write:integrations, delete:integrations …).

Functions§

create_oauth_routes
Build the OAuth verb routes. The callback is PUBLIC (the provider cannot carry the caller’s credentials); every other route requires a validated principal and enforces its own permission.
require_principal
Auth-required layer: 401 unless a validated principal extension is on the request (fail closed — absence of auth information is never access).