1use std::{error::Error as StdError, fmt};
16
17use wasmparser::BinaryReaderError;
18
19#[derive(Debug)]
21pub struct Error(Box<ErrorKind>);
22
23pub(crate) fn new(kind: ErrorKind) -> Error {
24 Error(Box::new(kind))
25}
26
27#[derive(Debug)]
28pub enum ErrorKind {
29 Serialize(serde_json::error::Error),
30 Encryption(nkeys::error::Error),
31 Decode(data_encoding::DecodeError),
32 UTF8(std::string::FromUtf8Error),
33 Token(String),
34 InvalidCapability,
35 WasmElement(String),
36 IO(std::io::Error),
37 InvalidModuleHash,
38 ExpiredToken,
39 TokenTooEarly,
40 InvalidAlgorithm,
41 MissingIssuer,
42 MissingSubject,
43}
44
45impl Error {
46 #[must_use]
47 pub fn kind(&self) -> &ErrorKind {
48 &self.0
49 }
50
51 #[must_use]
52 pub fn into_kind(self) -> ErrorKind {
53 *self.0
54 }
55}
56
57impl StdError for Error {
58 fn description(&self) -> &str {
59 match *self.0 {
60 ErrorKind::Serialize(_) => "Serialization failure",
61 ErrorKind::Encryption(_) => "Encryption failure",
62 ErrorKind::Decode(_) => "Decode failure",
63 ErrorKind::UTF8(_) => "UTF8 failure",
64 ErrorKind::Token(_) => "JWT failure",
65 ErrorKind::InvalidCapability => "Invalid Capability",
66 ErrorKind::WasmElement(_) => "WebAssembly element",
67 ErrorKind::IO(_) => "I/O error",
68 ErrorKind::InvalidModuleHash => "Invalid Module Hash",
69 ErrorKind::ExpiredToken => "Token has expired",
70 ErrorKind::TokenTooEarly => "Token cannot be used yet",
71 ErrorKind::InvalidAlgorithm => "Invalid JWT algorithm",
72 ErrorKind::MissingIssuer => "Missing issuer claim",
73 ErrorKind::MissingSubject => "Missing sub claim",
74 }
75 }
76
77 fn cause(&self) -> Option<&dyn StdError> {
78 match *self.0 {
79 ErrorKind::Serialize(ref err) => Some(err),
80 ErrorKind::Encryption(ref err) => Some(err),
81 ErrorKind::Decode(ref err) => Some(err),
82 ErrorKind::UTF8(ref err) => Some(err),
83 ErrorKind::IO(ref err) => Some(err),
84 ErrorKind::Token(_)
85 | ErrorKind::InvalidCapability
86 | ErrorKind::WasmElement(_)
87 | ErrorKind::InvalidModuleHash
88 | ErrorKind::ExpiredToken
89 | ErrorKind::TokenTooEarly
90 | ErrorKind::InvalidAlgorithm
91 | ErrorKind::MissingIssuer
92 | ErrorKind::MissingSubject => None,
93 }
94 }
95}
96
97impl fmt::Display for Error {
98 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99 match *self.0 {
100 ErrorKind::Serialize(ref err) => write!(f, "Serialization error: {err}"),
101 ErrorKind::Encryption(ref err) => write!(f, "Encryption error: {err}"),
102 ErrorKind::Decode(ref err) => write!(f, "Decode error: {err}"),
103 ErrorKind::UTF8(ref err) => write!(f, "UTF8 error: {err}"),
104 ErrorKind::Token(ref err) => write!(f, "JWT error: {err}"),
105 ErrorKind::InvalidCapability => write!(f, "Invalid capability"),
106 ErrorKind::WasmElement(ref err) => write!(f, "Wasm Element error: {err}"),
107 ErrorKind::IO(ref err) => write!(f, "I/O error: {err}"),
108 ErrorKind::InvalidModuleHash => write!(f, "Invalid module hash"),
109 ErrorKind::ExpiredToken => write!(f, "Module token has expired"),
110 ErrorKind::TokenTooEarly => write!(f, "Module cannot be used yet"),
111 ErrorKind::InvalidAlgorithm => {
112 write!(f, "Invalid JWT algorithm. WASCAP only supports Ed25519")
113 }
114 ErrorKind::MissingIssuer => {
115 write!(
116 f,
117 "Invalid JWT. WASCAP requires an issuer claim to be present"
118 )
119 }
120 ErrorKind::MissingSubject => {
121 write!(f, "Invalid JWT. WASCAP requires a sub claim to be present")
122 }
123 }
124 }
125}
126
127impl From<std::io::Error> for Error {
128 fn from(source: std::io::Error) -> Error {
129 Error(Box::new(ErrorKind::IO(source)))
130 }
131}
132
133impl From<BinaryReaderError> for Error {
134 fn from(source: BinaryReaderError) -> Error {
135 let io_error = ::std::io::Error::other(source.to_string());
136 Error(Box::new(ErrorKind::IO(io_error)))
137 }
138}
139
140impl From<serde_json::error::Error> for Error {
141 fn from(source: serde_json::error::Error) -> Error {
142 Error(Box::new(ErrorKind::Serialize(source)))
143 }
144}
145
146impl From<data_encoding::DecodeError> for Error {
147 fn from(source: data_encoding::DecodeError) -> Error {
148 Error(Box::new(ErrorKind::Decode(source)))
149 }
150}
151
152impl From<nkeys::error::Error> for Error {
153 fn from(source: nkeys::error::Error) -> Error {
154 Error(Box::new(ErrorKind::Encryption(source)))
155 }
156}
157
158impl From<std::string::FromUtf8Error> for Error {
159 fn from(source: std::string::FromUtf8Error) -> Error {
160 Error(Box::new(ErrorKind::UTF8(source)))
161 }
162}