pulseengine_mcp_security_middleware/
error.rs1use thiserror::Error;
4
5pub type SecurityResult<T> = Result<T, SecurityError>;
7
8#[derive(Debug, Error)]
10pub enum SecurityError {
11 #[error("Configuration error: {0}")]
13 Config(String),
14
15 #[error("Authentication failed: {0}")]
17 AuthenticationFailed(String),
18
19 #[error("Authorization failed: {0}")]
21 AuthorizationFailed(String),
22
23 #[error("Invalid token: {0}")]
25 InvalidToken(String),
26
27 #[error("Token expired")]
29 TokenExpired,
30
31 #[error("Missing authentication credentials")]
33 MissingAuth,
34
35 #[error("Rate limit exceeded")]
37 RateLimitExceeded,
38
39 #[error("Invalid API key")]
41 InvalidApiKey,
42
43 #[error("JWT validation error: {0}")]
45 JwtValidation(String),
46
47 #[error("Environment variable error: {0}")]
49 Environment(#[from] std::env::VarError),
50
51 #[error("IO error: {0}")]
53 Io(#[from] std::io::Error),
54
55 #[error("JSON error: {0}")]
57 Json(#[from] serde_json::Error),
58
59 #[error("Random generation error: {0}")]
61 Random(String),
62
63 #[error("Cryptographic error: {0}")]
65 Crypto(String),
66
67 #[error("HTTP error: {0}")]
69 Http(String),
70
71 #[error("Internal security error: {0}")]
73 Internal(String),
74}
75
76impl SecurityError {
77 pub fn config<S: Into<String>>(msg: S) -> Self {
79 Self::Config(msg.into())
80 }
81
82 pub fn auth<S: Into<String>>(msg: S) -> Self {
84 Self::AuthenticationFailed(msg.into())
85 }
86
87 pub fn authz<S: Into<String>>(msg: S) -> Self {
89 Self::AuthorizationFailed(msg.into())
90 }
91
92 pub fn invalid_token<S: Into<String>>(msg: S) -> Self {
94 Self::InvalidToken(msg.into())
95 }
96
97 pub fn jwt<S: Into<String>>(msg: S) -> Self {
99 Self::JwtValidation(msg.into())
100 }
101
102 pub fn random<S: Into<String>>(msg: S) -> Self {
104 Self::Random(msg.into())
105 }
106
107 pub fn crypto<S: Into<String>>(msg: S) -> Self {
109 Self::Crypto(msg.into())
110 }
111
112 pub fn http<S: Into<String>>(msg: S) -> Self {
114 Self::Http(msg.into())
115 }
116
117 pub fn internal<S: Into<String>>(msg: S) -> Self {
119 Self::Internal(msg.into())
120 }
121}
122
123impl From<jsonwebtoken::errors::Error> for SecurityError {
125 fn from(err: jsonwebtoken::errors::Error) -> Self {
126 use jsonwebtoken::errors::ErrorKind;
127
128 match err.kind() {
129 ErrorKind::ExpiredSignature => SecurityError::TokenExpired,
130 ErrorKind::InvalidToken => SecurityError::InvalidToken("Invalid JWT token".to_string()),
131 ErrorKind::InvalidSignature => {
132 SecurityError::InvalidToken("Invalid JWT signature".to_string())
133 }
134 ErrorKind::InvalidAudience => {
135 SecurityError::InvalidToken("Invalid JWT audience".to_string())
136 }
137 ErrorKind::InvalidIssuer => {
138 SecurityError::InvalidToken("Invalid JWT issuer".to_string())
139 }
140 _ => SecurityError::JwtValidation(err.to_string()),
141 }
142 }
143}