Skip to main content

chronix_security/auth/
error.rs

1//! Authentication errors.
2
3/// Errors that can occur during authentication or encryption operations.
4#[derive(Debug, thiserror::Error)]
5pub enum AuthError {
6    /// Invalid or missing API key.
7    #[error("invalid api key: {0}")]
8    InvalidApiKey(String),
9
10    /// API key has expired.
11    #[error("api key expired: {0}")]
12    ExpiredApiKey(String),
13
14    /// Invalid JWT token.
15    #[error("invalid jwt: {0}")]
16    InvalidJwt(String),
17
18    /// JWT token has expired.
19    #[error("jwt expired")]
20    ExpiredJwt,
21
22    /// Invalid client certificate.
23    #[error("invalid client certificate: {0}")]
24    InvalidCertificate(String),
25
26    /// No authentication provided.
27    #[error("no authentication provided")]
28    NoAuth,
29
30    /// Encryption error.
31    #[error("encryption error: {0}")]
32    Encryption(String),
33
34    /// Decryption error.
35    #[error("decryption error: {0}")]
36    Decryption(String),
37
38    /// Key not found.
39    #[error("key not found: {0}")]
40    KeyNotFound(String),
41
42    /// Configuration error.
43    #[error("auth config error: {0}")]
44    Config(String),
45}
46
47impl AuthError {
48    /// Returns a generic, client-safe error message that does not
49    /// expose internal configuration details.  Use `Display` (the
50    /// `#[error(...)]` messages) for server-side logging only.
51    #[must_use]
52    pub fn client_message(&self) -> &'static str {
53        match self {
54            Self::InvalidApiKey(_) | Self::InvalidJwt(_) | Self::InvalidCertificate(_) => {
55                "invalid credentials"
56            }
57            Self::ExpiredApiKey(_) | Self::ExpiredJwt => "credentials expired",
58            Self::NoAuth => "authentication required",
59            Self::Encryption(_) | Self::Decryption(_) | Self::KeyNotFound(_) => "internal error",
60            Self::Config(_) => "service misconfigured",
61        }
62    }
63
64    /// Whether this error should be treated as HTTP 401 (vs 500).
65    #[must_use]
66    pub fn is_auth_failure(&self) -> bool {
67        matches!(
68            self,
69            Self::InvalidApiKey(_)
70                | Self::InvalidJwt(_)
71                | Self::InvalidCertificate(_)
72                | Self::ExpiredApiKey(_)
73                | Self::ExpiredJwt
74                | Self::NoAuth
75        )
76    }
77}