2023-03-06 01:17:34 +00:00
|
|
|
#![doc = include_str!("../docs/01_intro.md")]
|
|
|
|
#![doc = include_str!("../docs/02_overview.md")]
|
|
|
|
#![doc = include_str!("../docs/03_federating_users.md")]
|
|
|
|
#![doc = include_str!("../docs/04_federating_posts.md")]
|
|
|
|
#![doc = include_str!("../docs/05_configuration.md")]
|
|
|
|
#![doc = include_str!("../docs/06_http_endpoints_axum.md")]
|
|
|
|
#![doc = include_str!("../docs/07_fetching_data.md")]
|
|
|
|
#![doc = include_str!("../docs/08_receiving_activities.md")]
|
|
|
|
#![doc = include_str!("../docs/09_sending_activities.md")]
|
|
|
|
#![doc = include_str!("../docs/10_fetching_objects_with_unknown_type.md")]
|
2023-03-02 14:18:06 +00:00
|
|
|
#![deny(missing_docs)]
|
2022-06-02 11:17:12 +00:00
|
|
|
|
2023-09-01 09:19:22 +00:00
|
|
|
pub mod activity_sending;
|
2023-03-06 01:17:34 +00:00
|
|
|
#[cfg(feature = "actix-web")]
|
|
|
|
pub mod actix_web;
|
|
|
|
#[cfg(feature = "axum")]
|
|
|
|
pub mod axum;
|
2023-02-19 12:26:01 +00:00
|
|
|
pub mod config;
|
2023-03-01 23:19:10 +00:00
|
|
|
pub mod error;
|
2023-03-06 01:17:34 +00:00
|
|
|
pub mod fetch;
|
|
|
|
pub mod http_signatures;
|
2023-02-19 12:26:01 +00:00
|
|
|
pub mod protocol;
|
2023-03-06 01:17:34 +00:00
|
|
|
pub(crate) mod reqwest_shim;
|
2022-06-02 11:17:12 +00:00
|
|
|
pub mod traits;
|
2023-03-01 23:19:10 +00:00
|
|
|
|
2023-12-11 23:40:57 +00:00
|
|
|
use crate::{
|
|
|
|
config::Data,
|
|
|
|
error::Error,
|
|
|
|
fetch::object_id::ObjectId,
|
|
|
|
traits::{ActivityHandler, Actor, Object},
|
|
|
|
};
|
2023-03-01 23:19:10 +00:00
|
|
|
pub use activitystreams_kinds as kinds;
|
2022-06-02 11:17:12 +00:00
|
|
|
|
2023-12-11 23:40:57 +00:00
|
|
|
use serde::{de::DeserializeOwned, Deserialize};
|
|
|
|
use url::Url;
|
|
|
|
|
2023-03-06 01:17:34 +00:00
|
|
|
/// Mime type for Activitypub data, used for `Accept` and `Content-Type` HTTP headers
|
2023-03-16 20:41:29 +00:00
|
|
|
pub static FEDERATION_CONTENT_TYPE: &str = "application/activity+json";
|
2023-12-11 23:40:57 +00:00
|
|
|
|
|
|
|
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,
|
|
|
|
{
|
2023-12-11 23:49:37 +00:00
|
|
|
let activity: Activity = serde_json::from_slice(body).map_err(|e| {
|
2023-12-11 23:40:57 +00:00
|
|
|
// Attempt to parse only activity id for error message
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
struct Id {
|
|
|
|
id: Url,
|
|
|
|
}
|
2023-12-11 23:49:37 +00:00
|
|
|
match serde_json::from_slice::<Id>(body) {
|
2023-12-11 23:40:57 +00:00
|
|
|
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))
|
|
|
|
}
|