mirror of
https://github.com/LemmyNet/activitypub-federation-rust.git
synced 2024-06-08 16:29:33 +00:00
Better error when receive fails
This commit is contained in:
parent
48489eb265
commit
42dbc6375b
|
@ -3,8 +3,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Data,
|
config::Data,
|
||||||
error::Error,
|
error::Error,
|
||||||
fetch::object_id::ObjectId,
|
|
||||||
http_signatures::{verify_body_hash, verify_signature},
|
http_signatures::{verify_body_hash, verify_signature},
|
||||||
|
parse_received_activity,
|
||||||
traits::{ActivityHandler, Actor, Object},
|
traits::{ActivityHandler, Actor, Object},
|
||||||
};
|
};
|
||||||
use actix_web::{web::Bytes, HttpRequest, HttpResponse};
|
use actix_web::{web::Bytes, HttpRequest, HttpResponse};
|
||||||
|
@ -29,11 +29,7 @@ where
|
||||||
{
|
{
|
||||||
verify_body_hash(request.headers().get("Digest"), &body)?;
|
verify_body_hash(request.headers().get("Digest"), &body)?;
|
||||||
|
|
||||||
let activity: Activity = serde_json::from_slice(&body).map_err(Error::Json)?;
|
let (activity, actor) = parse_received_activity::<Activity, ActorT, _>(&body, data).await?;
|
||||||
data.config.verify_url_and_domain(&activity).await?;
|
|
||||||
let actor = ObjectId::<ActorT>::from(activity.actor().clone())
|
|
||||||
.dereference(data)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
verify_signature(
|
verify_signature(
|
||||||
request.headers(),
|
request.headers(),
|
||||||
|
@ -54,6 +50,7 @@ mod test {
|
||||||
use crate::{
|
use crate::{
|
||||||
activity_sending::generate_request_headers,
|
activity_sending::generate_request_headers,
|
||||||
config::FederationConfig,
|
config::FederationConfig,
|
||||||
|
fetch::object_id::ObjectId,
|
||||||
http_signatures::sign_request,
|
http_signatures::sign_request,
|
||||||
traits::tests::{DbConnection, DbUser, Follow, DB_USER_KEYPAIR},
|
traits::tests::{DbConnection, DbUser, Follow, DB_USER_KEYPAIR},
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Data,
|
config::Data,
|
||||||
error::Error,
|
error::Error,
|
||||||
fetch::object_id::ObjectId,
|
http_signatures::verify_signature,
|
||||||
http_signatures::{verify_body_hash, verify_signature},
|
parse_received_activity,
|
||||||
traits::{ActivityHandler, Actor, Object},
|
traits::{ActivityHandler, Actor, Object},
|
||||||
};
|
};
|
||||||
use axum::{
|
use axum::{
|
||||||
|
@ -33,13 +33,8 @@ where
|
||||||
<ActorT as Object>::Error: From<Error>,
|
<ActorT as Object>::Error: From<Error>,
|
||||||
Datatype: Clone,
|
Datatype: Clone,
|
||||||
{
|
{
|
||||||
verify_body_hash(activity_data.headers.get("Digest"), &activity_data.body)?;
|
let (activity, actor) =
|
||||||
|
parse_received_activity::<Activity, ActorT, _>(&activity_data.body, data).await?;
|
||||||
let activity: Activity = serde_json::from_slice(&activity_data.body).map_err(Error::Json)?;
|
|
||||||
data.config.verify_url_and_domain(&activity).await?;
|
|
||||||
let actor = ObjectId::<ActorT>::from(activity.actor().clone())
|
|
||||||
.dereference(data)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
verify_signature(
|
verify_signature(
|
||||||
&activity_data.headers,
|
&activity_data.headers,
|
||||||
|
|
|
@ -38,6 +38,9 @@ pub enum Error {
|
||||||
/// JSON Error
|
/// JSON Error
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Json(#[from] serde_json::Error),
|
Json(#[from] serde_json::Error),
|
||||||
|
/// Failed to parse an activity received from another instance
|
||||||
|
#[error("Failed to parse incoming activity with id {0}: {1}")]
|
||||||
|
ParseReceivedActivity(Url, serde_json::Error),
|
||||||
/// Reqwest Middleware Error
|
/// Reqwest Middleware Error
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
ReqwestMiddleware(#[from] reqwest_middleware::Error),
|
ReqwestMiddleware(#[from] reqwest_middleware::Error),
|
||||||
|
|
39
src/lib.rs
39
src/lib.rs
|
@ -23,7 +23,46 @@ pub mod protocol;
|
||||||
pub(crate) mod reqwest_shim;
|
pub(crate) mod reqwest_shim;
|
||||||
pub mod traits;
|
pub mod traits;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
config::Data,
|
||||||
|
error::Error,
|
||||||
|
fetch::object_id::ObjectId,
|
||||||
|
traits::{ActivityHandler, Actor, Object},
|
||||||
|
};
|
||||||
pub use activitystreams_kinds as kinds;
|
pub use activitystreams_kinds as kinds;
|
||||||
|
|
||||||
|
use serde::{de::DeserializeOwned, Deserialize};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
/// Mime type for Activitypub data, used for `Accept` and `Content-Type` HTTP headers
|
/// Mime type for Activitypub data, used for `Accept` and `Content-Type` HTTP headers
|
||||||
pub static FEDERATION_CONTENT_TYPE: &str = "application/activity+json";
|
pub static FEDERATION_CONTENT_TYPE: &str = "application/activity+json";
|
||||||
|
|
||||||
|
async fn parse_received_activity<Activity, ActorT, Datatype>(
|
||||||
|
body: &[u8],
|
||||||
|
data: &Data<Datatype>,
|
||||||
|
) -> Result<(Activity, ActorT), <Activity as ActivityHandler>::Error>
|
||||||
|
where
|
||||||
|
Activity: ActivityHandler<DataType = Datatype> + DeserializeOwned + Send + 'static,
|
||||||
|
ActorT: Object<DataType = Datatype> + Actor + Send + 'static,
|
||||||
|
for<'de2> <ActorT as Object>::Kind: serde::Deserialize<'de2>,
|
||||||
|
<Activity as ActivityHandler>::Error: From<Error> + From<<ActorT as Object>::Error>,
|
||||||
|
<ActorT as Object>::Error: From<Error>,
|
||||||
|
Datatype: Clone,
|
||||||
|
{
|
||||||
|
let activity: Activity = serde_json::from_slice(&body).map_err(|e| {
|
||||||
|
// Attempt to parse only activity id for error message
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct Id {
|
||||||
|
id: Url,
|
||||||
|
}
|
||||||
|
match serde_json::from_slice::<Id>(&body) {
|
||||||
|
Ok(id) => Error::ParseReceivedActivity(id.id, e),
|
||||||
|
Err(e) => Error::Json(e),
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
data.config.verify_url_and_domain(&activity).await?;
|
||||||
|
let actor = ObjectId::<ActorT>::from(activity.actor().clone())
|
||||||
|
.dereference(data)
|
||||||
|
.await?;
|
||||||
|
Ok((activity, actor))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue