diff --git a/Cargo.lock b/Cargo.lock index b5c65413..a9e8dd0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1762,8 +1762,8 @@ dependencies = [ "serde", "serde_json", "sha2", - "strum", - "strum_macros", + "strum 0.20.0", + "strum_macros 0.20.1", "thiserror", "tokio 0.3.7", "url", @@ -1825,8 +1825,8 @@ dependencies = [ "serde", "serde_json", "sha2", - "strum", - "strum_macros", + "strum 0.20.0", + "strum_macros 0.20.1", "thiserror", "tokio 0.3.7", "url", @@ -1872,8 +1872,8 @@ dependencies = [ "serde", "serde_json", "sha2", - "strum", - "strum_macros", + "strum 0.20.0", + "strum_macros 0.20.1", "thiserror", "tokio 0.3.7", "url", @@ -1917,8 +1917,8 @@ dependencies = [ "serde", "serde_json", "sha2", - "strum", - "strum_macros", + "strum 0.21.0", + "strum_macros 0.21.1", "thiserror", "tokio 0.3.7", "url", @@ -1941,8 +1941,8 @@ dependencies = [ "serde_json", "serial_test", "sha2", - "strum", - "strum_macros", + "strum 0.20.0", + "strum_macros 0.20.1", "url", ] @@ -2015,7 +2015,7 @@ dependencies = [ "rss", "serde", "sha2", - "strum", + "strum 0.20.0", "url", ] @@ -2053,7 +2053,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "strum", + "strum 0.20.0", "tokio 0.3.7", "url", ] @@ -2085,8 +2085,8 @@ dependencies = [ "reqwest", "serde", "serde_json", - "strum", - "strum_macros", + "strum 0.20.0", + "strum_macros 0.20.1", "thiserror", "tokio 0.3.7", "url", @@ -2112,8 +2112,8 @@ dependencies = [ "reqwest", "serde", "serde_json", - "strum", - "strum_macros", + "strum 0.20.0", + "strum_macros 0.20.1", "tokio 0.3.7", ] @@ -3373,6 +3373,15 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c" +[[package]] +name = "strum" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2" +dependencies = [ + "strum_macros 0.21.1", +] + [[package]] name = "strum_macros" version = "0.20.1" @@ -3385,6 +3394,18 @@ dependencies = [ "syn 1.0.60", ] +[[package]] +name = "strum_macros" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" +dependencies = [ + "heck", + "proc-macro2 1.0.24", + "quote 1.0.8", + "syn 1.0.60", +] + [[package]] name = "syn" version = "0.14.9" diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index fe63d4d5..e280f8aa 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -52,6 +52,7 @@ pub type GroupExt = /// Activitystreams type for person type PersonExt = Ext2>>, PersonExtension, PublicKeyExtension>; +pub type SiteExt = actor::ApActor>; /// Activitystreams type for post pub type PageExt = Ext1, PageExtension>; pub type NoteExt = ApObject; diff --git a/crates/apub_receive/Cargo.toml b/crates/apub_receive/Cargo.toml index 54e01f7d..3141d19d 100644 --- a/crates/apub_receive/Cargo.toml +++ b/crates/apub_receive/Cargo.toml @@ -25,8 +25,8 @@ actix-rt = { version = "1.1.1", default-features = false } awc = { version = "2.0.3", default-features = false } log = "0.4.14" rand = "0.8.3" -strum = "0.20.0" -strum_macros = "0.20.1" +strum = { version = "0.21", features = ["derive"] } +strum_macros = "0.21" url = { version = "2.2.1", features = ["serde"] } percent-encoding = "2.1.0" openssl = "0.10.32" diff --git a/crates/apub_receive/src/activities/receive/comment.rs b/crates/apub_receive/src/activities/receive/comment.rs index 18508fa2..b285f595 100644 --- a/crates/apub_receive/src/activities/receive/comment.rs +++ b/crates/apub_receive/src/activities/receive/comment.rs @@ -15,6 +15,20 @@ use lemmy_db_views::comment_view::CommentView; use lemmy_utils::{location_info, utils::scrape_text_for_mentions, LemmyError}; use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation, UserOperationCrud}; +// TODO: +// - define traits for all activity types +// - implement inbox routing with these traits +// - replace context with actix style Data struct (actix_web::web::Data) +pub(crate) trait ReceiveCreate { + fn receive_create(self, create: Create, context: LemmyContext, request_counter: &mut i32); +} + +impl ReceiveCreate for Comment { + fn receive_create(self, _create: Create, _context: LemmyContext, _request_counter: &mut i32) { + unimplemented!() + } +} + pub(crate) async fn receive_create_comment( create: Create, context: &LemmyContext, diff --git a/crates/apub_receive/src/inbox/community_inbox.rs b/crates/apub_receive/src/inbox/community_inbox.rs index dfea8605..8ab65813 100644 --- a/crates/apub_receive/src/inbox/community_inbox.rs +++ b/crates/apub_receive/src/inbox/community_inbox.rs @@ -5,6 +5,7 @@ use crate::{ get_activity_id, inbox_verify_http_signature, is_activity_already_known, + new_inbox_routing::receive_activity, receive_for_community::{ receive_add_for_community, receive_block_user_for_community, @@ -136,6 +137,7 @@ pub(crate) async fn community_receive_message( let any_base = activity.clone().into_any_base()?; let actor_url = actor.actor_id(); let activity_kind = activity.kind().context(location_info!())?; + receive_activity(any_base.clone(), context)?; let do_announce = match activity_kind { CommunityValidTypes::Follow => { Box::pin(handle_follow( diff --git a/crates/apub_receive/src/inbox/mod.rs b/crates/apub_receive/src/inbox/mod.rs index dce2c279..3a940bfe 100644 --- a/crates/apub_receive/src/inbox/mod.rs +++ b/crates/apub_receive/src/inbox/mod.rs @@ -27,6 +27,7 @@ use std::fmt::Debug; use url::Url; pub mod community_inbox; +pub mod new_inbox_routing; pub mod person_inbox; pub(crate) mod receive_for_community; pub mod shared_inbox; diff --git a/crates/apub_receive/src/inbox/new_inbox_routing.rs b/crates/apub_receive/src/inbox/new_inbox_routing.rs new file mode 100644 index 00000000..99cf50fb --- /dev/null +++ b/crates/apub_receive/src/inbox/new_inbox_routing.rs @@ -0,0 +1,100 @@ +use activitystreams::base::AnyBase; +use anyhow::Context; +use lemmy_utils::{location_info, LemmyError}; +use lemmy_websocket::LemmyContext; +use std::{collections::HashMap, str::FromStr}; +use strum_macros::EnumString; + +// for now, limit it to activity routing only, no http sigs, parsing or any of that +// need to route in this order: +// 1. recipient actor +// 2. activity type +// 3. inner object (recursively until object is empty or an url) + +// library part + +/// macro shorthand to create hashmap +/// usage: `let counts = hashmap!['A' => 0, 'C' => 0, 'G' => 0, 'T' => 0];` +/// from https://stackoverflow.com/questions/28392008/more-concise-hashmap-initialization +macro_rules! hashmap { + ($( $key: expr => $val: expr ),*) => {{ + let mut map = ::std::collections::HashMap::new(); + $( map.insert($key, $val); )* + map + }} +} + +#[derive(Hash, Eq, PartialEq, EnumString)] +enum ActivityTypes { + Follow, + Announce, + Create, +} + +#[derive(Eq, PartialEq)] +enum ObjectTypes { + Page, + Note, + Url, // we dont dereference urls in object field, so we dont know what exactly it refers to + None, // object field doesnt exist +} + +struct InboxConfig { + actors: Vec, +} + +impl InboxConfig { + fn shared_inbox_handler() { + todo!() + } +} + +type AcceptedTypes = HashMap; + +// TODO: need to provide a handler function for each value +enum InnerType { + Simple(ObjectTypes), + Nested(AcceptedTypes), +} + +struct ActorConfig { + accepted_types: AcceptedTypes, +} + +impl ActorConfig { + pub(crate) fn actor_inbox_handler( + self, + activity: AnyBase, + _context: &LemmyContext, + ) -> Result<(), LemmyError> { + // TODO: probably better to define our own struct with the fields we need + unparsed, and later + // convert to activity (needs id_unchecked(), kind, object) + let kind = ActivityTypes::from_str(activity.kind_str().context(location_info!())?)?; + use InnerType::*; + match self.accepted_types.get(&kind).context(location_info!())? { + Simple(o) => {} + Nested(a) => {} + } + // TODO: correctly route the activity to handle_follow, receive_create_comment or receive_create_post + todo!() + } +} + +// application part + +pub(crate) fn receive_activity( + activity: AnyBase, + context: &LemmyContext, +) -> Result<(), LemmyError> { + use ActivityTypes::*; + use InnerType::*; + use ObjectTypes::*; + + let accepted_types = hashmap![Follow => Simple(Url), + Announce => + Nested(hashmap![Create => Simple(Note), Create => Simple(Page)])]; + let community_inbox_config = ActorConfig { accepted_types }; + let inbox_config = InboxConfig { actors: vec![] }; + community_inbox_config.actor_inbox_handler(activity, context)?; + Ok(()) +}