1use std::convert::{From, Infallible};
5use thiserror::Error;
6
7#[derive(Error, Clone, Debug, PartialEq, Eq)]
9#[cfg_attr(feature = "serde-error", derive(serde::Serialize, serde::Deserialize))]
10pub enum Token {
11 #[error("internal error")]
12 InternalError,
13 #[error("error deserializing or verifying the token")]
14 Format(Format),
15 #[error("tried to append a block to a sealed token")]
16 AppendOnSealed,
17 #[error("tried to seal an already sealed token")]
18 AlreadySealed,
19 #[error("authorization failed")]
20 FailedLogic(Logic),
21 #[error("error generating Datalog: {0}")]
22 Language(biscuit_parser::error::LanguageError),
23 #[error("Reached Datalog execution limits")]
24 RunLimit(RunLimit),
25 #[error("Cannot convert from Term: {0}")]
26 ConversionError(String),
27 #[error("Cannot decode base64 token: {0}")]
28 Base64(Base64Error),
29 #[error("Datalog execution failure: {0}")]
30 Execution(Expression),
31}
32
33impl From<Infallible> for Token {
34 fn from(_: Infallible) -> Self {
35 unreachable!()
36 }
37}
38
39impl From<Format> for Token {
40 fn from(e: Format) -> Self {
41 Token::Format(e)
42 }
43}
44
45impl From<Logic> for Token {
46 fn from(e: Logic) -> Self {
47 Token::FailedLogic(e)
48 }
49}
50
51impl From<biscuit_parser::error::LanguageError> for Token {
52 fn from(e: biscuit_parser::error::LanguageError) -> Self {
53 Token::Language(e)
54 }
55}
56
57impl From<base64::DecodeError> for Token {
58 fn from(e: base64::DecodeError) -> Self {
59 let err = match e {
60 base64::DecodeError::InvalidByte(offset, byte) => {
61 Base64Error::InvalidByte(offset, byte)
62 }
63 base64::DecodeError::InvalidLength => Base64Error::InvalidLength,
64 base64::DecodeError::InvalidLastSymbol(offset, byte) => {
65 Base64Error::InvalidLastSymbol(offset, byte)
66 }
67 };
68
69 Token::Base64(err)
70 }
71}
72
73impl From<Execution> for Token {
74 fn from(e: Execution) -> Self {
75 match e {
76 Execution::RunLimit(limit) => Token::RunLimit(limit),
77 Execution::Expression(e) => Token::Execution(e),
78 }
79 }
80}
81
82#[derive(Clone, Debug, PartialEq, Eq)]
83#[cfg_attr(feature = "serde-error", derive(serde::Serialize, serde::Deserialize))]
84pub enum Base64Error {
85 InvalidByte(usize, u8),
86 InvalidLength,
87 InvalidLastSymbol(usize, u8),
88}
89
90impl std::fmt::Display for Base64Error {
91 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
92 match *self {
93 Base64Error::InvalidByte(index, byte) => {
94 write!(f, "Invalid byte {}, offset {}.", byte, index)
95 }
96 Base64Error::InvalidLength => write!(f, "Encoded text cannot have a 6-bit remainder."),
97 Base64Error::InvalidLastSymbol(index, byte) => {
98 write!(f, "Invalid last symbol {}, offset {}.", byte, index)
99 }
100 }
101 }
102}
103
104#[derive(Error, Clone, Debug, PartialEq, Eq)]
107#[cfg_attr(feature = "serde-error", derive(serde::Serialize, serde::Deserialize))]
108pub enum Format {
109 #[error("failed verifying the signature")]
110 Signature(Signature),
111 #[error("failed verifying the signature of a sealed token")]
112 SealedSignature,
113 #[error("the token does not provide intermediate public keys")]
114 EmptyKeys,
115 #[error("the root public key was not recognized")]
116 UnknownPublicKey,
117 #[error("could not deserialize the wrapper object")]
118 DeserializationError(String),
119 #[error("could not serialize the wrapper object")]
120 SerializationError(String),
121 #[error("could not deserialize the block")]
122 BlockDeserializationError(String),
123 #[error("could not serialize the block")]
124 BlockSerializationError(String),
125 #[error("Block format version is higher than supported")]
126 Version {
127 maximum: u32,
128 minimum: u32,
129 actual: u32,
130 },
131 #[error("invalid key size")]
132 InvalidKeySize(usize),
133 #[error("invalid signature size")]
134 InvalidSignatureSize(usize),
135 #[error("invalid key")]
136 InvalidKey(String),
137 #[error("could not deserialize signature")]
138 SignatureDeserializationError(String),
139 #[error("could not deserialize the block signature")]
140 BlockSignatureDeserializationError(String),
141 #[error("invalid block id")]
142 InvalidBlockId(usize),
143 #[error("the public key is already present in previous blocks")]
144 ExistingPublicKey(String),
145 #[error("multiple blocks declare the same symbols")]
146 SymbolTableOverlap,
147 #[error("multiple blocks declare the same public keys")]
148 PublicKeyTableOverlap,
149 #[error("the external public key was not recognized")]
150 UnknownExternalKey,
151 #[error("the symbol id was not in the table")]
152 UnknownSymbol(u64),
153}
154
155#[derive(Error, Clone, Debug, PartialEq, Eq)]
157#[cfg_attr(feature = "serde-error", derive(serde::Serialize, serde::Deserialize))]
158pub enum Signature {
159 #[error("could not parse the signature elements")]
160 InvalidFormat,
161 #[error("the signature did not match")]
162 InvalidSignature(String),
163 #[error("could not sign")]
164 InvalidSignatureGeneration(String),
165}
166
167#[derive(Error, Clone, Debug, PartialEq, Eq)]
169#[cfg_attr(feature = "serde-error", derive(serde::Serialize, serde::Deserialize))]
170pub enum Logic {
171 #[error("a rule provided by a block is generating facts with the authority or ambient tag, or has head variables not used in its body")]
172 InvalidBlockRule(u32, String),
173 #[error("authorization failed")]
174 Unauthorized {
175 policy: MatchedPolicy,
177 checks: Vec<FailedCheck>,
179 },
180 #[error("the authorizer already contains a token")]
181 AuthorizerNotEmpty,
182 #[error("no matching policy was found")]
183 NoMatchingPolicy {
184 checks: Vec<FailedCheck>,
186 },
187}
188
189#[derive(Error, Clone, Debug, PartialEq, Eq)]
190#[cfg_attr(feature = "serde-error", derive(serde::Serialize, serde::Deserialize))]
191pub enum MatchedPolicy {
192 #[error("an allow policy matched")]
193 Allow(usize),
194 #[error("a deny policy matched")]
195 Deny(usize),
196}
197
198#[derive(Error, Clone, Debug, PartialEq, Eq)]
200#[cfg_attr(feature = "serde-error", derive(serde::Serialize, serde::Deserialize))]
201pub enum FailedCheck {
202 #[error("a check failed in a block")]
203 Block(FailedBlockCheck),
204 #[error("a check provided by the authorizer failed")]
205 Authorizer(FailedAuthorizerCheck),
206}
207
208#[derive(Clone, Debug, PartialEq, Eq)]
209#[cfg_attr(feature = "serde-error", derive(serde::Serialize, serde::Deserialize))]
210pub struct FailedBlockCheck {
211 pub block_id: u32,
212 pub check_id: u32,
213 pub rule: String,
215}
216
217#[derive(Clone, Debug, PartialEq, Eq)]
218#[cfg_attr(feature = "serde-error", derive(serde::Serialize, serde::Deserialize))]
219pub struct FailedAuthorizerCheck {
220 pub check_id: u32,
221 pub rule: String,
223}
224
225#[derive(Error, Clone, Debug, PartialEq, Eq)]
227#[cfg_attr(feature = "serde-error", derive(serde::Serialize, serde::Deserialize))]
228pub enum Execution {
229 #[error("Reached Datalog execution limits")]
230 RunLimit(RunLimit),
231 #[error("Expression execution failure")]
232 Expression(Expression),
233}
234
235#[derive(Error, Clone, Debug, PartialEq, Eq)]
237#[cfg_attr(feature = "serde-error", derive(serde::Serialize, serde::Deserialize))]
238pub enum Expression {
239 #[error("Unknown symbol")]
240 UnknownSymbol(u64),
241 #[error("Unknown variable")]
242 UnknownVariable(u32),
243 #[error("Invalid type")]
244 InvalidType,
245 #[error("Overflow")]
246 Overflow,
247 #[error("Division by zero")]
248 DivideByZero,
249 #[error("Wrong number of elements on stack")]
250 InvalidStack,
251}
252
253#[derive(Error, Clone, Debug, PartialEq, Eq)]
255#[cfg_attr(feature = "serde-error", derive(serde::Serialize, serde::Deserialize))]
256pub enum RunLimit {
257 #[error("too many facts generated")]
258 TooManyFacts,
259 #[error("too many engine iterations")]
260 TooManyIterations,
261 #[error("spent too much time verifying")]
262 Timeout,
263}
264
265#[cfg(test)]
266mod tests {
267 use super::*;
268
269 #[test]
270 fn error_format_strings() {
271 assert_eq!(
272 format!("{}", Token::ConversionError("test".to_owned())),
273 "Cannot convert from Term: test"
274 );
275
276 assert_eq!(
277 format!("{}", Token::Base64(Base64Error::InvalidLength)),
278 "Cannot decode base64 token: Encoded text cannot have a 6-bit remainder."
279 );
280 }
281}