1use miette::Diagnostic;
21use smol_str::SmolStr;
22use thiserror::Error;
23
24use crate::{
25 ast::{Eid, EntityType, EntityUID, PartialValueToValueError},
26 entities::{conformance::err::EntitySchemaConformanceError, err::Duplicate},
27 evaluator::{evaluation_errors::UnlinkedSlotError, EvaluationError},
28 transitive_closure::TcError,
29 validator::{RequestValidationError, ValidationError},
30};
31
32#[derive(Debug, Error, Diagnostic)]
34#[error("Unexpected action: `{}`", .action)]
35pub struct UnexpectedActionError {
36 pub(super) action: EntityUID,
37}
38
39#[derive(Debug, Error, Diagnostic)]
41pub enum JsonDeserializationError {
42 #[error(transparent)]
44 #[diagnostic(transparent)]
45 Concrete(#[from] crate::entities::json::err::JsonDeserializationError),
46 #[error(transparent)]
49 #[diagnostic(transparent)]
50 UnexpectedAction(#[from] UnexpectedActionError),
51 #[error(transparent)]
53 #[diagnostic(transparent)]
54 RestrictedExprEvaluation(#[from] EvaluationError),
55}
56
57#[derive(Debug, Error, Diagnostic)]
59pub enum EntityValidationError {
60 #[error(transparent)]
62 #[diagnostic(transparent)]
63 Concrete(#[from] EntitySchemaConformanceError),
64 #[error(transparent)]
66 #[diagnostic(transparent)]
67 MismatchedActionAncestors(#[from] MismatchedActionAncestorsError),
68}
69
70#[derive(Debug, Error, Diagnostic)]
72#[error("action `{}`'s ancestors do not match the schema", .action)]
73pub struct MismatchedActionAncestorsError {
74 pub(super) action: EntityUID,
75}
76
77#[derive(Debug, Error, Diagnostic)]
79#[error("ancestor `{ancestor}` of `{uid}` has unknown ancestors")]
80#[diagnostic(help(
81 "an entity with known ancestors cannot have an ancestor whose own ancestors are unknown"
82))]
83pub struct AncestorValidationError {
84 pub(crate) uid: EntityUID,
85 pub(crate) ancestor: EntityUID,
86}
87
88#[derive(Debug, Error, Diagnostic)]
90pub enum TpeError {
91 #[error(transparent)]
94 #[diagnostic(transparent)]
95 NoMatchingReqEnv(#[from] NoMatchingReqEnvError),
96 #[error(transparent)]
98 #[diagnostic(transparent)]
99 Validation(#[from] PolicyValidationError),
100 #[error(transparent)]
102 #[diagnostic(transparent)]
103 ExprToResidualError(#[from] ExprToResidualError),
104}
105
106#[derive(Debug, Error, Diagnostic)]
109#[error("policy failed to validate against the schema")]
110pub struct PolicyValidationError {
111 #[related]
112 pub(super) errors: Vec<ValidationError>,
113}
114
115impl PolicyValidationError {
116 pub(crate) fn new(errors: Vec<ValidationError>) -> Self {
117 Self { errors }
118 }
119
120 pub fn errors(&self) -> impl Iterator<Item = &ValidationError> {
122 self.errors.iter()
123 }
124}
125
126#[derive(Debug, Error, Diagnostic)]
129#[non_exhaustive]
130pub enum ExprToResidualError {
131 #[error(transparent)]
133 #[diagnostic(transparent)]
134 MissingTypeAnnotation(#[from] MissingTypeAnnotationError),
135 #[error(transparent)]
137 #[diagnostic(transparent)]
138 UnlinkedSlotError(#[from] UnlinkedSlotError),
139 #[error(transparent)]
141 #[diagnostic(transparent)]
142 UnknownNotSupported(#[from] UnknownNotSupportedError),
143 #[error(transparent)]
145 #[diagnostic(transparent)]
146 ErrorNotSupported(#[from] ErrorNotSupportedError),
147}
148
149#[derive(Debug, Error, Diagnostic)]
151#[error("expression is missing a type annotation")]
152#[diagnostic(help(
153 "expressions must be typechecked by the policy validator before partial evaluation"
154))]
155pub struct MissingTypeAnnotationError;
156
157#[derive(Debug, Error, Diagnostic)]
159#[error("expression contains an unknown, which is not supported in residuals")]
160pub struct UnknownNotSupportedError;
161
162#[derive(Debug, Error, Diagnostic)]
164#[error("expression contains an error node, which is not supported in residuals")]
165pub struct ErrorNotSupportedError;
166
167#[derive(Debug, Error, Diagnostic)]
169#[error("expected a concrete request, but found a partial request")]
170pub struct PartialRequestError {}
171
172#[derive(Debug, Error, Diagnostic)]
175#[error("no request environment in the schema matches the given request")]
176pub struct NoMatchingReqEnvError;
177
178#[derive(Debug, Error, Diagnostic)]
180pub enum EntitiesError {
181 #[error(transparent)]
183 #[diagnostic(transparent)]
184 Deserialization(#[from] JsonDeserializationError),
185 #[error(transparent)]
187 #[diagnostic(transparent)]
188 Validation(#[from] EntityValidationError),
189 #[error(transparent)]
191 #[diagnostic(transparent)]
192 AncestorValidation(#[from] AncestorValidationError),
193 #[error(transparent)]
195 #[diagnostic(transparent)]
196 TCComputation(#[from] TcError<EntityUID>),
197 #[error(transparent)]
200 #[diagnostic(transparent)]
201 Duplicate(#[from] Duplicate),
202 #[error(transparent)]
204 #[diagnostic(transparent)]
205 PartialValueToValue(#[from] PartialValueToValueError),
206}
207
208#[derive(Debug, Error, Diagnostic)]
211pub enum EntitiesConsistencyError {
212 #[error(transparent)]
214 #[diagnostic(transparent)]
215 MissingEntity(#[from] MissingEntityError),
216 #[error(transparent)]
218 #[diagnostic(transparent)]
219 UnknownEntity(#[from] UnknownEntityError),
220 #[error(transparent)]
223 #[diagnostic(transparent)]
224 InconsistentEntity(#[from] EntityConsistencyError),
225}
226
227#[derive(Debug, Error, Diagnostic)]
230pub enum EntityConsistencyError {
231 #[error(transparent)]
233 #[diagnostic(transparent)]
234 UnknownAttribute(#[from] UnknownAttributeError),
235 #[error(transparent)]
237 #[diagnostic(transparent)]
238 MismatchedAttribute(#[from] MismatchedAttributeError),
239 #[error(transparent)]
241 #[diagnostic(transparent)]
242 MismatchedAncestor(#[from] MismatchedAncestorError),
243 #[error(transparent)]
245 #[diagnostic(transparent)]
246 UnknownTag(#[from] UnknownTagError),
247 #[error(transparent)]
249 #[diagnostic(transparent)]
250 MismatchedTag(#[from] MismatchedTagError),
251}
252
253#[derive(Debug, Error, Diagnostic)]
255#[error("concrete entity `{uid}` has attribute `{attr}` not present in the partial entity")]
256pub struct UnknownAttributeError {
257 pub(super) uid: EntityUID,
258 pub(super) attr: SmolStr,
259}
260
261#[derive(Debug, Error, Diagnostic)]
263#[error("concrete entity `{uid}` has attribute values that do not match the partial entity")]
264pub struct MismatchedAttributeError {
265 pub(super) uid: EntityUID,
266}
267
268#[derive(Debug, Error, Diagnostic)]
270#[error("concrete entity `{uid}` has tag `{tag}` not present in the partial entity")]
271pub struct UnknownTagError {
272 pub(super) uid: EntityUID,
273 pub(super) tag: SmolStr,
274}
275
276#[derive(Debug, Error, Diagnostic)]
278#[error("concrete entity `{uid}` has tag values that do not match the partial entity")]
279pub struct MismatchedTagError {
280 pub(super) uid: EntityUID,
281}
282
283#[derive(Debug, Error, Diagnostic)]
285#[error("concrete entity `{uid}` has ancestors that do not match the partial entity")]
286pub struct MismatchedAncestorError {
287 pub(super) uid: EntityUID,
288}
289
290#[derive(Debug, Error, Diagnostic)]
292#[error("entity `{uid}` is present in the partial entities but missing from the concrete entities")]
293pub struct MissingEntityError {
294 pub(super) uid: EntityUID,
295}
296
297#[derive(Debug, Error, Diagnostic)]
299#[error("concrete entities contain unknown entity `{uid}`")]
300pub struct UnknownEntityError {
301 pub(super) uid: EntityUID,
302}
303
304#[derive(Debug, Error, Diagnostic)]
306pub enum RequestConsistencyError {
307 #[error("the concrete request's principal is unknown")]
309 UnknownPrincipal,
310 #[error("the concrete request's resource is unknown")]
312 UnknownResource,
313 #[error("the concrete request's action is unknown")]
315 UnknownAction,
316 #[error("the concrete request's context is unknown")]
318 UnknownContext,
319 #[error(transparent)]
321 #[diagnostic(transparent)]
322 InconsistentPrincipalType(#[from] InconsistentPrincipalTypeError),
323 #[error(transparent)]
325 #[diagnostic(transparent)]
326 InconsistentPrincipalEid(#[from] InconsistentPrincipalEidError),
327 #[error(transparent)]
329 #[diagnostic(transparent)]
330 InconsistentResourceType(#[from] InconsistentResourceTypeError),
331 #[error(transparent)]
333 #[diagnostic(transparent)]
334 InconsistentResourceEid(#[from] InconsistentResourceEidError),
335 #[error(transparent)]
337 #[diagnostic(transparent)]
338 InconsistentAction(#[from] InconsistentActionError),
339 #[error("the partial and concrete request contexts do not match")]
341 InconsistentContext,
342 #[error("the concrete request's context contains unknowns")]
344 ConcreteContextContainsUnknowns,
345}
346
347#[derive(Debug, Error, Diagnostic)]
349#[error("partial request principal type `{partial}` does not match concrete request principal type `{concrete}`")]
350pub struct InconsistentPrincipalTypeError {
351 pub(super) partial: EntityType,
352 pub(super) concrete: EntityType,
353}
354
355#[derive(Debug, Error, Diagnostic)]
357#[error("partial request principal id `{}` does not match concrete request principal id `{}`", .partial.escaped(), .concrete.escaped())]
358pub struct InconsistentPrincipalEidError {
359 pub(super) partial: Eid,
360 pub(super) concrete: Eid,
361}
362
363#[derive(Debug, Error, Diagnostic)]
365#[error("partial request resource type `{partial}` does not match concrete request resource type `{concrete}`")]
366pub struct InconsistentResourceTypeError {
367 pub(super) partial: EntityType,
368 pub(super) concrete: EntityType,
369}
370
371#[derive(Debug, Error, Diagnostic)]
373#[error("partial request resource id `{}` does not match concrete request resource id `{}`", .partial.escaped(), .concrete.escaped())]
374pub struct InconsistentResourceEidError {
375 pub(super) partial: Eid,
376 pub(super) concrete: Eid,
377}
378
379#[derive(Debug, Error, Diagnostic)]
381#[error("partial request action `{partial}` does not match concrete request action `{concrete}`")]
382pub struct InconsistentActionError {
383 pub(super) partial: EntityUID,
384 pub(super) concrete: EntityUID,
385}
386
387#[derive(Debug, Error, Diagnostic)]
389pub enum ReauthorizationError {
390 #[error(transparent)]
392 #[diagnostic(transparent)]
393 RequestValidation(#[from] RequestValidationError),
394 #[error(transparent)]
396 #[diagnostic(transparent)]
397 EntityValidation(#[from] EntitySchemaConformanceError),
398 #[error(transparent)]
400 #[diagnostic(transparent)]
401 EntitiesConsistency(#[from] EntitiesConsistencyError),
402 #[error(transparent)]
404 #[diagnostic(transparent)]
405 RequestConsistency(#[from] RequestConsistencyError),
406}