From 86b6f94b65cb3e821bab75439852afabfec78377 Mon Sep 17 00:00:00 2001 From: mo khan Date: Thu, 12 Jun 2025 09:59:14 -0600 Subject: feat: start to add support for refresh tokens --- REFACTORING_PLAN.md | 289 ---------------------------------------------------- 1 file changed, 289 deletions(-) delete mode 100644 REFACTORING_PLAN.md (limited to 'REFACTORING_PLAN.md') diff --git a/REFACTORING_PLAN.md b/REFACTORING_PLAN.md deleted file mode 100644 index ec24449..0000000 --- a/REFACTORING_PLAN.md +++ /dev/null @@ -1,289 +0,0 @@ -# OAuth2 STS SOLID Refactoring Plan - -## Overview -This document outlines refactoring opportunities to better align with SOLID principles. - -## 1. Extract Grant Type Handlers (SRP + OCP) - -### Current Issue -`OAuthServer::handle_token()` contains all grant type logic in one method. - -### Proposed Solution -```rust -trait GrantHandler { - fn can_handle(&self, grant_type: &str) -> bool; - fn handle_grant( - &self, - params: &HashMap, - auth_header: Option<&str>, - ip_address: Option, - ) -> Result; -} - -struct AuthorizationCodeGrantHandler { - client_authenticator: Arc, - token_generator: Arc, - code_repository: Arc, - token_repository: Arc, - audit_logger: Arc, -} - -struct RefreshTokenGrantHandler { - // Similar dependencies -} - -struct GrantHandlerRegistry { - handlers: Vec>, -} -``` - -### Benefits -- ✅ Easy to add new grant types (Client Credentials, Device Code, etc.) -- ✅ Each handler has single responsibility -- ✅ Testable in isolation - -## 2. Create Repository Abstractions (DIP + SRP) - -### Current Issue -Monolithic `Database` struct violates SRP and makes testing difficult. - -### Proposed Solution -```rust -trait ClientRepository { - fn get_client(&self, client_id: &str) -> Result>; - fn authenticate_client(&self, client_id: &str, secret: &str) -> Result; - fn is_redirect_uri_valid(&self, client_id: &str, uri: &str) -> bool; -} - -trait TokenRepository { - fn create_access_token(&self, token: &DbAccessToken) -> Result<()>; - fn get_access_token(&self, token_hash: &str) -> Result>; - fn revoke_access_token(&self, token_hash: &str) -> Result<()>; -} - -trait AuthCodeRepository { - fn create_auth_code(&self, code: &DbAuthCode) -> Result<()>; - fn get_auth_code(&self, code: &str) -> Result>; - fn mark_auth_code_used(&self, code: &str) -> Result<()>; -} - -// SQLite implementations -struct SqliteClientRepository { - database: Arc>, -} - -struct SqliteTokenRepository { - database: Arc>, -} -``` - -### Benefits -- ✅ Easy to swap database backends (PostgreSQL, Redis, etc.) -- ✅ Better testability with mock repositories -- ✅ Clear separation of concerns - -## 3. Extract Authentication Strategy (OCP + SRP) - -### Current Issue -Client authentication logic scattered throughout token handlers. - -### Proposed Solution -```rust -trait ClientAuthenticator { - fn authenticate( - &self, - params: &HashMap, - auth_header: Option<&str>, - ) -> Result<(String, String), String>; // Returns (client_id, client_secret) -} - -struct BasicAuthenticator { - client_repository: Arc, -} - -struct PostAuthenticator { - client_repository: Arc, -} - -struct CompositeAuthenticator { - authenticators: Vec>, -} -``` - -### Benefits -- ✅ Easy to add new authentication methods (JWT, mTLS, etc.) -- ✅ Clear separation of authentication concerns -- ✅ Configurable authentication strategies - -## 4. Extract Token Generation (SRP + OCP) - -### Current Issue -Token generation logic embedded in `OAuthServer`. - -### Proposed Solution -```rust -trait TokenGenerator { - fn generate_access_token( - &self, - user_id: &str, - client_id: &str, - scope: &Option, - token_id: &str, - ) -> Result; - - fn generate_refresh_token( - &self, - client_id: &str, - user_id: &str, - scope: &Option, - ) -> Result; -} - -struct JwtTokenGenerator { - key_manager: Arc>, - config: Config, -} - -struct OpaqueTokenGenerator { - // For opaque token implementation -} -``` - -### Benefits -- ✅ Easy to switch token formats (JWT vs opaque) -- ✅ Configurable token generation strategies -- ✅ Better testability - -## 5. Extract Cross-Cutting Concerns - -### Rate Limiting -```rust -trait RateLimiter { - fn check_rate_limit(&self, identifier: &str, endpoint: &str) -> Result<()>; -} - -struct DatabaseRateLimiter { - rate_repository: Arc, - config: Config, -} - -struct RedisRateLimiter { - redis_client: redis::Client, - config: Config, -} -``` - -### Audit Logging -```rust -trait AuditLogger { - fn log_event(&self, event: AuditEvent) -> Result<()>; -} - -struct DatabaseAuditLogger { - audit_repository: Arc, -} - -struct JsonFileAuditLogger { - file_path: PathBuf, -} -``` - -## 6. Refactor HTTP Layer (SRP) - -### Current Issue -`Server` mixes HTTP protocol with OAuth business logic. - -### Proposed Solution -```rust -struct HttpServer { - router: Router, - config: Config, -} - -struct Router { - oauth_handler: Arc, - static_handler: Arc, -} - -struct OAuthHandler { - oauth_service: Arc, // Renamed from OAuthServer -} - -// Clean separation between HTTP concerns and OAuth business logic -``` - -## 7. Dependency Injection Container - -### Proposed Solution -```rust -struct ServiceContainer { - // Repositories - client_repository: Arc, - token_repository: Arc, - auth_code_repository: Arc, - - // Services - client_authenticator: Arc, - token_generator: Arc, - rate_limiter: Arc, - audit_logger: Arc, - - // Grant handlers - grant_registry: Arc, -} - -impl ServiceContainer { - fn new(config: &Config) -> Result { - // Wire up all dependencies - } -} -``` - -## Implementation Strategy - -### Phase 1: Repository Extraction -1. Create repository traits -2. Move database methods to specific repositories -3. Update `OAuthServer` to use repositories - -### Phase 2: Grant Handler Extraction -1. Create `GrantHandler` trait -2. Extract authorization code handler -3. Extract refresh token handler -4. Create registry - -### Phase 3: Cross-Cutting Concerns -1. Extract rate limiting -2. Extract audit logging -3. Extract authentication - -### Phase 4: HTTP Layer Cleanup -1. Separate HTTP protocol from business logic -2. Create clean request/response handlers - -### Phase 5: Dependency Injection -1. Create service container -2. Wire up all dependencies -3. Update main.rs to use container - -## Benefits of This Refactoring - -### Maintainability -- ✅ Easier to understand and modify individual components -- ✅ Clear separation of concerns -- ✅ Reduced coupling between components - -### Extensibility -- ✅ Easy to add new grant types -- ✅ Easy to swap implementations (database, token format, etc.) -- ✅ Configurable strategies for cross-cutting concerns - -### Testability -- ✅ Each component can be tested in isolation -- ✅ Easy to create mock implementations -- ✅ Better unit test coverage - -### Production Readiness -- ✅ Easy to scale different components independently -- ✅ Better observability and monitoring capabilities -- ✅ More flexible deployment options \ No newline at end of file -- cgit v1.2.3