use crate::binding::Binding;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error("XML parse error: {0}")]
XmlParse(String),
#[error("XML emit error: {0}")]
XmlEmit(String),
#[error("Base64 decode failed")]
Base64Decode,
#[error("DEFLATE decode failed")]
Inflate,
#[error("SAML schema violation at <{element}>: {reason}")]
SchemaViolation {
element: String,
reason: &'static str,
},
#[error("XML signature verification failed: {reason}")]
SignatureVerification { reason: &'static str },
#[error("XML signature missing where required")]
SignatureMissing,
#[error("Disallowed signature algorithm: {alg}")]
DisallowedAlgorithm { alg: String },
#[error("Disallowed transform: {transform}")]
DisallowedTransform { transform: String },
#[error("Signature Reference URI does not resolve to a recognized element")]
ReferenceResolution,
#[error("X.509 parse failed")]
X509Parse,
#[error("XML-Enc decrypt failed: {reason}")]
DecryptFailed { reason: &'static str },
#[error("Issuer mismatch: expected {expected}, got {got:?}")]
IssuerMismatch {
expected: String,
got: Option<String>,
},
#[error("Destination mismatch")]
DestinationMismatch,
#[error("InResponseTo mismatch")]
InResponseToMismatch,
#[error("Audience restriction not satisfied")]
AudienceMismatch,
#[error("Assertion not yet valid (NotBefore in future)")]
NotYetValid,
#[error("Assertion expired (NotOnOrAfter passed)")]
Expired,
#[error("SubjectConfirmation Recipient mismatch")]
RecipientMismatch,
#[error("Status not Success: {code}")]
StatusNotSuccess {
code: String,
message: Option<String>,
},
#[error("Unsolicited Response received but allow_unsolicited is false")]
UnsolicitedNotAllowed,
#[error("Requested AuthnContextClassRef not satisfied")]
AuthnContextDowngrade,
#[error("Unknown peer entity: {entity_id}")]
UnknownEntity { entity_id: String },
#[error("AssertionConsumerServiceURL not registered for SP {entity_id}")]
UnregisteredAcs { entity_id: String },
#[error("No signing cert found in peer metadata")]
NoPeerSigningCert,
#[error("Peer does not advertise the requested binding: {binding:?}")]
UnsupportedByPeer { binding: Binding },
#[error("AuthnRequest/@ProtocolBinding is not legal for SSO Response: {requested:?}")]
IllegalResponseBinding { requested: Binding },
#[error("Invalid configuration: {reason}")]
InvalidConfiguration { reason: &'static str },
#[error("Assertion replay detected: assertion_id was already consumed within its validity window")]
AssertionReplay,
#[error("Replay cache full: refusing to evict live entries to make room")]
ReplayCacheFull,
#[error("Replay cache backend error: {reason}")]
ReplayCache { reason: &'static str },
#[error("HTTP request failed: {0}")]
Http(#[from] Box<dyn std::error::Error + Send + Sync>),
}