use affinidi_tsp::MessageType;
use thiserror::Error;
use trust_tasks_rs::RejectReason;
#[derive(Debug, Error)]
pub enum TspError {
#[error("TSP error: {0}")]
Upstream(#[from] affinidi_tsp::TspError),
#[error("unsupported TSP carriage: only Direct is handled (got {0:?})")]
UnsupportedCarriage(MessageType),
#[error("claimed sender VID `{claimed}` does not match the verified sender `{verified}`")]
SenderMismatch {
claimed: String,
verified: String,
},
#[error("unexpected envelope type: {0}")]
WrongEnvelopeType(String),
#[error("payload did not parse as a Trust Task envelope: {0}")]
InvalidBody(serde_json::Error),
#[error("could not serialise TrustTask for the envelope: {0}")]
SerialiseBody(serde_json::Error),
}
impl TspError {
pub fn into_reject_reason(self) -> RejectReason {
match self {
TspError::InvalidBody(e) => RejectReason::malformed_from_serde(&e),
TspError::SenderMismatch { .. } => RejectReason::ProofRequired,
_ => RejectReason::MalformedRequest {
reason: ENVELOPE_MALFORMED.to_string(),
},
}
}
}
const ENVELOPE_MALFORMED: &str = "message did not yield a well-formed Trust Task document";
#[cfg(test)]
mod tests {
use super::*;
fn reason(err: TspError) -> String {
match err.into_reject_reason() {
RejectReason::MalformedRequest { reason } => reason,
other => panic!("expected malformedRequest, got {other:?}"),
}
}
#[test]
fn the_wire_reason_carries_no_detail_from_the_error() {
let serde = serde_json::from_str::<serde_json::Value>("{\"subject\": ").unwrap_err();
let parsed = reason(TspError::InvalidBody(serde));
assert!(
!parsed.contains("line"),
"deserializer offset on the wire: {parsed}"
);
let other = reason(TspError::WrongEnvelopeType("internal/type".into()));
assert!(
!other.contains("internal/type"),
"envelope detail on the wire: {other}"
);
}
#[test]
fn a_sender_mismatch_asks_for_a_proof_as_the_didcomm_bindings_do() {
let mismatch = TspError::SenderMismatch {
claimed: "did:web:claimed.example".into(),
verified: "did:web:verified.example".into(),
};
assert!(matches!(
mismatch.into_reject_reason(),
RejectReason::ProofRequired
));
}
}