auth_framework/
config.rs

1//! Configuration types for the authentication framework.
2
3use crate::errors::{AuthError, Result};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::time::Duration;
7
8/// Main configuration for the authentication framework.
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct AuthConfig {
11    /// Default token lifetime
12    pub token_lifetime: Duration,
13    
14    /// Refresh token lifetime
15    pub refresh_token_lifetime: Duration,
16    
17    /// Whether multi-factor authentication is enabled
18    pub enable_multi_factor: bool,
19    
20    /// Storage configuration
21    pub storage: StorageConfig,
22    
23    /// Rate limiting configuration
24    pub rate_limiting: RateLimitConfig,
25    
26    /// Security configuration
27    pub security: SecurityConfig,
28    
29    /// Audit logging configuration
30    pub audit: AuditConfig,
31    
32    /// Custom settings for different auth methods
33    pub method_configs: HashMap<String, serde_json::Value>,
34}
35
36/// Storage configuration options.
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub enum StorageConfig {
39    /// In-memory storage (not recommended for production)
40    Memory,
41    
42    /// Redis storage
43    #[cfg(feature = "redis-storage")]
44    Redis {
45        url: String,
46        key_prefix: String,
47    },
48    
49    /// PostgreSQL storage
50    #[cfg(feature = "postgres-storage")]
51    Postgres {
52        connection_string: String,
53        table_prefix: String,
54    },
55    
56    /// MySQL storage
57    #[cfg(feature = "mysql-storage")]
58    MySQL {
59        connection_string: String,
60        table_prefix: String,
61    },
62    
63    /// Custom storage backend
64    Custom(String),
65}
66
67/// Rate limiting configuration.
68#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct RateLimitConfig {
70    /// Enable rate limiting
71    pub enabled: bool,
72    
73    /// Maximum requests per window
74    pub max_requests: u32,
75    
76    /// Time window for rate limiting
77    pub window: Duration,
78    
79    /// Burst allowance
80    pub burst: u32,
81}
82
83/// Security configuration options.
84#[derive(Debug, Clone, Serialize, Deserialize)]
85pub struct SecurityConfig {
86    /// Minimum password length
87    pub min_password_length: usize,
88    
89    /// Require password complexity
90    pub require_password_complexity: bool,
91    
92    /// Password hash algorithm
93    pub password_hash_algorithm: PasswordHashAlgorithm,
94    
95    /// JWT signing algorithm
96    pub jwt_algorithm: JwtAlgorithm,
97    
98    /// Secret key for signing (should be loaded from environment)
99    pub secret_key: Option<String>,
100    
101    /// Enable secure cookies
102    pub secure_cookies: bool,
103    
104    /// Cookie SameSite policy
105    pub cookie_same_site: CookieSameSite,
106    
107    /// CSRF protection
108    pub csrf_protection: bool,
109    
110    /// Session timeout
111    pub session_timeout: Duration,
112}
113
114/// Password hashing algorithms.
115#[derive(Debug, Clone, Serialize, Deserialize)]
116pub enum PasswordHashAlgorithm {
117    Argon2,
118    Bcrypt,
119    Scrypt,
120}
121
122/// JWT signing algorithms.
123#[derive(Debug, Clone, Serialize, Deserialize)]
124pub enum JwtAlgorithm {
125    HS256,
126    HS384,
127    HS512,
128    RS256,
129    RS384,
130    RS512,
131    ES256,
132    ES384,
133}
134
135/// Cookie SameSite policies.
136#[derive(Debug, Clone, Serialize, Deserialize)]
137pub enum CookieSameSite {
138    Strict,
139    Lax,
140    None,
141}
142
143/// Audit logging configuration.
144#[derive(Debug, Clone, Serialize, Deserialize)]
145pub struct AuditConfig {
146    /// Enable audit logging
147    pub enabled: bool,
148    
149    /// Log successful authentications
150    pub log_success: bool,
151    
152    /// Log failed authentications
153    pub log_failures: bool,
154    
155    /// Log permission checks
156    pub log_permissions: bool,
157    
158    /// Log token operations
159    pub log_tokens: bool,
160    
161    /// Audit log storage
162    pub storage: AuditStorage,
163}
164
165/// Audit log storage options.
166#[derive(Debug, Clone, Serialize, Deserialize)]
167pub enum AuditStorage {
168    /// Standard logging (via tracing)
169    Tracing,
170    
171    /// File-based storage
172    File { path: String },
173    
174    /// Database storage
175    Database { connection_string: String },
176    
177    /// External service
178    External { endpoint: String, api_key: String },
179}
180
181impl Default for AuthConfig {
182    fn default() -> Self {
183        Self {
184            token_lifetime: Duration::from_secs(3600), // 1 hour
185            refresh_token_lifetime: Duration::from_secs(86400 * 7), // 7 days
186            enable_multi_factor: false,
187            storage: StorageConfig::Memory,
188            rate_limiting: RateLimitConfig::default(),
189            security: SecurityConfig::default(),
190            audit: AuditConfig::default(),
191            method_configs: HashMap::new(),
192        }
193    }
194}
195
196impl Default for RateLimitConfig {
197    fn default() -> Self {
198        Self {
199            enabled: true,
200            max_requests: 100,
201            window: Duration::from_secs(60), // 1 minute
202            burst: 10,
203        }
204    }
205}
206
207impl Default for SecurityConfig {
208    fn default() -> Self {
209        Self {
210            min_password_length: 8,
211            require_password_complexity: true,
212            password_hash_algorithm: PasswordHashAlgorithm::Argon2,
213            jwt_algorithm: JwtAlgorithm::HS256,
214            secret_key: None,
215            secure_cookies: true,
216            cookie_same_site: CookieSameSite::Lax,
217            csrf_protection: true,
218            session_timeout: Duration::from_secs(3600 * 24), // 24 hours
219        }
220    }
221}
222
223impl Default for AuditConfig {
224    fn default() -> Self {
225        Self {
226            enabled: true,
227            log_success: true,
228            log_failures: true,
229            log_permissions: true,
230            log_tokens: false, // Tokens can be sensitive
231            storage: AuditStorage::Tracing,
232        }
233    }
234}
235
236impl AuthConfig {
237    /// Create a new configuration with default values.
238    pub fn new() -> Self {
239        Self::default()
240    }
241
242    /// Set the token lifetime.
243    pub fn token_lifetime(mut self, lifetime: Duration) -> Self {
244        self.token_lifetime = lifetime;
245        self
246    }
247
248    /// Set the refresh token lifetime.
249    pub fn refresh_token_lifetime(mut self, lifetime: Duration) -> Self {
250        self.refresh_token_lifetime = lifetime;
251        self
252    }
253
254    /// Enable or disable multi-factor authentication.
255    pub fn enable_multi_factor(mut self, enabled: bool) -> Self {
256        self.enable_multi_factor = enabled;
257        self
258    }
259
260    /// Require MFA for all users.
261    pub fn require_mfa(mut self, required: bool) -> Self {
262        self.enable_multi_factor = required;
263        self
264    }
265
266    /// Enable caching.
267    pub fn enable_caching(self, _enabled: bool) -> Self {
268        // This would set a caching flag in a real implementation
269        self
270    }
271
272    /// Set maximum failed attempts.
273    pub fn max_failed_attempts(self, _max: u32) -> Self {
274        // This would set max failed attempts in security config
275        self
276    }
277
278    /// Enable RBAC.
279    pub fn enable_rbac(self, _enabled: bool) -> Self {
280        // This would enable role-based access control
281        self
282    }
283
284    /// Enable security audit.
285    pub fn enable_security_audit(self, _enabled: bool) -> Self {
286        // This would enable security auditing
287        self
288    }
289
290    /// Enable middleware.
291    pub fn enable_middleware(self, _enabled: bool) -> Self {
292        // This would enable middleware support
293        self
294    }
295
296    /// Set the storage configuration.
297    pub fn storage(mut self, storage: StorageConfig) -> Self {
298        self.storage = storage;
299        self
300    }
301
302    /// Configure Redis storage.
303    #[cfg(feature = "redis-storage")]
304    pub fn redis_storage(mut self, url: impl Into<String>) -> Self {
305        self.storage = StorageConfig::Redis {
306            url: url.into(),
307            key_prefix: "auth:".to_string(),
308        };
309        self
310    }
311
312    /// Set rate limiting configuration.
313    pub fn rate_limiting(mut self, config: RateLimitConfig) -> Self {
314        self.rate_limiting = config;
315        self
316    }
317
318    /// Set security configuration.
319    pub fn security(mut self, config: SecurityConfig) -> Self {
320        self.security = config;
321        self
322    }
323
324    /// Set audit configuration.
325    pub fn audit(mut self, config: AuditConfig) -> Self {
326        self.audit = config;
327        self
328    }
329
330    /// Add configuration for a specific auth method.
331    pub fn method_config(
332        mut self,
333        method_name: impl Into<String>,
334        config: impl Serialize,
335    ) -> Result<Self> {
336        let value = serde_json::to_value(config)
337            .map_err(|e| AuthError::config(format!("Failed to serialize method config: {e}")))?;
338        
339        self.method_configs.insert(method_name.into(), value);
340        Ok(self)
341    }
342
343    /// Get configuration for a specific auth method.
344    pub fn get_method_config<T>(&self, method_name: &str) -> Result<Option<T>>
345    where
346        T: for<'de> Deserialize<'de>,
347    {
348        if let Some(value) = self.method_configs.get(method_name) {
349            let config = serde_json::from_value(value.clone())
350                .map_err(|e| AuthError::config(format!("Failed to deserialize method config: {e}")))?;
351            Ok(Some(config))
352        } else {
353            Ok(None)
354        }
355    }
356
357    /// Validate the configuration.
358    pub fn validate(&self) -> Result<()> {
359        // Validate token lifetimes
360        if self.token_lifetime.as_secs() == 0 {
361            return Err(AuthError::config("Token lifetime must be greater than 0"));
362        }
363
364        if self.refresh_token_lifetime.as_secs() == 0 {
365            return Err(AuthError::config("Refresh token lifetime must be greater than 0"));
366        }
367
368        if self.refresh_token_lifetime <= self.token_lifetime {
369            return Err(AuthError::config(
370                "Refresh token lifetime must be greater than token lifetime"
371            ));
372        }
373
374        // Validate security settings
375        if self.security.min_password_length < 4 {
376            return Err(AuthError::config(
377                "Minimum password length must be at least 4 characters"
378            ));
379        }
380
381        // Validate rate limiting
382        if self.rate_limiting.enabled && self.rate_limiting.max_requests == 0 {
383            return Err(AuthError::config(
384                "Rate limit max requests must be greater than 0 when enabled"
385            ));
386        }
387
388        Ok(())
389    }
390}
391
392impl RateLimitConfig {
393    /// Create a new rate limit configuration.
394    pub fn new(max_requests: u32, window: Duration) -> Self {
395        Self {
396            enabled: true,
397            max_requests,
398            window,
399            burst: max_requests / 10, // 10% of max as burst
400        }
401    }
402
403    /// Disable rate limiting.
404    pub fn disabled() -> Self {
405        Self {
406            enabled: false,
407            ..Default::default()
408        }
409    }
410}
411
412impl SecurityConfig {
413    /// Create a new security configuration with secure defaults.
414    pub fn secure() -> Self {
415        Self {
416            min_password_length: 12,
417            require_password_complexity: true,
418            password_hash_algorithm: PasswordHashAlgorithm::Argon2,
419            jwt_algorithm: JwtAlgorithm::RS256,
420            secret_key: None,
421            secure_cookies: true,
422            cookie_same_site: CookieSameSite::Strict,
423            csrf_protection: true,
424            session_timeout: Duration::from_secs(3600 * 8), // 8 hours
425        }
426    }
427
428    /// Create a development-friendly configuration.
429    pub fn development() -> Self {
430        Self {
431            min_password_length: 6,
432            require_password_complexity: false,
433            password_hash_algorithm: PasswordHashAlgorithm::Bcrypt,
434            jwt_algorithm: JwtAlgorithm::HS256,
435            secret_key: Some("development-secret-key".to_string()),
436            secure_cookies: false,
437            cookie_same_site: CookieSameSite::Lax,
438            csrf_protection: false,
439            session_timeout: Duration::from_secs(3600 * 24), // 24 hours
440        }
441    }
442}