2022-01-17 22:54:45 +00:00
|
|
|
use activitystreams::checked::CheckError;
|
2022-02-26 18:12:07 +00:00
|
|
|
use actix_rt::task::JoinError;
|
2020-03-20 00:55:11 +00:00
|
|
|
use actix_web::{
|
|
|
|
error::{BlockingError, ResponseError},
|
|
|
|
http::StatusCode,
|
2021-06-24 17:02:27 +00:00
|
|
|
HttpResponse,
|
2020-03-20 00:55:11 +00:00
|
|
|
};
|
2020-04-23 18:04:17 +00:00
|
|
|
use http_signature_normalization_actix::PrepareSignError;
|
2021-09-18 17:55:39 +00:00
|
|
|
use std::{convert::Infallible, fmt::Debug, io};
|
|
|
|
use tracing::error;
|
|
|
|
use tracing_error::SpanTrace;
|
|
|
|
|
|
|
|
pub(crate) struct Error {
|
|
|
|
context: SpanTrace,
|
|
|
|
kind: ErrorKind,
|
|
|
|
}
|
|
|
|
|
2021-11-25 03:57:20 +00:00
|
|
|
impl std::fmt::Debug for Error {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
writeln!(f, "{:?}", self.kind)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-18 17:55:39 +00:00
|
|
|
impl std::fmt::Display for Error {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
2021-11-23 22:19:59 +00:00
|
|
|
writeln!(f, "{}", self.kind)?;
|
2021-09-18 17:55:39 +00:00
|
|
|
std::fmt::Display::fmt(&self.context, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::error::Error for Error {
|
|
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
|
|
|
self.kind.source()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> From<T> for Error
|
|
|
|
where
|
|
|
|
ErrorKind: From<T>,
|
|
|
|
{
|
|
|
|
fn from(error: T) -> Self {
|
|
|
|
Error {
|
|
|
|
context: SpanTrace::capture(),
|
|
|
|
kind: error.into(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-03-16 03:36:46 +00:00
|
|
|
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
2021-09-18 17:55:39 +00:00
|
|
|
pub(crate) enum ErrorKind {
|
2020-03-21 20:24:05 +00:00
|
|
|
#[error("Error queueing job, {0}")]
|
|
|
|
Queue(anyhow::Error),
|
|
|
|
|
2020-03-20 00:55:11 +00:00
|
|
|
#[error("Error in configuration, {0}")]
|
|
|
|
Config(#[from] config::ConfigError),
|
|
|
|
|
2020-03-16 03:36:46 +00:00
|
|
|
#[error("Couldn't parse key, {0}")]
|
2021-08-01 20:12:06 +00:00
|
|
|
Pkcs8(#[from] rsa::pkcs8::Error),
|
2020-03-16 03:36:46 +00:00
|
|
|
|
2022-04-08 22:39:38 +00:00
|
|
|
#[error("Couldn't encode public key, {0}")]
|
|
|
|
Spki(#[from] rsa::pkcs8::spki::Error),
|
|
|
|
|
2022-01-17 22:54:45 +00:00
|
|
|
#[error("Couldn't parse IRI, {0}")]
|
|
|
|
ParseIri(#[from] activitystreams::iri_string::validate::Error),
|
|
|
|
|
2022-01-24 05:03:00 +00:00
|
|
|
#[error("Couldn't normalize IRI, {0}")]
|
2022-02-01 17:47:17 +00:00
|
|
|
NormalizeIri(
|
|
|
|
#[from]
|
|
|
|
activitystreams::iri_string::task::Error<activitystreams::iri_string::normalize::Error>,
|
|
|
|
),
|
2020-03-16 03:36:46 +00:00
|
|
|
|
|
|
|
#[error("Couldn't perform IO, {0}")]
|
2021-09-18 17:55:39 +00:00
|
|
|
Io(#[from] io::Error),
|
2020-03-16 03:36:46 +00:00
|
|
|
|
2020-03-30 06:06:13 +00:00
|
|
|
#[error("Couldn't sign string, {0}")]
|
2020-03-16 03:36:46 +00:00
|
|
|
Rsa(rsa::errors::Error),
|
|
|
|
|
2021-02-10 04:05:06 +00:00
|
|
|
#[error("Couldn't use db, {0}")]
|
|
|
|
Sled(#[from] sled::Error),
|
|
|
|
|
2020-07-10 23:06:04 +00:00
|
|
|
#[error("Couldn't do the json thing, {0}")]
|
2020-03-16 03:36:46 +00:00
|
|
|
Json(#[from] serde_json::Error),
|
|
|
|
|
2020-04-23 18:04:17 +00:00
|
|
|
#[error("Couldn't build signing string, {0}")]
|
|
|
|
PrepareSign(#[from] PrepareSignError),
|
2020-03-16 03:36:46 +00:00
|
|
|
|
2022-10-29 17:22:13 +00:00
|
|
|
#[error("Couldn't sign digest")]
|
|
|
|
Signature(#[from] signature::Error),
|
|
|
|
|
2020-03-16 03:36:46 +00:00
|
|
|
#[error("Couldn't parse the signature header")]
|
|
|
|
HeaderValidation(#[from] actix_web::http::header::InvalidHeaderValue),
|
|
|
|
|
2020-03-16 04:15:50 +00:00
|
|
|
#[error("Couldn't decode base64")]
|
|
|
|
Base64(#[from] base64::DecodeError),
|
|
|
|
|
2020-03-18 04:58:13 +00:00
|
|
|
#[error("Actor ({0}), or Actor's server, is not subscribed")]
|
|
|
|
NotSubscribed(String),
|
|
|
|
|
2021-02-10 04:05:06 +00:00
|
|
|
#[error("Actor is not allowed, {0}")]
|
|
|
|
NotAllowed(String),
|
2020-03-18 02:16:09 +00:00
|
|
|
|
|
|
|
#[error("Cannot make decisions for foreign actor, {0}")]
|
|
|
|
WrongActor(String),
|
|
|
|
|
|
|
|
#[error("Actor ({0}) tried to submit another actor's ({1}) payload")]
|
|
|
|
BadActor(String, String),
|
2020-03-17 19:52:33 +00:00
|
|
|
|
2020-03-20 03:23:10 +00:00
|
|
|
#[error("Signature verification is required, but no signature was given")]
|
|
|
|
NoSignature(String),
|
|
|
|
|
2020-03-18 04:35:20 +00:00
|
|
|
#[error("Wrong ActivityPub kind, {0}")]
|
|
|
|
Kind(String),
|
|
|
|
|
2020-03-19 22:19:05 +00:00
|
|
|
#[error("Too many CPUs, {0}")]
|
|
|
|
CpuCount(#[from] std::num::TryFromIntError),
|
2020-03-18 04:35:20 +00:00
|
|
|
|
2020-06-20 04:11:02 +00:00
|
|
|
#[error("{0}")]
|
2022-01-17 22:54:45 +00:00
|
|
|
HostMismatch(#[from] CheckError),
|
2020-03-23 22:17:53 +00:00
|
|
|
|
2020-03-26 03:26:45 +00:00
|
|
|
#[error("Invalid or missing content type")]
|
|
|
|
ContentType,
|
|
|
|
|
2020-03-20 18:40:18 +00:00
|
|
|
#[error("Couldn't flush buffer")]
|
|
|
|
FlushBuffer,
|
|
|
|
|
2020-04-22 22:41:01 +00:00
|
|
|
#[error("Invalid algorithm provided to verifier, {0}")]
|
|
|
|
Algorithm(String),
|
2020-03-16 04:15:50 +00:00
|
|
|
|
2020-03-16 03:36:46 +00:00
|
|
|
#[error("Object has already been relayed")]
|
|
|
|
Duplicate,
|
|
|
|
|
2020-04-21 21:39:02 +00:00
|
|
|
#[error("Couldn't send request to {0}, {1}")]
|
|
|
|
SendRequest(String, String),
|
2020-03-16 03:36:46 +00:00
|
|
|
|
2020-04-21 21:39:02 +00:00
|
|
|
#[error("Couldn't receive request response from {0}, {1}")]
|
|
|
|
ReceiveResponse(String, String),
|
2020-03-16 03:36:46 +00:00
|
|
|
|
2020-07-25 15:13:00 +00:00
|
|
|
#[error("Response from {0} has invalid status code, {1}")]
|
|
|
|
Status(String, StatusCode),
|
2020-03-16 03:36:46 +00:00
|
|
|
|
2020-05-21 21:24:56 +00:00
|
|
|
#[error("Expected an Object, found something else")]
|
|
|
|
ObjectFormat,
|
|
|
|
|
|
|
|
#[error("Expected a single object, found array")]
|
|
|
|
ObjectCount,
|
|
|
|
|
|
|
|
#[error("Input is missing a 'type' field")]
|
|
|
|
MissingKind,
|
|
|
|
|
|
|
|
#[error("Input is missing a 'id' field")]
|
|
|
|
MissingId,
|
|
|
|
|
2022-01-17 22:54:45 +00:00
|
|
|
#[error("IriString is missing a domain")]
|
2020-06-20 04:11:02 +00:00
|
|
|
MissingDomain,
|
|
|
|
|
2020-03-16 03:36:46 +00:00
|
|
|
#[error("URI is missing domain field")]
|
|
|
|
Domain,
|
2020-03-20 00:55:11 +00:00
|
|
|
|
|
|
|
#[error("Blocking operation was canceled")]
|
|
|
|
Canceled,
|
2020-12-23 18:06:15 +00:00
|
|
|
|
|
|
|
#[error("Not trying request due to failed breaker")]
|
|
|
|
Breaker,
|
2021-09-18 17:55:39 +00:00
|
|
|
|
|
|
|
#[error("Failed to extract fields from {0}")]
|
2021-09-21 19:32:25 +00:00
|
|
|
Extract(&'static str),
|
2020-03-16 03:36:46 +00:00
|
|
|
}
|
|
|
|
|
2021-09-18 17:55:39 +00:00
|
|
|
impl ResponseError for Error {
|
2020-03-16 03:36:46 +00:00
|
|
|
fn status_code(&self) -> StatusCode {
|
2021-09-18 17:55:39 +00:00
|
|
|
match self.kind {
|
|
|
|
ErrorKind::NotAllowed(_) | ErrorKind::WrongActor(_) | ErrorKind::BadActor(_, _) => {
|
2021-02-10 04:05:06 +00:00
|
|
|
StatusCode::FORBIDDEN
|
|
|
|
}
|
2021-09-18 17:55:39 +00:00
|
|
|
ErrorKind::NotSubscribed(_) => StatusCode::UNAUTHORIZED,
|
|
|
|
ErrorKind::Duplicate => StatusCode::ACCEPTED,
|
|
|
|
ErrorKind::Kind(_)
|
|
|
|
| ErrorKind::MissingKind
|
|
|
|
| ErrorKind::MissingId
|
|
|
|
| ErrorKind::ObjectCount => StatusCode::BAD_REQUEST,
|
2020-03-18 04:58:13 +00:00
|
|
|
_ => StatusCode::INTERNAL_SERVER_ERROR,
|
|
|
|
}
|
2020-03-16 03:36:46 +00:00
|
|
|
}
|
|
|
|
|
2021-06-24 17:02:27 +00:00
|
|
|
fn error_response(&self) -> HttpResponse {
|
|
|
|
HttpResponse::build(self.status_code())
|
2021-02-11 00:00:11 +00:00
|
|
|
.insert_header(("Content-Type", "application/activity+json"))
|
2021-04-17 17:36:47 +00:00
|
|
|
.body(
|
|
|
|
serde_json::to_string(&serde_json::json!({
|
2021-09-18 17:55:39 +00:00
|
|
|
"error": self.kind.to_string(),
|
2021-04-17 17:36:47 +00:00
|
|
|
}))
|
2021-11-23 22:19:59 +00:00
|
|
|
.unwrap_or_else(|_| "{}".to_string()),
|
2021-04-17 17:36:47 +00:00
|
|
|
)
|
2020-03-16 03:36:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-18 17:55:39 +00:00
|
|
|
impl From<BlockingError> for ErrorKind {
|
2021-02-11 00:00:11 +00:00
|
|
|
fn from(_: BlockingError) -> Self {
|
2021-09-18 17:55:39 +00:00
|
|
|
ErrorKind::Canceled
|
2020-03-20 00:55:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-26 18:12:07 +00:00
|
|
|
impl From<JoinError> for ErrorKind {
|
|
|
|
fn from(_: JoinError) -> Self {
|
|
|
|
ErrorKind::Canceled
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-18 17:55:39 +00:00
|
|
|
impl From<Infallible> for ErrorKind {
|
2020-03-16 03:36:46 +00:00
|
|
|
fn from(i: Infallible) -> Self {
|
|
|
|
match i {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-18 17:55:39 +00:00
|
|
|
impl From<rsa::errors::Error> for ErrorKind {
|
2020-03-16 03:36:46 +00:00
|
|
|
fn from(e: rsa::errors::Error) -> Self {
|
2021-09-18 17:55:39 +00:00
|
|
|
ErrorKind::Rsa(e)
|
2020-03-16 03:36:46 +00:00
|
|
|
}
|
|
|
|
}
|