feat(auth): implement OAuth 2.0 Device Authorization Flow (RFC 8628)#354
Merged
feat(auth): implement OAuth 2.0 Device Authorization Flow (RFC 8628)#354
Conversation
Adds support for CLI and device applications to authenticate without embedding a client secret. ## Backend (campus) - Add DeviceCode model for tracking pending device authorizations - Add device authorization flow scheme (OAuth2DeviceAuthorizationFlowScheme) - Add OAuth routes (public, no auth required): - POST /oauth/device_authorize - request device/user code - POST /oauth/token - poll for token (device_code grant type) - GET /oauth/device - verification page (HTML) - POST /oauth/device/authorize - submit user code authorization - Add RFC 8628 token errors: AuthorizationPendingError, SlowDownError, ExpiredTokenError, AccessDeniedError - Add utility functions: generate_device_code(), generate_user_code() - Export ConflictError from errors __init__.py ## campus-api-python - Add OAuth device flow client methods - Add `oauth` property to AuthRoot - Add `mode` parameter to Campus.__init__(): "server" (default, requires CLIENT_ID/CLIENT_SECRET) or "device" (no credentials required) Resolves #353 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- test_error_codes_format: skip OAuth token error codes (AUTH_ prefix) and inherited str methods when validating error constants - test_invalid_request_error_has_envelope: allow details to be None since not all error types include details by default Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use client_resource[client_id] instead of client_resource.client[client_id] - Use device_code_resource instead of device_code_resource.device_code - Use credentials_resource["campus"][user_id] instead of credentials_resource.credentials["campus"] - Import InvalidClientError and InvalidGrantError from token_errors not auth_errors - Replace auth_errors.ExpiredTokenError with api_errors.InvalidRequestError - Fix return type annotation in device_authorization.py All 13 type-check errors related to OAuth device flow are now fixed. Remaining 20 errors are pre-existing issues in storage backends. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add group_name and details parameters to StorageError base class to support error context across all storage backends - Add boto3-stubs as dev dependency for type annotations 0 errors, 0 warnings, 0 informations Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This was referenced Feb 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds support for CLI and device applications to authenticate without embedding a client secret.
Backend (campus)
ExpiredTokenError, AccessDeniedError
Resolves #353
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com