about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGriffin Smith <grfn@gws.fyi>2022-05-16T15·18-0400
committerclbot <clbot@tvl.fyi>2022-05-16T15·37+0000
commitd3778302811573dbb3cb99ea716f9d15bf067e69 (patch)
treec8f03cdd3124fb8f2db4d2ef115d7133921b7e99
parente20f7695fa18995e6111a79841e5abd5bf32b477 (diff)
feat(net/alcoholic_jwt): Implement Error for ValidationError r/4082
This allows using it unchanged in contexts where working with &dyn Error
is desirable, such as when using anyhow.

Change-Id: Ide34025e432204546b2c80b14b870af42dbfbb44
Reviewed-on: https://cl.tvl.fyi/c/depot/+/5615
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
Autosubmit: grfn <grfn@gws.fyi>
-rw-r--r--net/alcoholic_jwt/src/lib.rs34
1 files changed, 34 insertions, 0 deletions
diff --git a/net/alcoholic_jwt/src/lib.rs b/net/alcoholic_jwt/src/lib.rs
index 297bf2a99085..1b50a9117712 100644
--- a/net/alcoholic_jwt/src/lib.rs
+++ b/net/alcoholic_jwt/src/lib.rs
@@ -84,6 +84,8 @@ use openssl::rsa::Rsa;
 use openssl::sign::Verifier;
 use serde::de::DeserializeOwned;
 use serde_json::Value;
+use std::error::Error;
+use std::fmt::{self, Display};
 use std::time::{Duration, SystemTime, UNIX_EPOCH};
 
 #[cfg(test)]
@@ -219,6 +221,38 @@ pub enum ValidationError {
     InvalidClaims(Vec<&'static str>),
 }
 
+impl Error for ValidationError {
+    fn source(&self) -> Option<&(dyn Error + 'static)> {
+        match self {
+            ValidationError::InvalidBase64(e) => Some(e),
+            ValidationError::OpenSSL(e) => Some(e),
+            ValidationError::JSON(e) => Some(e),
+            ValidationError::InvalidComponents
+            | ValidationError::InvalidJWK
+            | ValidationError::InvalidSignature
+            | ValidationError::InvalidClaims(_) => None,
+        }
+    }
+}
+
+impl Display for ValidationError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            ValidationError::InvalidComponents => {
+                f.write_str("Invalid number of token components in JWT")
+            }
+            ValidationError::InvalidBase64(_) => f.write_str("Invalid Base64 encoding in JWT"),
+            ValidationError::InvalidJWK => f.write_str("JWK decoding failed"),
+            ValidationError::InvalidSignature => f.write_str("JWT signature validation failed"),
+            ValidationError::OpenSSL(e) => write!(f, "SSL error: {}", e),
+            ValidationError::JSON(e) => write!(f, "JSON error: {}", e),
+            ValidationError::InvalidClaims(errs) => {
+                write!(f, "Invalid claims: {}", errs.join(", "))
+            }
+        }
+    }
+}
+
 type JWTResult<T> = Result<T, ValidationError>;
 
 impl From<ErrorStack> for ValidationError {