1use std::error::Error as StdError;
2use std::fmt;
3use std::result;
4use std::sync::Arc;
5
6pub(crate) fn new_error(kind: ErrorKind) -> Error {
8 Error(Box::new(kind))
9}
10
11pub type Result<T> = result::Result<T, Error>;
13
14#[derive(Clone, Debug, Eq, PartialEq)]
16pub struct Error(Box<ErrorKind>);
17
18impl Error {
19 pub fn kind(&self) -> &ErrorKind {
21 &self.0
22 }
23
24 pub fn into_kind(self) -> ErrorKind {
26 *self.0
27 }
28}
29
30#[non_exhaustive]
36#[derive(Clone, Debug)]
37pub enum ErrorKind {
38 InvalidToken,
40 InvalidSignature,
42 InvalidEcdsaKey,
44 InvalidRsaKey(String),
46 RsaFailedSigning,
48 InvalidAlgorithmName,
50 InvalidKeyFormat,
52
53 MissingRequiredClaim(String),
56 ExpiredSignature,
58 InvalidIssuer,
60 InvalidAudience,
62 InvalidSubject,
64 ImmatureSignature,
66 InvalidAlgorithm,
69 MissingAlgorithm,
71
72 Base64(base64::DecodeError),
75 Json(Arc<serde_json::Error>),
77 Utf8(::std::string::FromUtf8Error),
79 Crypto(::ring::error::Unspecified),
81}
82
83impl StdError for Error {
84 fn cause(&self) -> Option<&dyn StdError> {
85 match &*self.0 {
86 ErrorKind::InvalidToken => None,
87 ErrorKind::InvalidSignature => None,
88 ErrorKind::InvalidEcdsaKey => None,
89 ErrorKind::RsaFailedSigning => None,
90 ErrorKind::InvalidRsaKey(_) => None,
91 ErrorKind::ExpiredSignature => None,
92 ErrorKind::MissingAlgorithm => None,
93 ErrorKind::MissingRequiredClaim(_) => None,
94 ErrorKind::InvalidIssuer => None,
95 ErrorKind::InvalidAudience => None,
96 ErrorKind::InvalidSubject => None,
97 ErrorKind::ImmatureSignature => None,
98 ErrorKind::InvalidAlgorithm => None,
99 ErrorKind::InvalidAlgorithmName => None,
100 ErrorKind::InvalidKeyFormat => None,
101 ErrorKind::Base64(err) => Some(err),
102 ErrorKind::Json(err) => Some(err.as_ref()),
103 ErrorKind::Utf8(err) => Some(err),
104 ErrorKind::Crypto(err) => Some(err),
105 }
106 }
107}
108
109impl fmt::Display for Error {
110 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111 match &*self.0 {
112 ErrorKind::InvalidToken
113 | ErrorKind::InvalidSignature
114 | ErrorKind::InvalidEcdsaKey
115 | ErrorKind::ExpiredSignature
116 | ErrorKind::RsaFailedSigning
117 | ErrorKind::MissingAlgorithm
118 | ErrorKind::InvalidIssuer
119 | ErrorKind::InvalidAudience
120 | ErrorKind::InvalidSubject
121 | ErrorKind::ImmatureSignature
122 | ErrorKind::InvalidAlgorithm
123 | ErrorKind::InvalidKeyFormat
124 | ErrorKind::InvalidAlgorithmName => write!(f, "{:?}", self.0),
125 ErrorKind::MissingRequiredClaim(c) => write!(f, "Missing required claim: {}", c),
126 ErrorKind::InvalidRsaKey(msg) => write!(f, "RSA key invalid: {}", msg),
127 ErrorKind::Json(err) => write!(f, "JSON error: {}", err),
128 ErrorKind::Utf8(err) => write!(f, "UTF-8 error: {}", err),
129 ErrorKind::Crypto(err) => write!(f, "Crypto error: {}", err),
130 ErrorKind::Base64(err) => write!(f, "Base64 error: {}", err),
131 }
132 }
133}
134
135impl PartialEq for ErrorKind {
136 fn eq(&self, other: &Self) -> bool {
137 format!("{:?}", self) == format!("{:?}", other)
138 }
139}
140
141impl Eq for ErrorKind {}
143
144impl From<base64::DecodeError> for Error {
145 fn from(err: base64::DecodeError) -> Error {
146 new_error(ErrorKind::Base64(err))
147 }
148}
149
150impl From<serde_json::Error> for Error {
151 fn from(err: serde_json::Error) -> Error {
152 new_error(ErrorKind::Json(Arc::new(err)))
153 }
154}
155
156impl From<::std::string::FromUtf8Error> for Error {
157 fn from(err: ::std::string::FromUtf8Error) -> Error {
158 new_error(ErrorKind::Utf8(err))
159 }
160}
161
162impl From<::ring::error::Unspecified> for Error {
163 fn from(err: ::ring::error::Unspecified) -> Error {
164 new_error(ErrorKind::Crypto(err))
165 }
166}
167
168impl From<::ring::error::KeyRejected> for Error {
169 fn from(_err: ::ring::error::KeyRejected) -> Error {
170 new_error(ErrorKind::InvalidEcdsaKey)
171 }
172}
173
174impl From<ErrorKind> for Error {
175 fn from(kind: ErrorKind) -> Error {
176 new_error(kind)
177 }
178}
179
180#[cfg(test)]
181mod tests {
182 use wasm_bindgen_test::wasm_bindgen_test;
183
184 use super::*;
185
186 #[test]
187 #[wasm_bindgen_test]
188 fn test_error_rendering() {
189 assert_eq!(
190 "InvalidAlgorithmName",
191 Error::from(ErrorKind::InvalidAlgorithmName).to_string()
192 );
193 }
194}