# Technical Specification: OAuth2 Controllers (Phase 6.4) ## Overview This document provides the implementation blueprint for OAuth2 controllers in the Configurable Mock API application. The implementation follows the existing Repository-Service-Controller pattern and integrates with the admin interface. ## 1. File Structure ### New Files - `oauth2/controller.py` – OAuth2 standard endpoints (RFC 6749, 7662, 7009, OIDC) - `oauth2/auth_code_store.py` – In‑memory storage for authorization codes - `templates/admin/oauth_clients.html` – List OAuth clients - `templates/admin/oauth_client_form.html` – Create/edit client form - `templates/admin/oauth_tokens.html` – List OAuth tokens - `templates/admin/oauth_users.html` – List OAuth users (optional) - `templates/oauth/authorize_consent.html` – Authorization consent page ### Modified Files - `controllers/admin_controller.py` – Add admin OAuth2 management routes under `/admin/oauth` - `config.py` – Add OAuth2 configuration settings - `app.py` – Include OAuth2 router ## 2. OAuth2 Standard Endpoints ### Router: `/oauth` | Endpoint | Method | Purpose | |----------|--------|---------| | `/oauth/authorize` | GET | Display consent screen | | `/oauth/authorize` | POST | Process consent | | `/oauth/token` | POST | Issue tokens (all grant types) | | `/oauth/userinfo` | GET | Return user claims (OpenID Connect) | | `/oauth/introspect` | POST | Token introspection (RFC 7662) | | `/oauth/revoke` | POST | Token revocation (RFC 7009) | | `/.well-known/openid-configuration` | GET | OIDC discovery metadata | ### Dependencies - Database session: `Depends(get_db)` - Token validation: `get_current_token_payload` (for userinfo) - Client authentication: HTTP Basic for introspection/revocation ## 3. Admin OAuth2 Management Endpoints ### Router: `/admin/oauth` | Endpoint | Method | Purpose | |----------|--------|---------| | `/admin/oauth/clients` | GET | List clients (paginated) | | `/admin/oauth/clients/new` | GET | Create client form | | `/admin/oauth/clients` | POST | Create client | | `/admin/oauth/clients/{client_id}/edit` | GET | Edit client form | | `/admin/oauth/clients/{client_id}` | POST | Update client | | `/admin/oauth/clients/{client_id}/delete` | POST | Deactivate client | | `/admin/oauth/tokens` | GET | List tokens with filters | | `/admin/oauth/tokens/{token_id}/revoke` | POST | Revoke token | | `/admin/oauth/users` | GET | List users (optional) | ### Authentication - Protected by existing `AuthMiddleware` (session‑based). ## 4. Configuration Additions (`config.py`) ```python # Add to Settings class oauth2_issuer: str = "http://localhost:8000" oauth2_access_token_expire_minutes: int = 30 oauth2_refresh_token_expire_days: int = 7 oauth2_authorization_code_expire_minutes: int = 10 oauth2_supported_grant_types: List[str] = [ "authorization_code", "client_credentials", "refresh_token", ] oauth2_supported_scopes: List[str] = [ "openid", "profile", "email", "api:read", "api:write" ] ``` ## 5. Authorization Code Store Create `oauth2/auth_code_store.py` with an in‑memory dictionary protected by `asyncio.Lock`. Store authorization codes with expiration (datetime). Provide methods: - `store_code(code: str, data: dict)` - `get_code(code: str) -> Optional[dict]` - `delete_code(code: str)` ## 6. Template Requirements All admin templates extend `base.html` and use Bootstrap 5 styling. - **oauth_clients.html**: Table with columns: Client ID, Name, Grant Types, Redirect URIs, Active, Actions. - **oauth_client_form.html**: Form fields: client_id, client_secret (plaintext), name, redirect_uris (newline‑separated), grant_types (checkboxes), scopes (newline‑separated), is_active (checkbox). - **oauth_tokens.html**: Table with columns: Access Token (truncated), Client, User, Scopes, Expires, Active, Revoke button. - **authorize_consent.html**: Simple page showing client name, requested scopes, Allow/Deny buttons. ## 7. Integration with Existing Code - Use existing `OAuthService`, `TokenService`, `ClientService`, `ScopeService`. - Use `OAuthClientRepository`, `OAuthTokenRepository`, `OAuthUserRepository`. - Update `app.py` to include OAuth2 router after admin router. ## 8. Security Considerations - Validate redirect_uri exactly (including query parameters). - Hash client secrets with bcrypt (already implemented). - Implement token revocation by deletion from database. - Use `state` parameter for CSRF protection in authorization flow. - Log all authentication failures. ## 9. Implementation Steps for @coder 1. **Create authorization code store** (`oauth2/auth_code_store.py`). 2. **Implement OAuth2 controller** (`oauth2/controller.py`) with all endpoints. 3. **Extend admin controller** (`controllers/admin_controller.py`) with OAuth2 management routes. 4. **Create HTML templates** in `templates/admin/` and `templates/oauth/`. 5. **Update configuration** (`config.py`) with OAuth2 settings. 6. **Update app** (`app.py`) to include OAuth2 router. 7. **Test** with curl/Postman and verify admin pages. ## 10. Example Code Snippets ### OAuth2 Controller Example ```python # oauth2/controller.py @router.post("/token") async def token_endpoint( grant_type: str = Form(...), client_id: Optional[str] = Form(None), client_secret: Optional[str] = Form(None), code: Optional[str] = Form(None), redirect_uri: Optional[str] = Form(None), refresh_token: Optional[str] = Form(None), scope: Optional[str] = Form(None), db: AsyncSession = Depends(get_db), ): oauth_service = OAuthService(db) if grant_type == "authorization_code": # validate code, redirect_uri pass # ... ``` ### Admin Controller Example ```python # controllers/admin_controller.py @router.get("/oauth/clients", response_class=HTMLResponse) async def list_oauth_clients( request: Request, page: int = 1, db: AsyncSession = Depends(get_db), ): repo = OAuthClientRepository(db) clients = await repo.get_all(skip=(page-1)*PAGE_SIZE, limit=PAGE_SIZE) # render template ``` ## 11. Next Steps (Phase 6.5) - Update `PROJECT_PLAN.md` with completed items. - Write integration tests for OAuth2 flows. - Consider adding PKCE support (optional). --- **Approval Required**: Please review this specification before implementation begins. Any changes should be documented in `PROJECT_PLAN.md`.