1use std::fmt::Display;
21
22use smol_str::SmolStr;
23use thiserror::Error;
24
25use crate::{
26 ast::{Eid, EntityType, EntityUID, PartialValueToValueError},
27 entities::{
28 conformance::err::{EntitySchemaConformanceError, InvalidEnumEntityError},
29 err::Duplicate,
30 },
31 evaluator::EvaluationError,
32 transitive_closure::TcError,
33 validator::{RequestValidationError, ValidationError},
34};
35
36#[derive(Debug, Error)]
38#[error("Unexpected action: `{}`", .action)]
39pub struct UnexpectedActionError {
40 pub(super) action: EntityUID,
41}
42
43#[derive(Debug, Error)]
45pub enum JsonDeserializationError {
46 #[error(transparent)]
48 Concrete(#[from] crate::entities::json::err::JsonDeserializationError),
49 #[error(transparent)]
52 UnexpectedAction(#[from] UnexpectedActionError),
53 #[error(transparent)]
55 RestrictedExprEvaluation(#[from] EvaluationError),
56}
57
58#[derive(Debug, Error)]
60pub enum EntityValidationError {
61 #[error(transparent)]
63 Concrete(#[from] EntitySchemaConformanceError),
64 #[error(transparent)]
66 UnknownActionComponent(#[from] UnknownActionComponentError),
67 #[error(transparent)]
69 MismatchedActionAncestors(#[from] MismatchedActionAncestorsError),
70}
71
72#[derive(Debug, Error)]
74#[error("action `{}` has unknown ancestors/attrs/tags", .action)]
75pub struct UnknownActionComponentError {
76 pub(super) action: EntityUID,
77}
78
79#[derive(Debug, Error)]
81#[error("action `{}`'s ancestors do not match the schema", .action)]
82pub struct MismatchedActionAncestorsError {
83 pub(super) action: EntityUID,
84}
85
86#[derive(Debug, Error)]
88#[error("`{}`'s ancestor `{}` has unknown ancestors", .uid, .ancestor)]
89pub struct AncestorValidationError {
90 pub(crate) uid: EntityUID,
91 pub(crate) ancestor: EntityUID,
92}
93
94#[derive(Debug, Error)]
96pub enum TpeError {
97 #[error(transparent)]
100 NoMatchingReqEnv(#[from] NoMatchingReqEnvError),
101 #[error(transparent)]
103 NonstaticPolicy(#[from] NonstaticPolicyError),
104 #[error("Failed validation: {:#?}", .0)]
106 Validation(Vec<ValidationError>),
107 #[error(transparent)]
109 ExprToResidualError(#[from] ExprToResidualError),
110}
111
112#[derive(Debug, Error)]
115#[non_exhaustive]
116pub enum ExprToResidualError {
117 #[error(transparent)]
119 MissingTypeAnnotation(#[from] MissingTypeAnnotationError),
120 #[error(transparent)]
122 SlotNotSupported(#[from] SlotNotSupportedError),
123 #[error(transparent)]
125 UnknownNotSupported(#[from] UnknownNotSupportedError),
126 #[error(transparent)]
128 ErrorNotSupported(#[from] ErrorNotSupportedError),
129}
130
131#[derive(Debug, Error)]
133#[error("Expression is missing type annotation")]
134pub struct MissingTypeAnnotationError;
135
136#[derive(Debug, Error)]
138#[error("Expression contains a slot which is not supported in residuals")]
139pub struct SlotNotSupportedError;
140
141#[derive(Debug, Error)]
143#[error("Expression contains an unknown which is not supported in residuals")]
144pub struct UnknownNotSupportedError;
145
146#[derive(Debug, Error)]
148#[error("Expression contains an error which is not supported in residuals")]
149pub struct ErrorNotSupportedError;
150
151#[derive(Debug, Error)]
153#[error("Found a partial request when a concrete request was expected")]
154pub struct PartialRequestError {}
155
156#[derive(Debug, Error)]
159#[error("Can't find a matching request environment")]
160pub struct NoMatchingReqEnvError;
161
162#[derive(Debug, Error)]
164#[error("Found a non-static policy")]
165pub struct NonstaticPolicyError;
166
167#[derive(Debug, Error)]
169pub enum RequestBuilderError {
170 #[error(transparent)]
172 Validation(#[from] RequestValidationError),
173 #[error(transparent)]
175 ExistingPrincipal(#[from] ExistingPrincipalError),
176 #[error(transparent)]
178 ExistingResource(#[from] ExistingResourceError),
179 #[error("Context already exists")]
181 ExistingContext,
182 #[error(transparent)]
185 IncorrectPrincipalEntityType(#[from] IncorrectPrincipalEntityTypeError),
186 #[error(transparent)]
189 IncorrectResourceEntityType(#[from] IncorrectResourceEntityTypeError),
190 #[error("invalid principal candidate: {}", .0)]
192 InvalidPrincipalCandidate(InvalidEnumEntityError),
193 #[error("invalid resource candidate: {}", .0)]
195 InvalidResourceCandidate(InvalidEnumEntityError),
196 #[error("context candidate doesn't validate: {}", .0)]
198 IllTypedContextCandidate(RequestValidationError),
199 #[error("context candidate contains unknowns")]
201 UnknownContextCandidate,
202}
203
204#[derive(Debug, Error)]
207#[error("Principal `{}` already exists", .principal)]
208pub struct ExistingPrincipalError {
209 pub(super) principal: EntityUID,
210}
211
212#[derive(Debug, Error)]
215#[error("Resource `{}` already exists", .resource)]
216pub struct ExistingResourceError {
217 pub(super) resource: EntityUID,
218}
219
220#[derive(Debug, Error)]
223#[error("Principal type `{}` is inconsistent with the partial request's `{}`", .ty, .expected)]
224pub struct IncorrectPrincipalEntityTypeError {
225 pub(super) ty: EntityType,
226 pub(super) expected: EntityType,
227}
228
229#[derive(Debug, Error)]
232#[error("Resource type `{}` is inconsistent with the partial request's `{}`", .ty, .expected)]
233pub struct IncorrectResourceEntityTypeError {
234 pub(super) ty: EntityType,
235 pub(super) expected: EntityType,
236}
237
238#[derive(Debug, Error)]
240pub enum EntitiesError {
241 #[error(transparent)]
243 Deserialization(#[from] JsonDeserializationError),
244 #[error(transparent)]
246 Validation(#[from] EntityValidationError),
247 #[error(transparent)]
249 AncestorValidation(#[from] AncestorValidationError),
250 #[error(transparent)]
252 TCComputation(#[from] TcError<EntityUID>),
253 #[error(transparent)]
256 Duplicate(#[from] Duplicate),
257 #[error(transparent)]
259 PartialValueToValue(#[from] PartialValueToValueError),
260}
261
262#[derive(Debug, Error)]
265pub enum EntitiesConsistencyError {
266 #[error(transparent)]
268 MissingEntity(#[from] MissingEntityError),
269 #[error(transparent)]
271 UnknownEntity(#[from] UnknownEntityError),
272 #[error(transparent)]
275 InconsistentEntity(#[from] EntityConsistencyError),
276}
277
278#[derive(Debug, Error)]
281pub enum EntityConsistencyError {
282 #[error(transparent)]
284 UnknownAttribute(#[from] UnknownAttributeError),
285 #[error(transparent)]
287 MismatchedAttribute(#[from] MismatchedAttributeError),
288 #[error(transparent)]
290 MismatchedAncestor(#[from] MismatchedAncestorError),
291 #[error(transparent)]
293 UnknownTag(#[from] UnknownTagError),
294 #[error(transparent)]
296 MismatchedTag(#[from] MismatchedTagError),
297}
298
299#[derive(Debug, Error)]
301#[error("Concrete entity `{uid}` contains unknown attribute `{attr}`")]
302pub struct UnknownAttributeError {
303 pub(super) uid: EntityUID,
304 pub(super) attr: SmolStr,
305}
306
307#[derive(Debug, Error)]
309#[error("Entity `{uid}`'s attributes do not match")]
310pub struct MismatchedAttributeError {
311 pub(super) uid: EntityUID,
312}
313
314#[derive(Debug, Error)]
316#[error("Concrete entity `{uid}` contains unknown tag `{tag}`")]
317pub struct UnknownTagError {
318 pub(super) uid: EntityUID,
319 pub(super) tag: SmolStr,
320}
321
322#[derive(Debug, Error)]
324#[error("Entity `{uid}`'s tags do not match")]
325pub struct MismatchedTagError {
326 pub(super) uid: EntityUID,
327}
328
329#[derive(Debug, Error)]
331#[error("Entity `{uid}`'s ancestors do not match")]
332pub struct MismatchedAncestorError {
333 pub(super) uid: EntityUID,
334}
335
336#[derive(Debug, Error)]
338#[error("Concrete entities does not include `{uid}`")]
339pub struct MissingEntityError {
340 pub(super) uid: EntityUID,
341}
342
343#[derive(Debug, Error)]
345#[error("Concrete entities contains unknown entity `{uid}`")]
346pub struct UnknownEntityError {
347 pub(super) uid: EntityUID,
348}
349
350#[derive(Debug, Error)]
352pub struct MissingEntitiesError {
353 pub(super) missing_entities: Vec<EntityUID>,
354}
355
356impl MissingEntitiesError {
357 pub fn new(missing_entities: Vec<EntityUID>) -> Self {
359 Self { missing_entities }
360 }
361}
362
363impl Display for MissingEntitiesError {
364 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
365 write!(
366 f,
367 "Failed to load entities: {}",
368 self.missing_entities
369 .iter()
370 .map(|uid| uid.to_string())
371 .collect::<Vec<_>>()
372 .join(", ")
373 )
374 }
375}
376
377#[derive(Debug, Error)]
379pub enum RequestConsistencyError {
380 #[error("Concrete principal is unknown")]
382 UnknownPrincipal,
383 #[error("Concrete resource is unknown")]
385 UnknownResource,
386 #[error("Concrete action is unknown")]
388 UnknownAction,
389 #[error("Concrete context is unknown")]
391 UnknownContext,
392 #[error(transparent)]
394 InconsistentPrincipalType(#[from] InconsistentPrincipalTypeError),
395 #[error(transparent)]
397 InconsistentPrincipalEid(#[from] InconsistentPrincipalEidError),
398 #[error(transparent)]
400 InconsistentResourceType(#[from] InconsistentResourceTypeError),
401 #[error(transparent)]
403 InconsistentResourceEid(#[from] InconsistentResourceEidError),
404 #[error(transparent)]
406 InconsistentAction(#[from] InconsistentActionError),
407 #[error("Contexts are inconsistent")]
409 InconsistentContext,
410 #[error("Concrete context contains unknowns")]
412 ConcreteContextContainsUnknowns,
413}
414
415#[derive(Debug, Error)]
417#[error("Principal types `{partial}` and `{concrete}` do not match")]
418pub struct InconsistentPrincipalTypeError {
419 pub(super) partial: EntityType,
420 pub(super) concrete: EntityType,
421}
422
423#[derive(Debug, Error)]
425#[error("Principal eid `{}` and `{}` do not match", .partial.escaped(), .concrete.escaped())]
426pub struct InconsistentPrincipalEidError {
427 pub(super) partial: Eid,
428 pub(super) concrete: Eid,
429}
430
431#[derive(Debug, Error)]
433#[error("Resource types `{partial}` and `{concrete}` do not match")]
434pub struct InconsistentResourceTypeError {
435 pub(super) partial: EntityType,
436 pub(super) concrete: EntityType,
437}
438
439#[derive(Debug, Error)]
441#[error("Resource eid `{}` and `{}` do not match", .partial.escaped(), .concrete.escaped())]
442pub struct InconsistentResourceEidError {
443 pub(super) partial: Eid,
444 pub(super) concrete: Eid,
445}
446
447#[derive(Debug, Error)]
449#[error("Actions `{}` and `{}` do not match", .partial, .concrete)]
450pub struct InconsistentActionError {
451 pub(super) partial: EntityUID,
452 pub(super) concrete: EntityUID,
453}
454
455#[derive(Debug, Error)]
457pub enum ReauthorizationError {
458 #[error(transparent)]
460 RequestValidation(#[from] RequestValidationError),
461 #[error(transparent)]
463 EntityValidation(#[from] EntitySchemaConformanceError),
464 #[error(transparent)]
466 EntitiesConsistentcy(#[from] EntitiesConsistencyError),
467 #[error(transparent)]
469 RequestConsistentcy(#[from] RequestConsistencyError),
470}