Skip to content

feat(auth): model the token broker — POST /auth/v1/broker/<provider>[/<integration>] - #82

Merged
ngjunsiang merged 1 commit into
feat/auth-connectionsfrom
feat/auth-broker
Oct 4, 2026
Merged

ngjunsiang merged 1 commit into
feat/auth-connectionsfrom
feat/auth-broker

Conversation

@nycomp

@nycomp nycomp commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Stack (merge in order): #78 -> #79 -> #80 -> #81 -> #82 -> #85
This is 5 of 6. Base is the branch of the PR below; each PR's diff shows only its own commit, and GitHub retargets it to main when the one below merges. Branches rebuilt on current main (9563443) — content unchanged from the original commits.
As always per SOP: after each merge, verify the issue auto-closed and close it manually if not.

Summary

  • New auth.broker resource: broker.token(provider, integration=None, *, min_scopes=None)
    • identity route: POST /auth/v1/broker/<provider>/
    • namespaced route: POST /auth/v1/broker/<provider>/<integration>/ (e.g. google + classroom)
    • body {"min_scopes": [...]} when given, {} otherwise — matching what campus-classroom sends today
  • Returns the flat 200 response ({provider, user_id, access_token, token_type, expires_in, scope}); refresh tokens never leave Campus (server invariant).
  • Errors arrive as APIError subclasses through raise_for_status() — 404 not-connected → NotFoundError, 401 session-expired → AuthenticationError, 403 with details.missing_scopes, 400 AUTH_INVALID_SCOPE — so campus-classroom can drop its hand-rolled status mapping (classroom_auth.py:288-293).

Tests

tests/unit/test_broker.py — 4 contract tests pinning both route paths, empty-body vs min_scopes bodies. Full suite: 156 passed.

Fixes #72

auth.broker.token(provider, integration=None, min_scopes=None) POSTs
/auth/v1/broker/<provider>/ or /auth/v1/broker/<provider>/<integration>/
with {min_scopes} when given. campus-classroom currently raw-requests
this endpoint and hand-maps error statuses; through the JsonClient the
errors arrive as APIError subclasses (403 details.missing_scopes, 401
AuthenticationError, 400 AUTH_INVALID_SCOPE) via raise_for_status.

Fixes #72
Sign up for free to 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.

feat(auth): model the token broker — POST /auth/v1/broker/<provider>[/<integration>]

2 participants