use std::fmt::Display;
use smol_str::SmolStr;
use thiserror::Error;
use crate::{
ast::{Eid, EntityType, EntityUID, PartialValueToValueError},
entities::{
conformance::err::{EntitySchemaConformanceError, InvalidEnumEntityError},
err::Duplicate,
},
evaluator::EvaluationError,
transitive_closure::TcError,
validator::{RequestValidationError, ValidationError},
};
#[derive(Debug, Error)]
#[error("Unexpected action: `{}`", .action)]
pub struct UnexpectedActionError {
pub(super) action: EntityUID,
}
#[derive(Debug, Error)]
pub enum JsonDeserializationError {
#[error(transparent)]
Concrete(#[from] crate::entities::json::err::JsonDeserializationError),
#[error(transparent)]
UnexpectedAction(#[from] UnexpectedActionError),
#[error(transparent)]
RestrictedExprEvaluation(#[from] EvaluationError),
}
#[derive(Debug, Error)]
pub enum EntityValidationError {
#[error(transparent)]
Concrete(#[from] EntitySchemaConformanceError),
#[error(transparent)]
UnknownActionComponent(#[from] UnknownActionComponentError),
#[error(transparent)]
MismatchedActionAncestors(#[from] MismatchedActionAncestorsError),
}
#[derive(Debug, Error)]
#[error("action `{}` has unknown ancestors/attrs/tags", .action)]
pub struct UnknownActionComponentError {
pub(super) action: EntityUID,
}
#[derive(Debug, Error)]
#[error("action `{}`'s ancestors do not match the schema", .action)]
pub struct MismatchedActionAncestorsError {
pub(super) action: EntityUID,
}
#[derive(Debug, Error)]
#[error("`{}`'s ancestor `{}` has unknown ancestors", .uid, .ancestor)]
pub struct AncestorValidationError {
pub(crate) uid: EntityUID,
pub(crate) ancestor: EntityUID,
}
#[derive(Debug, Error)]
pub enum TpeError {
#[error(transparent)]
NoMatchingReqEnv(#[from] NoMatchingReqEnvError),
#[error(transparent)]
NonstaticPolicy(#[from] NonstaticPolicyError),
#[error("Failed validation: {:#?}", .0)]
Validation(Vec<ValidationError>),
#[error(transparent)]
ExprToResidualError(#[from] ExprToResidualError),
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum ExprToResidualError {
#[error(transparent)]
MissingTypeAnnotation(#[from] MissingTypeAnnotationError),
#[error(transparent)]
SlotNotSupported(#[from] SlotNotSupportedError),
#[error(transparent)]
UnknownNotSupported(#[from] UnknownNotSupportedError),
#[error(transparent)]
ErrorNotSupported(#[from] ErrorNotSupportedError),
}
#[derive(Debug, Error)]
#[error("Expression is missing type annotation")]
pub struct MissingTypeAnnotationError;
#[derive(Debug, Error)]
#[error("Expression contains a slot which is not supported in residuals")]
pub struct SlotNotSupportedError;
#[derive(Debug, Error)]
#[error("Expression contains an unknown which is not supported in residuals")]
pub struct UnknownNotSupportedError;
#[derive(Debug, Error)]
#[error("Expression contains an error which is not supported in residuals")]
pub struct ErrorNotSupportedError;
#[derive(Debug, Error)]
#[error("Found a partial request when a concrete request was expected")]
pub struct PartialRequestError {}
#[derive(Debug, Error)]
#[error("Can't find a matching request environment")]
pub struct NoMatchingReqEnvError;
#[derive(Debug, Error)]
#[error("Found a non-static policy")]
pub struct NonstaticPolicyError;
#[derive(Debug, Error)]
pub enum RequestBuilderError {
#[error(transparent)]
Validation(#[from] RequestValidationError),
#[error(transparent)]
ExistingPrincipal(#[from] ExistingPrincipalError),
#[error(transparent)]
ExistingResource(#[from] ExistingResourceError),
#[error("Context already exists")]
ExistingContext,
#[error(transparent)]
IncorrectPrincipalEntityType(#[from] IncorrectPrincipalEntityTypeError),
#[error(transparent)]
IncorrectResourceEntityType(#[from] IncorrectResourceEntityTypeError),
#[error("invalid principal candidate: {}", .0)]
InvalidPrincipalCandidate(InvalidEnumEntityError),
#[error("invalid resource candidate: {}", .0)]
InvalidResourceCandidate(InvalidEnumEntityError),
#[error("context candidate doesn't validate: {}", .0)]
IllTypedContextCandidate(RequestValidationError),
#[error("context candidate contains unknowns")]
UnknownContextCandidate,
}
#[derive(Debug, Error)]
#[error("Principal `{}` already exists", .principal)]
pub struct ExistingPrincipalError {
pub(super) principal: EntityUID,
}
#[derive(Debug, Error)]
#[error("Resource `{}` already exists", .resource)]
pub struct ExistingResourceError {
pub(super) resource: EntityUID,
}
#[derive(Debug, Error)]
#[error("Principal type `{}` is inconsistent with the partial request's `{}`", .ty, .expected)]
pub struct IncorrectPrincipalEntityTypeError {
pub(super) ty: EntityType,
pub(super) expected: EntityType,
}
#[derive(Debug, Error)]
#[error("Resource type `{}` is inconsistent with the partial request's `{}`", .ty, .expected)]
pub struct IncorrectResourceEntityTypeError {
pub(super) ty: EntityType,
pub(super) expected: EntityType,
}
#[derive(Debug, Error)]
pub enum EntitiesError {
#[error(transparent)]
Deserialization(#[from] JsonDeserializationError),
#[error(transparent)]
Validation(#[from] EntityValidationError),
#[error(transparent)]
AncestorValidation(#[from] AncestorValidationError),
#[error(transparent)]
TCComputation(#[from] TcError<EntityUID>),
#[error(transparent)]
Duplicate(#[from] Duplicate),
#[error(transparent)]
PartialValueToValue(#[from] PartialValueToValueError),
}
#[derive(Debug, Error)]
pub enum EntitiesConsistencyError {
#[error(transparent)]
MissingEntity(#[from] MissingEntityError),
#[error(transparent)]
UnknownEntity(#[from] UnknownEntityError),
#[error(transparent)]
InconsistentEntity(#[from] EntityConsistencyError),
}
#[derive(Debug, Error)]
pub enum EntityConsistencyError {
#[error(transparent)]
UnknownAttribute(#[from] UnknownAttributeError),
#[error(transparent)]
MismatchedAttribute(#[from] MismatchedAttributeError),
#[error(transparent)]
MismatchedAncestor(#[from] MismatchedAncestorError),
#[error(transparent)]
UnknownTag(#[from] UnknownTagError),
#[error(transparent)]
MismatchedTag(#[from] MismatchedTagError),
}
#[derive(Debug, Error)]
#[error("Concrete entity `{uid}` contains unknown attribute `{attr}`")]
pub struct UnknownAttributeError {
pub(super) uid: EntityUID,
pub(super) attr: SmolStr,
}
#[derive(Debug, Error)]
#[error("Entity `{uid}`'s attributes do not match")]
pub struct MismatchedAttributeError {
pub(super) uid: EntityUID,
}
#[derive(Debug, Error)]
#[error("Concrete entity `{uid}` contains unknown tag `{tag}`")]
pub struct UnknownTagError {
pub(super) uid: EntityUID,
pub(super) tag: SmolStr,
}
#[derive(Debug, Error)]
#[error("Entity `{uid}`'s tags do not match")]
pub struct MismatchedTagError {
pub(super) uid: EntityUID,
}
#[derive(Debug, Error)]
#[error("Entity `{uid}`'s ancestors do not match")]
pub struct MismatchedAncestorError {
pub(super) uid: EntityUID,
}
#[derive(Debug, Error)]
#[error("Concrete entities does not include `{uid}`")]
pub struct MissingEntityError {
pub(super) uid: EntityUID,
}
#[derive(Debug, Error)]
#[error("Concrete entities contains unknown entity `{uid}`")]
pub struct UnknownEntityError {
pub(super) uid: EntityUID,
}
#[derive(Debug, Error)]
pub struct MissingEntitiesError {
pub(super) missing_entities: Vec<EntityUID>,
}
impl MissingEntitiesError {
pub fn new(missing_entities: Vec<EntityUID>) -> Self {
Self { missing_entities }
}
}
impl Display for MissingEntitiesError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Failed to load entities: {}",
self.missing_entities
.iter()
.map(|uid| uid.to_string())
.collect::<Vec<_>>()
.join(", ")
)
}
}
#[derive(Debug, Error)]
pub enum RequestConsistencyError {
#[error("Concrete principal is unknown")]
UnknownPrincipal,
#[error("Concrete resource is unknown")]
UnknownResource,
#[error("Concrete action is unknown")]
UnknownAction,
#[error("Concrete context is unknown")]
UnknownContext,
#[error(transparent)]
InconsistentPrincipalType(#[from] InconsistentPrincipalTypeError),
#[error(transparent)]
InconsistentPrincipalEid(#[from] InconsistentPrincipalEidError),
#[error(transparent)]
InconsistentResourceType(#[from] InconsistentResourceTypeError),
#[error(transparent)]
InconsistentResourceEid(#[from] InconsistentResourceEidError),
#[error(transparent)]
InconsistentAction(#[from] InconsistentActionError),
#[error("Contexts are inconsistent")]
InconsistentContext,
#[error("Concrete context contains unknowns")]
ConcreteContextContainsUnknowns,
}
#[derive(Debug, Error)]
#[error("Principal types `{partial}` and `{concrete}` do not match")]
pub struct InconsistentPrincipalTypeError {
pub(super) partial: EntityType,
pub(super) concrete: EntityType,
}
#[derive(Debug, Error)]
#[error("Principal eid `{}` and `{}` do not match", .partial.escaped(), .concrete.escaped())]
pub struct InconsistentPrincipalEidError {
pub(super) partial: Eid,
pub(super) concrete: Eid,
}
#[derive(Debug, Error)]
#[error("Resource types `{partial}` and `{concrete}` do not match")]
pub struct InconsistentResourceTypeError {
pub(super) partial: EntityType,
pub(super) concrete: EntityType,
}
#[derive(Debug, Error)]
#[error("Resource eid `{}` and `{}` do not match", .partial.escaped(), .concrete.escaped())]
pub struct InconsistentResourceEidError {
pub(super) partial: Eid,
pub(super) concrete: Eid,
}
#[derive(Debug, Error)]
#[error("Actions `{}` and `{}` do not match", .partial, .concrete)]
pub struct InconsistentActionError {
pub(super) partial: EntityUID,
pub(super) concrete: EntityUID,
}
#[derive(Debug, Error)]
pub enum ReauthorizationError {
#[error(transparent)]
RequestValidation(#[from] RequestValidationError),
#[error(transparent)]
EntityValidation(#[from] EntitySchemaConformanceError),
#[error(transparent)]
EntitiesConsistentcy(#[from] EntitiesConsistencyError),
#[error(transparent)]
RequestConsistentcy(#[from] RequestConsistencyError),
}