summaryrefslogtreecommitdiff
path: root/REFACTORING_PLAN.md
diff options
context:
space:
mode:
Diffstat (limited to 'REFACTORING_PLAN.md')
-rw-r--r--REFACTORING_PLAN.md289
1 files changed, 289 insertions, 0 deletions
diff --git a/REFACTORING_PLAN.md b/REFACTORING_PLAN.md
new file mode 100644
index 0000000..ec24449
--- /dev/null
+++ b/REFACTORING_PLAN.md
@@ -0,0 +1,289 @@
+# 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<String, String>,
+ auth_header: Option<&str>,
+ ip_address: Option<String>,
+ ) -> Result<String, String>;
+}
+
+struct AuthorizationCodeGrantHandler {
+ client_authenticator: Arc<dyn ClientAuthenticator>,
+ token_generator: Arc<dyn TokenGenerator>,
+ code_repository: Arc<dyn AuthCodeRepository>,
+ token_repository: Arc<dyn TokenRepository>,
+ audit_logger: Arc<dyn AuditLogger>,
+}
+
+struct RefreshTokenGrantHandler {
+ // Similar dependencies
+}
+
+struct GrantHandlerRegistry {
+ handlers: Vec<Arc<dyn GrantHandler>>,
+}
+```
+
+### 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<Option<OAuthClient>>;
+ fn authenticate_client(&self, client_id: &str, secret: &str) -> Result<bool>;
+ 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<Option<DbAccessToken>>;
+ 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<Option<DbAuthCode>>;
+ fn mark_auth_code_used(&self, code: &str) -> Result<()>;
+}
+
+// SQLite implementations
+struct SqliteClientRepository {
+ database: Arc<Mutex<Database>>,
+}
+
+struct SqliteTokenRepository {
+ database: Arc<Mutex<Database>>,
+}
+```
+
+### 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<String, String>,
+ auth_header: Option<&str>,
+ ) -> Result<(String, String), String>; // Returns (client_id, client_secret)
+}
+
+struct BasicAuthenticator {
+ client_repository: Arc<dyn ClientRepository>,
+}
+
+struct PostAuthenticator {
+ client_repository: Arc<dyn ClientRepository>,
+}
+
+struct CompositeAuthenticator {
+ authenticators: Vec<Arc<dyn ClientAuthenticator>>,
+}
+```
+
+### 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<String>,
+ token_id: &str,
+ ) -> Result<String>;
+
+ fn generate_refresh_token(
+ &self,
+ client_id: &str,
+ user_id: &str,
+ scope: &Option<String>,
+ ) -> Result<String>;
+}
+
+struct JwtTokenGenerator {
+ key_manager: Arc<Mutex<KeyManager>>,
+ 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<dyn RateRepository>,
+ 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<dyn AuditRepository>,
+}
+
+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<OAuthHandler>,
+ static_handler: Arc<StaticHandler>,
+}
+
+struct OAuthHandler {
+ oauth_service: Arc<OAuthService>, // 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<dyn ClientRepository>,
+ token_repository: Arc<dyn TokenRepository>,
+ auth_code_repository: Arc<dyn AuthCodeRepository>,
+
+ // Services
+ client_authenticator: Arc<dyn ClientAuthenticator>,
+ token_generator: Arc<dyn TokenGenerator>,
+ rate_limiter: Arc<dyn RateLimiter>,
+ audit_logger: Arc<dyn AuditLogger>,
+
+ // Grant handlers
+ grant_registry: Arc<GrantHandlerRegistry>,
+}
+
+impl ServiceContainer {
+ fn new(config: &Config) -> Result<Self> {
+ // 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