solid_pod_rs_activitypub/error.rs
1//! Error types for the ActivityPub sibling crate.
2//!
3//! The types here deliberately split by bounded context so that each
4//! handler surfaces only the failures it can actually raise; this
5//! keeps the `pub` API honest about what a given operation can go
6//! wrong on.
7
8use thiserror::Error;
9
10/// Signature-layer errors raised by [`crate::http_sig`].
11#[derive(Debug, Error)]
12pub enum SigError {
13 /// A required HTTP header (e.g. `Date`, `Digest`) is absent.
14 #[error("missing required header: {0}")]
15 MissingHeader(&'static str),
16 /// The `Signature` header could not be parsed.
17 #[error("malformed Signature header: {0}")]
18 MalformedSignature(String),
19 /// The `Signature` header lacks a `keyId` parameter.
20 #[error("missing keyId in signature")]
21 MissingKeyId,
22 /// The declared algorithm is not `rsa-sha256`.
23 #[error("unsupported signature algorithm: {0}")]
24 UnsupportedAlgorithm(String),
25 /// The `Digest` header does not match the request body.
26 #[error("digest mismatch (body tampered)")]
27 DigestMismatch,
28 /// Failed to dereference the remote actor's public key.
29 #[error("failed to fetch remote actor key at {0}: {1}")]
30 ActorFetch(String, String),
31 /// The fetched actor document contains no usable public key.
32 #[error("actor has no usable public key")]
33 NoPublicKey,
34 /// RSA signature verification returned a mismatch.
35 #[error("signature verification failed: {0}")]
36 VerifyFailed(String),
37 /// Base64 decoding of the signature value failed.
38 #[error("base64 decode error: {0}")]
39 Base64(String),
40 /// An RSA key-parsing or padding error.
41 #[error("RSA error: {0}")]
42 Rsa(String),
43 /// The `keyId` URL could not be parsed.
44 #[error("URL parse error: {0}")]
45 Url(String),
46 /// The `Date` header is too old or too far in the future (replay
47 /// protection).
48 #[error("request Date is stale or in the future: {0}")]
49 DateNotFresh(String),
50 /// The target URL resolves to a private/internal IP address (SSRF
51 /// protection).
52 #[error("SSRF blocked: {0}")]
53 SsrfBlocked(String),
54}
55
56/// Inbox-layer errors raised by [`crate::inbox`].
57#[derive(Debug, Error)]
58pub enum InboxError {
59 /// The request body is not valid JSON or lacks required fields.
60 #[error("invalid JSON body: {0}")]
61 InvalidJson(String),
62 /// The activity object has no `type` field.
63 #[error("missing activity type")]
64 MissingType,
65 /// SQLite persistence layer failure.
66 #[error("storage error: {0}")]
67 Storage(#[from] sqlx::Error),
68 /// HTTP Signature verification failed.
69 #[error("signature error: {0}")]
70 Signature(#[from] SigError),
71}
72
73/// Outbox-layer errors raised by [`crate::outbox`].
74#[derive(Debug, Error)]
75pub enum OutboxError {
76 /// The submitted activity is structurally invalid.
77 #[error("invalid activity: {0}")]
78 InvalidActivity(String),
79 /// SQLite persistence layer failure.
80 #[error("storage error: {0}")]
81 Storage(#[from] sqlx::Error),
82 /// Outbound HTTP Signature generation failed.
83 #[error("signature error: {0}")]
84 Signature(#[from] SigError),
85 /// The federated delivery queue rejected the item.
86 #[error("delivery queue error: {0}")]
87 Delivery(String),
88 /// The inbox URL resolves to a private/internal IP address (SSRF
89 /// protection).
90 #[error("SSRF blocked: {0}")]
91 SsrfBlocked(String),
92}