#![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")] #![deny(missing_docs)] pub mod activity_queue; pub mod activity_sending; #[cfg(feature = "actix-web")] pub mod actix_web; #[cfg(feature = "axum")] pub mod axum; pub mod config; pub mod error; pub mod fetch; pub mod http_signatures; pub mod protocol; pub(crate) mod reqwest_shim; pub mod traits; use crate::{ config::Data, error::Error, fetch::object_id::ObjectId, traits::{ActivityHandler, Actor, Object}, }; 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 pub const FEDERATION_CONTENT_TYPE: &str = "application/activity+json"; /// Deserialize incoming inbox activity to the given type, perform basic /// validation and extract the actor. async fn parse_received_activity( body: &[u8], data: &Data, ) -> Result<(Activity, ActorT), ::Error> where Activity: ActivityHandler + DeserializeOwned + Send + 'static, ActorT: Object + Actor + Send + 'static, for<'de2> ::Kind: serde::Deserialize<'de2>, ::Error: From + From<::Error>, ::Error: From, Datatype: Clone, { let activity: Activity = serde_json::from_slice(body).map_err(|e| { // Attempt to include activity id in error message let id = extract_id(body).ok(); Error::ParseReceivedActivity(e, id) })?; data.config.verify_url_and_domain(&activity).await?; let actor = ObjectId::::from(activity.actor().clone()) .dereference(data) .await?; Ok((activity, actor)) } /// Attempt to parse id field from serialized json fn extract_id(data: &[u8]) -> serde_json::Result { #[derive(Deserialize)] struct Id { id: Url, } Ok(serde_json::from_slice::(data)?.id) }