ultrafast_mcp_auth/
error.rs

1use thiserror::Error;
2
3/// Authentication and authorization errors
4#[derive(Error, Debug)]
5pub enum AuthError {
6    #[error("OAuth authentication failed: {message}")]
7    OAuthError { message: String },
8
9    #[error("Token validation failed: {reason}")]
10    TokenValidationError { reason: String },
11
12    #[error("Invalid client credentials")]
13    InvalidCredentials,
14
15    #[error("Expired token")]
16    ExpiredToken,
17
18    #[error("Invalid token audience: expected {expected}, got {actual}")]
19    InvalidAudience { expected: String, actual: String },
20
21    #[error("Missing required scope: {scope}")]
22    MissingScope { scope: String },
23
24    #[error("PKCE challenge failed")]
25    PkceChallengeFailed,
26
27    #[error("Authorization server error: {error}")]
28    AuthorizationServerError { error: String },
29
30    #[error("Token exchange error: {error}")]
31    TokenExchangeError { error: String },
32
33    #[error("Invalid token")]
34    InvalidToken(String),
35
36    #[error("Token expired")]
37    TokenExpired,
38
39    #[error("Invalid client: {0}")]
40    InvalidClient(String),
41
42    #[error("Invalid grant: {0}")]
43    InvalidGrant(String),
44
45    #[error("Invalid scope: {0}")]
46    InvalidScope(String),
47
48    #[error("Unauthorized client")]
49    UnauthorizedClient,
50
51    #[error("Unsupported grant type: {0}")]
52    UnsupportedGrantType(String),
53
54    #[error("Invalid request: {0}")]
55    InvalidRequest(String),
56
57    #[error("Server error: {0}")]
58    ServerError(String),
59
60    #[error("Network error: {0}")]
61    NetworkError(String),
62
63    #[error("Network error during authentication: {source}")]
64    ReqwestError {
65        #[from]
66        source: reqwest::Error,
67    },
68
69    #[error("JWT error: {source}")]
70    JwtError {
71        #[from]
72        source: jsonwebtoken::errors::Error,
73    },
74
75    #[error("Serialization error: {source}")]
76    SerializationError {
77        #[from]
78        source: serde_json::Error,
79    },
80
81    #[error("Invalid URL: {source}")]
82    UrlError {
83        #[from]
84        source: url::ParseError,
85    },
86}
87
88impl PartialEq for AuthError {
89    fn eq(&self, other: &Self) -> bool {
90        match (self, other) {
91            (AuthError::OAuthError { message: a }, AuthError::OAuthError { message: b }) => a == b,
92            (
93                AuthError::TokenValidationError { reason: a },
94                AuthError::TokenValidationError { reason: b },
95            ) => a == b,
96            (AuthError::InvalidCredentials, AuthError::InvalidCredentials) => true,
97            (AuthError::ExpiredToken, AuthError::ExpiredToken) => true,
98            (
99                AuthError::InvalidAudience {
100                    expected: e1,
101                    actual: a1,
102                },
103                AuthError::InvalidAudience {
104                    expected: e2,
105                    actual: a2,
106                },
107            ) => e1 == e2 && a1 == a2,
108            (AuthError::MissingScope { scope: a }, AuthError::MissingScope { scope: b }) => a == b,
109            (AuthError::PkceChallengeFailed, AuthError::PkceChallengeFailed) => true,
110            (
111                AuthError::AuthorizationServerError { error: a },
112                AuthError::AuthorizationServerError { error: b },
113            ) => a == b,
114            (
115                AuthError::TokenExchangeError { error: a },
116                AuthError::TokenExchangeError { error: b },
117            ) => a == b,
118            (AuthError::InvalidToken(a), AuthError::InvalidToken(b)) => a == b,
119            (AuthError::TokenExpired, AuthError::TokenExpired) => true,
120            (AuthError::InvalidClient(a), AuthError::InvalidClient(b)) => a == b,
121            (AuthError::InvalidGrant(a), AuthError::InvalidGrant(b)) => a == b,
122            (AuthError::InvalidScope(a), AuthError::InvalidScope(b)) => a == b,
123            (AuthError::UnauthorizedClient, AuthError::UnauthorizedClient) => true,
124            (AuthError::UnsupportedGrantType(a), AuthError::UnsupportedGrantType(b)) => a == b,
125            (AuthError::InvalidRequest(a), AuthError::InvalidRequest(b)) => a == b,
126            (AuthError::ServerError(a), AuthError::ServerError(b)) => a == b,
127            (AuthError::NetworkError(a), AuthError::NetworkError(b)) => a == b,
128            // For errors with external types, compare by their string representation
129            (AuthError::ReqwestError { source: a }, AuthError::ReqwestError { source: b }) => {
130                a.to_string() == b.to_string()
131            }
132            (AuthError::JwtError { source: a }, AuthError::JwtError { source: b }) => {
133                a.to_string() == b.to_string()
134            }
135            (
136                AuthError::SerializationError { source: a },
137                AuthError::SerializationError { source: b },
138            ) => a.to_string() == b.to_string(),
139            (AuthError::UrlError { source: a }, AuthError::UrlError { source: b }) => {
140                a.to_string() == b.to_string()
141            }
142            _ => false,
143        }
144    }
145}