auth_framework/
errors.rs

1//! Error types for the authentication framework.
2
3use thiserror::Error;
4
5/// Result type alias for the authentication framework.
6pub type Result<T> = std::result::Result<T, AuthError>;
7
8/// Main error type for the authentication framework.
9#[derive(Error, Debug)]
10pub enum AuthError {
11    /// Configuration errors
12    #[error("Configuration error: {message}")]
13    Configuration { message: String },
14
15    /// Authentication method errors
16    #[error("Authentication method '{method}' error: {message}")]
17    AuthMethod { method: String, message: String },
18
19    /// Token-related errors
20    #[error("Token error: {0}")]
21    Token(#[from] TokenError),
22
23    /// Permission-related errors
24    #[error("Permission error: {0}")]
25    Permission(#[from] PermissionError),
26
27    /// Storage-related errors
28    #[error("Storage error: {0}")]
29    Storage(#[from] StorageError),
30
31    /// Network/HTTP errors
32    #[error("Network error: {0}")]
33    Network(#[from] reqwest::Error),
34
35    /// JSON parsing errors
36    #[error("JSON error: {0}")]
37    Json(#[from] serde_json::Error),
38
39    /// JWT errors
40    #[error("JWT error: {0}")]
41    Jwt(#[from] jsonwebtoken::errors::Error),
42
43    /// Rate limiting errors
44    #[error("Rate limit exceeded: {message}")]
45    RateLimit { message: String },
46
47    /// MFA-related errors
48    #[error("MFA error: {0}")]
49    Mfa(#[from] MfaError),
50
51    /// Device flow errors
52    #[error("Device flow error: {0}")]
53    DeviceFlow(#[from] DeviceFlowError),
54
55    /// OAuth provider errors
56    #[error("OAuth provider error: {0}")]
57    OAuthProvider(#[from] OAuthProviderError),
58
59    /// User profile errors
60    #[error("User profile error: {message}")]
61    UserProfile { message: String },
62
63    /// Credential validation errors
64    #[error("Invalid credential: {credential_type} - {message}")]
65    InvalidCredential { credential_type: String, message: String },
66
67    /// Authentication timeout
68    #[error("Authentication timeout after {timeout_seconds} seconds")]
69    Timeout { timeout_seconds: u64 },
70
71    /// Provider configuration missing
72    #[error("Provider '{provider}' is not configured or supported")]
73    ProviderNotConfigured { provider: String },
74
75    /// Cryptography errors
76    #[error("Cryptography error: {message}")]
77    Crypto { message: String },
78
79    /// Validation errors
80    #[error("Validation error: {message}")]
81    Validation { message: String },
82
83    /// Generic internal errors
84    #[error("Internal error: {message}")]
85    Internal { message: String },
86}
87
88/// Token-specific errors
89#[derive(Error, Debug)]
90pub enum TokenError {
91    #[error("Token has expired")]
92    Expired,
93
94    #[error("Token is invalid")]
95    Invalid { message: String },
96
97    #[error("Token not found")]
98    NotFound,
99
100    #[error("Token creation failed: {message}")]
101    CreationFailed { message: String },
102
103    #[error("Token refresh failed: {message}")]
104    RefreshFailed { message: String },
105
106    #[error("Token revocation failed: {message}")]
107    RevocationFailed { message: String },
108}
109
110/// Permission-specific errors
111#[derive(Error, Debug)]
112pub enum PermissionError {
113    #[error("Access denied: missing permission '{permission}' for resource '{resource}'")]
114    AccessDenied { permission: String, resource: String },
115
116    #[error("Role '{role}' not found")]
117    RoleNotFound { role: String },
118
119    #[error("Permission '{permission}' not found")]
120    PermissionNotFound { permission: String },
121
122    #[error("Invalid permission format: {message}")]
123    InvalidFormat { message: String },
124
125    #[error("Permission denied: {message}")]
126    Denied { action: String, resource: String, message: String },
127}
128
129/// Storage-specific errors
130#[derive(Error, Debug)]
131pub enum StorageError {
132    #[error("Connection failed: {message}")]
133    ConnectionFailed { message: String },
134
135    #[error("Operation failed: {message}")]
136    OperationFailed { message: String },
137
138    #[error("Serialization error: {message}")]
139    Serialization { message: String },
140
141    #[error("Storage backend not available")]
142    BackendUnavailable,
143}
144
145/// MFA-specific errors
146#[derive(Error, Debug)]
147pub enum MfaError {
148    #[error("MFA challenge expired")]
149    ChallengeExpired,
150
151    #[error("Invalid MFA code")]
152    InvalidCode,
153
154    #[error("MFA method not supported: {method}")]
155    MethodNotSupported { method: String },
156
157    #[error("MFA setup required")]
158    SetupRequired,
159
160    #[error("MFA verification failed: {message}")]
161    VerificationFailed { message: String },
162}
163
164/// Device flow specific errors
165#[derive(Error, Debug)]
166pub enum DeviceFlowError {
167    #[error("Authorization pending - user has not yet completed authorization")]
168    AuthorizationPending,
169    
170    #[error("Slow down - polling too frequently")]
171    SlowDown,
172    
173    #[error("Device code expired")]
174    ExpiredToken,
175    
176    #[error("Access denied by user")]
177    AccessDenied,
178    
179    #[error("Invalid device code")]
180    InvalidDeviceCode,
181    
182    #[error("Unsupported grant type")]
183    UnsupportedGrantType,
184}
185
186/// OAuth provider specific errors
187#[derive(Error, Debug)]
188pub enum OAuthProviderError {
189    #[error("Invalid authorization code")]
190    InvalidAuthorizationCode,
191    
192    #[error("Invalid redirect URI")]
193    InvalidRedirectUri,
194    
195    #[error("Invalid client credentials")]
196    InvalidClientCredentials,
197    
198    #[error("Insufficient scope: required '{required}', granted '{granted}'")]
199    InsufficientScope { required: String, granted: String },
200    
201    #[error("Provider '{provider}' does not support '{feature}'")]
202    UnsupportedFeature { provider: String, feature: String },
203    
204    #[error("Rate limited by provider: {message}")]
205    RateLimited { message: String },
206}
207
208impl AuthError {
209    /// Create a new configuration error
210    pub fn config(message: impl Into<String>) -> Self {
211        Self::Configuration {
212            message: message.into(),
213        }
214    }
215
216    /// Create a new auth method error
217    pub fn auth_method(method: impl Into<String>, message: impl Into<String>) -> Self {
218        Self::AuthMethod {
219            method: method.into(),
220            message: message.into(),
221        }
222    }
223
224    /// Create a new rate limit error
225    pub fn rate_limit(message: impl Into<String>) -> Self {
226        Self::RateLimit {
227            message: message.into(),
228        }
229    }
230
231    /// Create a new crypto error
232    pub fn crypto(message: impl Into<String>) -> Self {
233        Self::Crypto {
234            message: message.into(),
235        }
236    }
237
238    /// Create a new validation error
239    pub fn validation(message: impl Into<String>) -> Self {
240        Self::Validation {
241            message: message.into(),
242        }
243    }
244
245    /// Create a new internal error
246    pub fn internal(message: impl Into<String>) -> Self {
247        Self::Internal {
248            message: message.into(),
249        }
250    }
251
252    /// Create an access denied error
253    pub fn access_denied(message: impl Into<String>) -> Self {
254        Self::Permission(PermissionError::Denied {
255            action: "access".to_string(),
256            resource: "resource".to_string(),
257            message: message.into(),
258        })
259    }
260
261    /// Create a token error
262    pub fn token(message: impl Into<String>) -> Self {
263        Self::Token(TokenError::Invalid {
264            message: message.into(),
265        })
266    }
267
268    /// Create a device flow error
269    pub fn device_flow(error: DeviceFlowError) -> Self {
270        Self::DeviceFlow(error)
271    }
272    
273    /// Create an OAuth provider error
274    pub fn oauth_provider(error: OAuthProviderError) -> Self {
275        Self::OAuthProvider(error)
276    }
277    
278    /// Create a user profile error
279    pub fn user_profile(message: impl Into<String>) -> Self {
280        Self::UserProfile {
281            message: message.into(),
282        }
283    }
284    
285    /// Create an invalid credential error
286    pub fn invalid_credential(credential_type: impl Into<String>, message: impl Into<String>) -> Self {
287        Self::InvalidCredential {
288            credential_type: credential_type.into(),
289            message: message.into(),
290        }
291    }
292    
293    /// Create a timeout error
294    pub fn timeout(timeout_seconds: u64) -> Self {
295        Self::Timeout { timeout_seconds }
296    }
297    
298    /// Create a provider not configured error
299    pub fn provider_not_configured(provider: impl Into<String>) -> Self {
300        Self::ProviderNotConfigured {
301            provider: provider.into(),
302        }
303    }
304}
305
306impl TokenError {
307    /// Create a new token creation failed error
308    pub fn creation_failed(message: impl Into<String>) -> Self {
309        Self::CreationFailed {
310            message: message.into(),
311        }
312    }
313
314    /// Create a new token refresh failed error
315    pub fn refresh_failed(message: impl Into<String>) -> Self {
316        Self::RefreshFailed {
317            message: message.into(),
318        }
319    }
320
321    /// Create a new token revocation failed error
322    pub fn revocation_failed(message: impl Into<String>) -> Self {
323        Self::RevocationFailed {
324            message: message.into(),
325        }
326    }
327}
328
329impl PermissionError {
330    /// Create a new access denied error
331    pub fn access_denied(permission: impl Into<String>, resource: impl Into<String>) -> Self {
332        Self::AccessDenied {
333            permission: permission.into(),
334            resource: resource.into(),
335        }
336    }
337
338    /// Create a new role not found error
339    pub fn role_not_found(role: impl Into<String>) -> Self {
340        Self::RoleNotFound {
341            role: role.into(),
342        }
343    }
344
345    /// Create a new permission not found error
346    pub fn permission_not_found(permission: impl Into<String>) -> Self {
347        Self::PermissionNotFound {
348            permission: permission.into(),
349        }
350    }
351
352    /// Create a new invalid format error
353    pub fn invalid_format(message: impl Into<String>) -> Self {
354        Self::InvalidFormat {
355            message: message.into(),
356        }
357    }
358}
359
360impl StorageError {
361    /// Create a new connection failed error
362    pub fn connection_failed(message: impl Into<String>) -> Self {
363        Self::ConnectionFailed {
364            message: message.into(),
365        }
366    }
367
368    /// Create a new operation failed error
369    pub fn operation_failed(message: impl Into<String>) -> Self {
370        Self::OperationFailed {
371            message: message.into(),
372        }
373    }
374
375    /// Create a new serialization error
376    pub fn serialization(message: impl Into<String>) -> Self {
377        Self::Serialization {
378            message: message.into(),
379        }
380    }
381}
382
383impl MfaError {
384    /// Create a new method not supported error
385    pub fn method_not_supported(method: impl Into<String>) -> Self {
386        Self::MethodNotSupported {
387            method: method.into(),
388        }
389    }
390
391    /// Create a new verification failed error
392    pub fn verification_failed(message: impl Into<String>) -> Self {
393        Self::VerificationFailed {
394            message: message.into(),
395        }
396    }
397}