mockapi/docs/TECH_SPEC_OAUTH2_CONTROLLERS.md
2026-03-16 10:49:01 +00:00

6.2 KiB
Raw Blame History

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 Inmemory 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 (sessionbased).

4. Configuration Additions (config.py)

# 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 inmemory 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 (newlineseparated), grant_types (checkboxes), scopes (newlineseparated), 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

# 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

# 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.