Skip to main content

modkit_auth/
claims_error.rs

1use thiserror::Error;
2
3/// Errors that can occur during JWT claims validation and processing
4#[derive(Debug, Error)]
5pub enum ClaimsError {
6    #[error("Invalid signature or key")]
7    InvalidSignature,
8
9    #[error("Invalid issuer: expected one of {expected:?}, got {actual}")]
10    InvalidIssuer {
11        expected: Vec<String>,
12        actual: String,
13    },
14
15    #[error("Invalid audience: expected one of {expected:?}, got {actual:?}")]
16    InvalidAudience {
17        expected: Vec<String>,
18        actual: Vec<String>,
19    },
20
21    #[error("Token expired")]
22    Expired,
23
24    #[error("Token not yet valid (nbf check failed)")]
25    NotYetValid,
26
27    #[error("Malformed claims: {0}")]
28    Malformed(String),
29
30    #[error("Provider error: {0}")]
31    Provider(String),
32
33    #[error("Missing required claim: {0}")]
34    MissingClaim(String),
35
36    #[error("Invalid claim format: {field} - {reason}")]
37    InvalidClaimFormat { field: String, reason: String },
38
39    #[error("Unknown key ID after refresh")]
40    UnknownKidAfterRefresh,
41
42    #[error("JWT decode failed: {0}")]
43    DecodeFailed(String),
44
45    #[error("JWKS fetch failed: {0}")]
46    JwksFetchFailed(String),
47
48    #[error("Unknown key ID: {0}")]
49    UnknownKeyId(String),
50}
51
52// Conversion from ClaimsError to AuthError for backward compatibility
53impl From<ClaimsError> for crate::errors::AuthError {
54    fn from(err: ClaimsError) -> Self {
55        match err {
56            ClaimsError::Expired => crate::errors::AuthError::TokenExpired,
57            ClaimsError::InvalidSignature => {
58                crate::errors::AuthError::InvalidToken("Invalid signature".into())
59            }
60            ClaimsError::InvalidIssuer { expected, actual } => {
61                crate::errors::AuthError::IssuerMismatch {
62                    expected: expected.join(", "),
63                    actual,
64                }
65            }
66            ClaimsError::InvalidAudience { expected, actual } => {
67                crate::errors::AuthError::AudienceMismatch { expected, actual }
68            }
69            ClaimsError::JwksFetchFailed(msg) => crate::errors::AuthError::JwksFetchFailed(msg),
70            other => crate::errors::AuthError::ValidationFailed(other.to_string()),
71        }
72    }
73}