Skip to main content

quarlus_security/
error.rs

1use quarlus_core::http::response::{IntoResponse, Response};
2use quarlus_core::http::StatusCode;
3
4/// Security-related errors for JWT validation and authentication.
5#[derive(Debug)]
6pub enum SecurityError {
7    /// The Authorization header is missing from the request.
8    MissingAuthHeader,
9
10    /// The authorization scheme is not "Bearer".
11    InvalidAuthScheme,
12
13    /// The JWT token is invalid (malformed, bad signature, etc.).
14    InvalidToken(String),
15
16    /// The JWT token has expired.
17    TokenExpired,
18
19    /// The key ID (kid) from the JWT header is not found in the JWKS.
20    UnknownKeyId(String),
21
22    /// Failed to fetch the JWKS from the remote endpoint.
23    JwksFetchError(String),
24
25    /// Token validation failed (issuer, audience, or other claim mismatch).
26    ValidationFailed(String),
27}
28
29impl std::fmt::Display for SecurityError {
30    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31        match self {
32            SecurityError::MissingAuthHeader => write!(f, "Missing Authorization header"),
33            SecurityError::InvalidAuthScheme => write!(f, "Invalid authorization scheme"),
34            SecurityError::InvalidToken(msg) => write!(f, "Invalid token: {msg}"),
35            SecurityError::TokenExpired => write!(f, "Token expired"),
36            SecurityError::UnknownKeyId(kid) => write!(f, "Unknown signing key: {kid}"),
37            SecurityError::JwksFetchError(msg) => write!(f, "JWKS fetch error: {msg}"),
38            SecurityError::ValidationFailed(msg) => write!(f, "Token validation failed: {msg}"),
39        }
40    }
41}
42
43impl std::error::Error for SecurityError {}
44
45impl IntoResponse for SecurityError {
46    fn into_response(self) -> Response {
47        let message = self.to_string();
48        let body = serde_json::json!({ "error": message });
49        (StatusCode::UNAUTHORIZED, quarlus_core::http::Json(body)).into_response()
50    }
51}
52
53impl From<SecurityError> for quarlus_core::AppError {
54    fn from(err: SecurityError) -> Self {
55        quarlus_core::AppError::Unauthorized(err.to_string())
56    }
57}