diff --git a/Cargo.lock b/Cargo.lock index fe8cb2af7..54b40e121 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1876,6 +1876,7 @@ dependencies = [ "strum_macros 0.20.1", "thiserror", "tokio 0.3.7", + "trait_enum", "url", "uuid", ] @@ -3689,6 +3690,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "trait_enum" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "130dd741d3c71f76d031e58caffff3624eaaa2db9bd8c4b05406a71885300fc7" + [[package]] name = "trust-dns-proto" version = "0.19.6" diff --git a/crates/apub/Cargo.toml b/crates/apub/Cargo.toml index 7d413f851..a06929230 100644 --- a/crates/apub/Cargo.toml +++ b/crates/apub/Cargo.toml @@ -50,3 +50,4 @@ thiserror = "1.0.23" background-jobs = "0.8.0" reqwest = { version = "0.10.10", features = ["json"] } backtrace = "0.3.56" +trait_enum = "0.5.0" diff --git a/crates/apub/src/activities/send/community.rs b/crates/apub/src/activities/send/community.rs index c5112f58c..230f24e32 100644 --- a/crates/apub/src/activities/send/community.rs +++ b/crates/apub/src/activities/send/community.rs @@ -49,7 +49,6 @@ use lemmy_utils::{location_info, settings::structs::Settings, LemmyError}; use lemmy_websocket::LemmyContext; use url::Url; -#[async_trait::async_trait(?Send)] impl ActorType for Community { fn is_local(&self) -> bool { self.local @@ -57,6 +56,9 @@ impl ActorType for Community { fn actor_id(&self) -> Url { self.actor_id.to_owned().into_inner() } + fn name(&self) -> String { + self.name.clone() + } fn public_key(&self) -> Option { self.public_key.to_owned() } diff --git a/crates/apub/src/activities/send/person.rs b/crates/apub/src/activities/send/person.rs index 286778c78..95f54c7b2 100644 --- a/crates/apub/src/activities/send/person.rs +++ b/crates/apub/src/activities/send/person.rs @@ -24,7 +24,6 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[async_trait::async_trait(?Send)] impl ActorType for Person { fn is_local(&self) -> bool { self.local @@ -32,6 +31,9 @@ impl ActorType for Person { fn actor_id(&self) -> Url { self.actor_id.to_owned().into_inner() } + fn name(&self) -> String { + self.name.clone() + } fn public_key(&self) -> Option { self.public_key.to_owned() diff --git a/crates/apub/src/fetcher/mod.rs b/crates/apub/src/fetcher/mod.rs index a4a6a145d..5d574e43a 100644 --- a/crates/apub/src/fetcher/mod.rs +++ b/crates/apub/src/fetcher/mod.rs @@ -40,34 +40,40 @@ where false } -/// Get a remote actor from its apub ID (either a person or a community). Thin wrapper around -/// `get_or_fetch_and_upsert_person()` and `get_or_fetch_and_upsert_community()`. -/// -/// If it exists locally and `!should_refetch_actor()`, it is returned directly from the database. -/// Otherwise it is fetched from the remote instance, stored and returned. +trait_enum! { +pub enum Actor: ActorType { + Person, + Community, +} +} +/* +impl ActorType for Actor { + fn is_local(&self) -> bool { + self. + self.is_local() + } + fn actor_id(&self) -> Url { + self.actor_id() + } + fn name(&self) -> String { + self.name() + } + fn public_key(&self) -> Option { + self.public_key() + } + fn private_key(&self) -> Option { + self.private_key() + } + fn get_shared_inbox_or_inbox_url(&self) -> Url { + self.get_shared_inbox_or_inbox_url() + } +} + */ + pub async fn get_or_fetch_and_upsert_actor( apub_id: &Url, context: &LemmyContext, recursion_counter: &mut i32, -) -> Result, LemmyError> { - let community = get_or_fetch_and_upsert_community(apub_id, context, recursion_counter).await; - let actor: Box = match community { - Ok(c) => Box::new(c), - Err(_) => Box::new(get_or_fetch_and_upsert_person(apub_id, context, recursion_counter).await?), - }; - Ok(actor) -} - -pub enum Actor { - Person(Person), - Community(Community), -} - -// TODO: use this and get rid of ActorType -pub async fn get_or_fetch_and_upsert_actor2( - apub_id: &Url, - context: &LemmyContext, - recursion_counter: &mut i32, ) -> Result { let community = get_or_fetch_and_upsert_community(apub_id, context, recursion_counter).await; let actor: Actor = match community { diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index e280f8aa5..bb4a80160 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -1,5 +1,7 @@ #[macro_use] extern crate lazy_static; +#[macro_use] +extern crate trait_enum; pub mod activities; pub mod activity_queue; @@ -171,10 +173,10 @@ pub trait ApubLikeableType { /// Common methods provided by ActivityPub actors (community and person). Not all methods are /// implemented by all actors. -#[async_trait::async_trait(?Send)] pub trait ActorType { fn is_local(&self) -> bool; fn actor_id(&self) -> Url; + fn name(&self) -> String; // TODO: every actor should have a public key, so this shouldnt be an option (needs to be fixed in db) fn public_key(&self) -> Option; diff --git a/crates/apub_receive/src/activities/comment/create.rs b/crates/apub_receive/src/activities/comment/create.rs index 198501628..8d8008483 100644 --- a/crates/apub_receive/src/activities/comment/create.rs +++ b/crates/apub_receive/src/activities/comment/create.rs @@ -1,6 +1,6 @@ -use crate::{ - activities::comment::{get_notif_recipients, send_websocket_message}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + comment::{get_notif_recipients, send_websocket_message}, + LemmyActivity, }; use activitystreams::{activity::kind::CreateType, base::BaseExt}; use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, ActorType, NoteExt}; @@ -21,7 +21,7 @@ pub struct CreateComment { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/comment/delete.rs b/crates/apub_receive/src/activities/comment/delete.rs index dcba11b80..a11ab72f5 100644 --- a/crates/apub_receive/src/activities/comment/delete.rs +++ b/crates/apub_receive/src/activities/comment/delete.rs @@ -1,4 +1,4 @@ -use crate::{activities::comment::send_websocket_message, inbox::new_inbox_routing::Activity}; +use crate::activities::{comment::send_websocket_message, LemmyActivity}; use activitystreams::activity::kind::DeleteType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_comment}; @@ -20,7 +20,7 @@ pub struct DeleteComment { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/comment/dislike.rs b/crates/apub_receive/src/activities/comment/dislike.rs index 31738460a..d5aafcd48 100644 --- a/crates/apub_receive/src/activities/comment/dislike.rs +++ b/crates/apub_receive/src/activities/comment/dislike.rs @@ -1,4 +1,4 @@ -use crate::{activities::comment::like_or_dislike_comment, inbox::new_inbox_routing::Activity}; +use crate::activities::{comment::like_or_dislike_comment, LemmyActivity}; use activitystreams::activity::kind::DislikeType; use lemmy_apub::check_is_apub_id_valid; use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; @@ -18,7 +18,7 @@ pub struct DislikeComment { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/comment/like.rs b/crates/apub_receive/src/activities/comment/like.rs index aed8c7ff0..a73067638 100644 --- a/crates/apub_receive/src/activities/comment/like.rs +++ b/crates/apub_receive/src/activities/comment/like.rs @@ -1,4 +1,4 @@ -use crate::{activities::comment::like_or_dislike_comment, inbox::new_inbox_routing::Activity}; +use crate::activities::{comment::like_or_dislike_comment, LemmyActivity}; use activitystreams::activity::kind::LikeType; use lemmy_apub::check_is_apub_id_valid; use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; @@ -18,7 +18,7 @@ pub struct LikeComment { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/comment/remove.rs b/crates/apub_receive/src/activities/comment/remove.rs index 108cae649..a12a26c03 100644 --- a/crates/apub_receive/src/activities/comment/remove.rs +++ b/crates/apub_receive/src/activities/comment/remove.rs @@ -1,7 +1,4 @@ -use crate::{ - activities::{comment::send_websocket_message, verify_mod_action}, - inbox::new_inbox_routing::Activity, -}; +use crate::activities::{comment::send_websocket_message, verify_mod_action, LemmyActivity}; use activitystreams::activity::kind::RemoveType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_comment}; @@ -23,7 +20,7 @@ pub struct RemoveComment { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/comment/undo_delete.rs b/crates/apub_receive/src/activities/comment/undo_delete.rs index 123984d3d..b540b6a47 100644 --- a/crates/apub_receive/src/activities/comment/undo_delete.rs +++ b/crates/apub_receive/src/activities/comment/undo_delete.rs @@ -1,6 +1,6 @@ -use crate::{ - activities::comment::{delete::DeleteComment, send_websocket_message}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + comment::{delete::DeleteComment, send_websocket_message}, + LemmyActivity, }; use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; @@ -16,14 +16,14 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoDeleteComment { to: PublicUrl, - object: Activity, + object: LemmyActivity, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/comment/undo_dislike.rs b/crates/apub_receive/src/activities/comment/undo_dislike.rs index 1f916ea5a..72d52c1c3 100644 --- a/crates/apub_receive/src/activities/comment/undo_dislike.rs +++ b/crates/apub_receive/src/activities/comment/undo_dislike.rs @@ -1,6 +1,6 @@ -use crate::{ - activities::comment::{dislike::DislikeComment, undo_like_or_dislike_comment}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + comment::{dislike::DislikeComment, undo_like_or_dislike_comment}, + LemmyActivity, }; use activitystreams::activity::kind::UndoType; use lemmy_apub::check_is_apub_id_valid; @@ -14,14 +14,14 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoDislikeComment { to: PublicUrl, - object: Activity, + object: LemmyActivity, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/comment/undo_like.rs b/crates/apub_receive/src/activities/comment/undo_like.rs index 045dcaf38..df87e1ad3 100644 --- a/crates/apub_receive/src/activities/comment/undo_like.rs +++ b/crates/apub_receive/src/activities/comment/undo_like.rs @@ -1,6 +1,6 @@ -use crate::{ - activities::comment::{like::LikeComment, undo_like_or_dislike_comment}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + comment::{like::LikeComment, undo_like_or_dislike_comment}, + LemmyActivity, }; use activitystreams::activity::kind::UndoType; use lemmy_apub::check_is_apub_id_valid; @@ -14,14 +14,14 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoLikeComment { to: PublicUrl, - object: Activity, + object: LemmyActivity, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/comment/undo_remove.rs b/crates/apub_receive/src/activities/comment/undo_remove.rs index 5303d9a99..094cb36f0 100644 --- a/crates/apub_receive/src/activities/comment/undo_remove.rs +++ b/crates/apub_receive/src/activities/comment/undo_remove.rs @@ -1,9 +1,7 @@ -use crate::{ - activities::{ - comment::{remove::RemoveComment, send_websocket_message}, - verify_mod_action, - }, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + comment::{remove::RemoveComment, send_websocket_message}, + verify_mod_action, + LemmyActivity, }; use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; @@ -19,14 +17,14 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoRemoveComment { to: PublicUrl, - object: Activity, + object: LemmyActivity, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/comment/update.rs b/crates/apub_receive/src/activities/comment/update.rs index 1e1cc0ade..cacaff04a 100644 --- a/crates/apub_receive/src/activities/comment/update.rs +++ b/crates/apub_receive/src/activities/comment/update.rs @@ -1,6 +1,6 @@ -use crate::{ - activities::comment::{get_notif_recipients, send_websocket_message}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + comment::{get_notif_recipients, send_websocket_message}, + LemmyActivity, }; use activitystreams::{activity::kind::UpdateType, base::BaseExt}; use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, ActorType, NoteExt}; @@ -21,7 +21,7 @@ pub struct UpdateComment { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/community/add_mod.rs b/crates/apub_receive/src/activities/community/add_mod.rs index ebdaeddf8..a6e1b9d9b 100644 --- a/crates/apub_receive/src/activities/community/add_mod.rs +++ b/crates/apub_receive/src/activities/community/add_mod.rs @@ -1,6 +1,7 @@ -use crate::{ - activities::{community::verify_add_remove_moderator_target, verify_mod_action}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + community::verify_add_remove_moderator_target, + verify_mod_action, + LemmyActivity, }; use activitystreams::{activity::kind::AddType, base::AnyBase}; use lemmy_api_common::blocking; @@ -31,7 +32,7 @@ pub struct AddMod { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/community/announce.rs b/crates/apub_receive/src/activities/community/announce.rs index 569b88e4a..74a6862cc 100644 --- a/crates/apub_receive/src/activities/community/announce.rs +++ b/crates/apub_receive/src/activities/community/announce.rs @@ -12,15 +12,7 @@ use crate::{ undo_remove::UndoRemoveComment, update::UpdateComment, }, - community::{ - block_user::BlockUserFromCommunity, - delete::DeleteCommunity, - remove::RemoveCommunity, - undo_block_user::UndoBlockUserFromCommunity, - undo_delete::UndoDeleteCommunity, - undo_remove::UndoRemoveCommunity, - update::UpdateCommunity, - }, + community::{block_user::BlockUserFromCommunity, undo_block_user::UndoBlockUserFromCommunity}, post::{ create::CreatePost, delete::DeletePost, @@ -33,8 +25,9 @@ use crate::{ undo_remove::UndoRemovePost, update::UpdatePost, }, + LemmyActivity, }, - inbox::{is_activity_already_known, new_inbox_routing::Activity}, + http::is_activity_already_known, }; use activitystreams::activity::kind::RemoveType; use lemmy_apub::{check_is_apub_id_valid, fetcher::person::get_or_fetch_and_upsert_person}; @@ -66,12 +59,6 @@ pub enum AnnouncableActivities { UndoRemovePost(UndoRemovePost), UndoLikePost(UndoLikePost), UndoDislikePost(UndoDislikePost), - // TODO: which of these get announced? - UpdateCommunity(UpdateCommunity), - DeleteCommunity(DeleteCommunity), - RemoveCommunity(RemoveCommunity), - UndoDeleteCommunity(UndoDeleteCommunity), - UndoRemoveCommunity(UndoRemoveCommunity), BlockUserFromCommunity(BlockUserFromCommunity), UndoBlockUserFromCommunity(UndoBlockUserFromCommunity), } @@ -98,14 +85,14 @@ impl ActivityHandler for AnnouncableActivities { #[serde(rename_all = "camelCase")] pub struct AnnounceActivity { to: PublicUrl, - object: Activity, + object: LemmyActivity, cc: [Url; 1], #[serde(rename = "type")] kind: RemoveType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Community; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/community/block_user.rs b/crates/apub_receive/src/activities/community/block_user.rs index 1e5b14c89..69b2f28d1 100644 --- a/crates/apub_receive/src/activities/community/block_user.rs +++ b/crates/apub_receive/src/activities/community/block_user.rs @@ -1,4 +1,4 @@ -use crate::{activities::verify_mod_action, inbox::new_inbox_routing::Activity}; +use crate::activities::{verify_mod_action, LemmyActivity}; use activitystreams::activity::kind::BlockType; use lemmy_api_common::blocking; use lemmy_apub::{ @@ -31,7 +31,7 @@ pub struct BlockUserFromCommunity { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/community/delete.rs b/crates/apub_receive/src/activities/community/delete.rs index 43900dcd1..d00cb90f8 100644 --- a/crates/apub_receive/src/activities/community/delete.rs +++ b/crates/apub_receive/src/activities/community/delete.rs @@ -1,6 +1,6 @@ -use crate::{ - activities::community::{send_websocket_message, verify_is_community_mod}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + community::{send_websocket_message, verify_is_community_mod}, + LemmyActivity, }; use activitystreams::activity::kind::DeleteType; use lemmy_api_common::blocking; @@ -31,7 +31,7 @@ pub struct DeleteCommunity { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = lemmy_apub::fetcher::Actor; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/community/remove.rs b/crates/apub_receive/src/activities/community/remove.rs index f429014e0..ce3b35dee 100644 --- a/crates/apub_receive/src/activities/community/remove.rs +++ b/crates/apub_receive/src/activities/community/remove.rs @@ -1,4 +1,4 @@ -use crate::{activities::community::send_websocket_message, inbox::new_inbox_routing::Activity}; +use crate::activities::{community::send_websocket_message, LemmyActivity}; use activitystreams::activity::kind::RemoveType; use lemmy_api_common::blocking; use lemmy_apub::check_is_apub_id_valid; @@ -20,7 +20,7 @@ pub struct RemoveCommunity { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = lemmy_apub::fetcher::Actor; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/community/remove_mod.rs b/crates/apub_receive/src/activities/community/remove_mod.rs index 4c047faf6..2225a3457 100644 --- a/crates/apub_receive/src/activities/community/remove_mod.rs +++ b/crates/apub_receive/src/activities/community/remove_mod.rs @@ -1,6 +1,7 @@ -use crate::{ - activities::{community::verify_add_remove_moderator_target, verify_mod_action}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + community::verify_add_remove_moderator_target, + verify_mod_action, + LemmyActivity, }; use activitystreams::{activity::kind::RemoveType, base::AnyBase}; use lemmy_api_common::blocking; @@ -31,7 +32,7 @@ pub struct RemoveMod { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/community/undo_block_user.rs b/crates/apub_receive/src/activities/community/undo_block_user.rs index 7ace537c8..e00979912 100644 --- a/crates/apub_receive/src/activities/community/undo_block_user.rs +++ b/crates/apub_receive/src/activities/community/undo_block_user.rs @@ -1,6 +1,7 @@ -use crate::{ - activities::{community::block_user::BlockUserFromCommunity, verify_mod_action}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + community::block_user::BlockUserFromCommunity, + verify_mod_action, + LemmyActivity, }; use activitystreams::activity::kind::BlockType; use lemmy_api_common::blocking; @@ -22,14 +23,14 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoBlockUserFromCommunity { to: PublicUrl, - object: Activity, + object: LemmyActivity, cc: [Url; 1], #[serde(rename = "type")] kind: BlockType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/community/undo_delete.rs b/crates/apub_receive/src/activities/community/undo_delete.rs index 717647c71..739347960 100644 --- a/crates/apub_receive/src/activities/community/undo_delete.rs +++ b/crates/apub_receive/src/activities/community/undo_delete.rs @@ -1,10 +1,6 @@ -use crate::{ - activities::community::{ - delete::DeleteCommunity, - send_websocket_message, - verify_is_community_mod, - }, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + community::{delete::DeleteCommunity, send_websocket_message, verify_is_community_mod}, + LemmyActivity, }; use activitystreams::activity::kind::DeleteType; use lemmy_api_common::blocking; @@ -28,14 +24,14 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoDeleteCommunity { to: PublicUrl, - object: Activity, + object: LemmyActivity, cc: [Url; 1], #[serde(rename = "type")] kind: DeleteType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = lemmy_apub::fetcher::Actor; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/community/undo_remove.rs b/crates/apub_receive/src/activities/community/undo_remove.rs index a251eea0c..9f1e5a68a 100644 --- a/crates/apub_receive/src/activities/community/undo_remove.rs +++ b/crates/apub_receive/src/activities/community/undo_remove.rs @@ -1,6 +1,6 @@ -use crate::{ - activities::community::{remove::RemoveCommunity, send_websocket_message}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + community::{remove::RemoveCommunity, send_websocket_message}, + LemmyActivity, }; use activitystreams::activity::kind::RemoveType; use lemmy_api_common::blocking; @@ -16,14 +16,14 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoRemoveCommunity { to: PublicUrl, - object: Activity, + object: LemmyActivity, cc: [Url; 1], #[serde(rename = "type")] kind: RemoveType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = lemmy_apub::fetcher::Actor; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/community/update.rs b/crates/apub_receive/src/activities/community/update.rs index 6d5773743..05ee02096 100644 --- a/crates/apub_receive/src/activities/community/update.rs +++ b/crates/apub_receive/src/activities/community/update.rs @@ -1,6 +1,6 @@ -use crate::{ - activities::community::{send_websocket_message, verify_is_community_mod}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + community::{send_websocket_message, verify_is_community_mod}, + LemmyActivity, }; use activitystreams::{activity::kind::UpdateType, base::BaseExt}; use lemmy_api_common::blocking; @@ -28,7 +28,7 @@ pub struct UpdateCommunity { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/follow/accept.rs b/crates/apub_receive/src/activities/following/accept.rs similarity index 87% rename from crates/apub_receive/src/activities/follow/accept.rs rename to crates/apub_receive/src/activities/following/accept.rs index dde9b951c..389d0a0e9 100644 --- a/crates/apub_receive/src/activities/follow/accept.rs +++ b/crates/apub_receive/src/activities/following/accept.rs @@ -1,4 +1,4 @@ -use crate::{activities::follow::follow::FollowCommunity, inbox::new_inbox_routing::Activity}; +use crate::activities::{following::follow::FollowCommunity, LemmyActivity}; use activitystreams::activity::kind::AcceptType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::person::get_or_fetch_and_upsert_person}; @@ -13,14 +13,14 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct AcceptFollowCommunity { to: Url, - object: Activity, + object: LemmyActivity, #[serde(rename = "type")] kind: AcceptType, } /// Handle accepted follows #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Community; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/follow/follow.rs b/crates/apub_receive/src/activities/following/follow.rs similarity index 93% rename from crates/apub_receive/src/activities/follow/follow.rs rename to crates/apub_receive/src/activities/following/follow.rs index 2d82bed40..dcf691d8f 100644 --- a/crates/apub_receive/src/activities/follow/follow.rs +++ b/crates/apub_receive/src/activities/following/follow.rs @@ -1,4 +1,4 @@ -use crate::inbox::new_inbox_routing::Activity; +use crate::activities::LemmyActivity; use activitystreams::{ activity::{kind::FollowType, Follow}, base::{AnyBase, ExtendsExt}, @@ -24,13 +24,13 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct FollowCommunity { to: Url, - pub(in crate::activities::follow) object: Url, + pub(in crate::activities::following) object: Url, #[serde(rename = "type")] kind: FollowType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/follow/mod.rs b/crates/apub_receive/src/activities/following/mod.rs similarity index 100% rename from crates/apub_receive/src/activities/follow/mod.rs rename to crates/apub_receive/src/activities/following/mod.rs diff --git a/crates/apub_receive/src/activities/follow/undo.rs b/crates/apub_receive/src/activities/following/undo.rs similarity index 89% rename from crates/apub_receive/src/activities/follow/undo.rs rename to crates/apub_receive/src/activities/following/undo.rs index e70ddd0aa..83a184ece 100644 --- a/crates/apub_receive/src/activities/follow/undo.rs +++ b/crates/apub_receive/src/activities/following/undo.rs @@ -1,4 +1,4 @@ -use crate::{activities::follow::follow::FollowCommunity, inbox::new_inbox_routing::Activity}; +use crate::activities::{following::follow::FollowCommunity, LemmyActivity}; use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::community::get_or_fetch_and_upsert_community}; @@ -16,13 +16,13 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoFollowCommunity { to: Url, - object: Activity, + object: LemmyActivity, #[serde(rename = "type")] kind: UndoType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/mod.rs b/crates/apub_receive/src/activities/mod.rs index daae53412..b46b3be2d 100644 --- a/crates/apub_receive/src/activities/mod.rs +++ b/crates/apub_receive/src/activities/mod.rs @@ -1,3 +1,4 @@ +use activitystreams::{base::AnyBase, primitives::OneOrMany, unparsed::Unparsed}; use anyhow::anyhow; use lemmy_api_common::blocking; use lemmy_db_queries::ApubObject; @@ -9,10 +10,33 @@ use url::Url; pub mod comment; pub mod community; -pub mod follow; +pub mod following; pub mod post; pub mod private_message; +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +#[serde(rename_all = "camelCase")] +pub struct LemmyActivity { + #[serde(rename = "@context")] + context: OneOrMany, + id: Url, + pub(crate) actor: Url, + + /// type-specific fields + #[serde(flatten)] + pub inner: Kind, + + // unparsed fields + #[serde(flatten)] + unparsed: Unparsed, +} + +impl LemmyActivity { + pub fn id_unchecked(&self) -> &Url { + &self.id + } +} + async fn verify_mod_action( actor_id: Url, activity_cc: Url, @@ -25,7 +49,7 @@ async fn verify_mod_action( if community.local { let actor = blocking(&context.pool(), move |conn| { - Person::read_from_apub_id(&conn, &actor_id.clone().into()) + Person::read_from_apub_id(&conn, &actor_id.into()) }) .await??; diff --git a/crates/apub_receive/src/activities/post/create.rs b/crates/apub_receive/src/activities/post/create.rs index 0b6080ffc..d74bd4884 100644 --- a/crates/apub_receive/src/activities/post/create.rs +++ b/crates/apub_receive/src/activities/post/create.rs @@ -1,4 +1,4 @@ -use crate::{activities::post::send_websocket_message, inbox::new_inbox_routing::Activity}; +use crate::activities::{post::send_websocket_message, LemmyActivity}; use activitystreams::{activity::kind::CreateType, base::BaseExt}; use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, ActorType, PageExt}; use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; @@ -18,7 +18,7 @@ pub struct CreatePost { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/post/delete.rs b/crates/apub_receive/src/activities/post/delete.rs index 17c5a4d3a..274c6a341 100644 --- a/crates/apub_receive/src/activities/post/delete.rs +++ b/crates/apub_receive/src/activities/post/delete.rs @@ -1,4 +1,4 @@ -use crate::{activities::post::send_websocket_message, inbox::new_inbox_routing::Activity}; +use crate::activities::{post::send_websocket_message, LemmyActivity}; use activitystreams::activity::kind::DeleteType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_post}; @@ -20,7 +20,7 @@ pub struct DeletePost { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/post/dislike.rs b/crates/apub_receive/src/activities/post/dislike.rs index 11e0c75f7..63c34731e 100644 --- a/crates/apub_receive/src/activities/post/dislike.rs +++ b/crates/apub_receive/src/activities/post/dislike.rs @@ -1,4 +1,4 @@ -use crate::{activities::post::like_or_dislike_post, inbox::new_inbox_routing::Activity}; +use crate::activities::{post::like_or_dislike_post, LemmyActivity}; use activitystreams::activity::kind::DislikeType; use lemmy_apub::check_is_apub_id_valid; use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; @@ -18,7 +18,7 @@ pub struct DislikePost { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/post/like.rs b/crates/apub_receive/src/activities/post/like.rs index 714627911..9cd16ec73 100644 --- a/crates/apub_receive/src/activities/post/like.rs +++ b/crates/apub_receive/src/activities/post/like.rs @@ -1,4 +1,4 @@ -use crate::{activities::post::like_or_dislike_post, inbox::new_inbox_routing::Activity}; +use crate::activities::{post::like_or_dislike_post, LemmyActivity}; use activitystreams::activity::kind::LikeType; use lemmy_apub::check_is_apub_id_valid; use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl}; @@ -18,7 +18,7 @@ pub struct LikePost { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/post/remove.rs b/crates/apub_receive/src/activities/post/remove.rs index c0b20e17c..7f8e62b45 100644 --- a/crates/apub_receive/src/activities/post/remove.rs +++ b/crates/apub_receive/src/activities/post/remove.rs @@ -1,7 +1,4 @@ -use crate::{ - activities::{post::send_websocket_message, verify_mod_action}, - inbox::new_inbox_routing::Activity, -}; +use crate::activities::{post::send_websocket_message, verify_mod_action, LemmyActivity}; use activitystreams::activity::kind::RemoveType; use lemmy_api_common::blocking; use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_post}; @@ -23,7 +20,7 @@ pub struct RemovePost { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/post/undo_delete.rs b/crates/apub_receive/src/activities/post/undo_delete.rs index d50d0d743..814c928c6 100644 --- a/crates/apub_receive/src/activities/post/undo_delete.rs +++ b/crates/apub_receive/src/activities/post/undo_delete.rs @@ -1,6 +1,6 @@ -use crate::{ - activities::post::{delete::DeletePost, send_websocket_message}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + post::{delete::DeletePost, send_websocket_message}, + LemmyActivity, }; use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; @@ -16,14 +16,14 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoDeletePost { to: PublicUrl, - object: Activity, + object: LemmyActivity, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/post/undo_dislike.rs b/crates/apub_receive/src/activities/post/undo_dislike.rs index 2c6144f22..d1484be38 100644 --- a/crates/apub_receive/src/activities/post/undo_dislike.rs +++ b/crates/apub_receive/src/activities/post/undo_dislike.rs @@ -1,6 +1,6 @@ -use crate::{ - activities::post::{dislike::DislikePost, undo_like_or_dislike_post}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + post::{dislike::DislikePost, undo_like_or_dislike_post}, + LemmyActivity, }; use activitystreams::activity::kind::UndoType; use lemmy_apub::check_is_apub_id_valid; @@ -14,14 +14,14 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoDislikePost { to: PublicUrl, - object: Activity, + object: LemmyActivity, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/post/undo_like.rs b/crates/apub_receive/src/activities/post/undo_like.rs index 94ab36c9b..bc05cf6ca 100644 --- a/crates/apub_receive/src/activities/post/undo_like.rs +++ b/crates/apub_receive/src/activities/post/undo_like.rs @@ -1,6 +1,6 @@ -use crate::{ - activities::post::{like::LikePost, undo_like_or_dislike_post}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + post::{like::LikePost, undo_like_or_dislike_post}, + LemmyActivity, }; use activitystreams::activity::kind::UndoType; use lemmy_apub::check_is_apub_id_valid; @@ -14,13 +14,13 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoLikePost { to: PublicUrl, - object: Activity, + object: LemmyActivity, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/post/undo_remove.rs b/crates/apub_receive/src/activities/post/undo_remove.rs index 248202d72..252ef7e73 100644 --- a/crates/apub_receive/src/activities/post/undo_remove.rs +++ b/crates/apub_receive/src/activities/post/undo_remove.rs @@ -1,9 +1,7 @@ -use crate::{ - activities::{ - post::{remove::RemovePost, send_websocket_message}, - verify_mod_action, - }, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + post::{remove::RemovePost, send_websocket_message}, + verify_mod_action, + LemmyActivity, }; use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; @@ -19,14 +17,14 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoRemovePost { to: PublicUrl, - object: Activity, + object: LemmyActivity, cc: [Url; 1], #[serde(rename = "type")] kind: UndoType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/post/update.rs b/crates/apub_receive/src/activities/post/update.rs index 198b29b32..bd03f45a7 100644 --- a/crates/apub_receive/src/activities/post/update.rs +++ b/crates/apub_receive/src/activities/post/update.rs @@ -1,4 +1,4 @@ -use crate::{activities::post::send_websocket_message, inbox::new_inbox_routing::Activity}; +use crate::activities::{post::send_websocket_message, LemmyActivity}; use activitystreams::{activity::kind::UpdateType, base::BaseExt}; use anyhow::Context; use lemmy_api_common::blocking; @@ -33,7 +33,7 @@ pub struct UpdatePost { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/private_message/create.rs b/crates/apub_receive/src/activities/private_message/create.rs index 8e70b256a..27889ddf8 100644 --- a/crates/apub_receive/src/activities/private_message/create.rs +++ b/crates/apub_receive/src/activities/private_message/create.rs @@ -1,7 +1,4 @@ -use crate::{ - activities::private_message::send_websocket_message, - inbox::new_inbox_routing::Activity, -}; +use crate::activities::{private_message::send_websocket_message, LemmyActivity}; use activitystreams::{activity::kind::CreateType, base::BaseExt}; use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, ActorType, NoteExt}; use lemmy_apub_lib::{verify_domains_match, ActivityHandler}; @@ -20,7 +17,7 @@ pub struct CreatePrivateMessage { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/private_message/delete.rs b/crates/apub_receive/src/activities/private_message/delete.rs index abad6d707..61e52fc8d 100644 --- a/crates/apub_receive/src/activities/private_message/delete.rs +++ b/crates/apub_receive/src/activities/private_message/delete.rs @@ -1,7 +1,4 @@ -use crate::{ - activities::private_message::send_websocket_message, - inbox::new_inbox_routing::Activity, -}; +use crate::activities::{private_message::send_websocket_message, LemmyActivity}; use activitystreams::activity::kind::DeleteType; use lemmy_api_common::blocking; use lemmy_apub::check_is_apub_id_valid; @@ -22,7 +19,7 @@ pub struct DeletePrivateMessage { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/private_message/undo_delete.rs b/crates/apub_receive/src/activities/private_message/undo_delete.rs index 7f5f923e9..8a169fab8 100644 --- a/crates/apub_receive/src/activities/private_message/undo_delete.rs +++ b/crates/apub_receive/src/activities/private_message/undo_delete.rs @@ -1,6 +1,6 @@ -use crate::{ - activities::private_message::{delete::DeletePrivateMessage, send_websocket_message}, - inbox::new_inbox_routing::Activity, +use crate::activities::{ + private_message::{delete::DeletePrivateMessage, send_websocket_message}, + LemmyActivity, }; use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; @@ -16,13 +16,13 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoDeletePrivateMessage { to: Url, - object: Activity, + object: LemmyActivity, #[serde(rename = "type")] kind: UndoType, } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/activities/private_message/update.rs b/crates/apub_receive/src/activities/private_message/update.rs index 790a317a9..d535b9d7a 100644 --- a/crates/apub_receive/src/activities/private_message/update.rs +++ b/crates/apub_receive/src/activities/private_message/update.rs @@ -1,7 +1,4 @@ -use crate::{ - activities::private_message::send_websocket_message, - inbox::new_inbox_routing::Activity, -}; +use crate::activities::{private_message::send_websocket_message, LemmyActivity}; use activitystreams::{activity::kind::UpdateType, base::BaseExt}; use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, ActorType, NoteExt}; use lemmy_apub_lib::{verify_domains_match, ActivityHandler}; @@ -20,7 +17,7 @@ pub struct UpdatePrivateMessage { } #[async_trait::async_trait(?Send)] -impl ActivityHandler for Activity { +impl ActivityHandler for LemmyActivity { type Actor = Person; async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub_receive/src/http/community.rs b/crates/apub_receive/src/http/community.rs index 1d5ae906e..18acda428 100644 --- a/crates/apub_receive/src/http/community.rs +++ b/crates/apub_receive/src/http/community.rs @@ -1,10 +1,18 @@ -use crate::http::{create_apub_response, create_apub_tombstone_response}; +use crate::{ + activities::LemmyActivity, + http::{ + create_apub_response, + create_apub_tombstone_response, + inbox_enums::GroupInboxActivities, + receive_activity, + }, +}; use activitystreams::{ base::{AnyBase, BaseExt}, collection::{CollectionExt, OrderedCollection, UnorderedCollection}, url::Url, }; -use actix_web::{body::Body, web, HttpResponse}; +use actix_web::{body::Body, web, HttpRequest, HttpResponse}; use lemmy_api_common::blocking; use lemmy_apub::{ extensions::context::lemmy_context, @@ -46,6 +54,16 @@ pub(crate) async fn get_apub_community_http( } } +/// Handler for all incoming receive to community inboxes. +pub async fn community_inbox( + request: HttpRequest, + input: web::Json>, + path: web::Path, + context: web::Data, +) -> Result { + receive_activity(request, input.into_inner(), Some(path.0), context).await +} + /// Returns an empty followers collection, only populating the size (for privacy). pub(crate) async fn get_apub_community_followers( info: web::Path, diff --git a/crates/apub_receive/src/inbox/new_inbox_routing.rs b/crates/apub_receive/src/http/inbox_enums.rs similarity index 52% rename from crates/apub_receive/src/inbox/new_inbox_routing.rs rename to crates/apub_receive/src/http/inbox_enums.rs index 7670f8d2b..6aab33244 100644 --- a/crates/apub_receive/src/inbox/new_inbox_routing.rs +++ b/crates/apub_receive/src/http/inbox_enums.rs @@ -23,7 +23,7 @@ use crate::activities::{ undo_remove::UndoRemoveCommunity, update::UpdateCommunity, }, - follow::{accept::AcceptFollowCommunity, follow::FollowCommunity, undo::UndoFollowCommunity}, + following::{accept::AcceptFollowCommunity, follow::FollowCommunity, undo::UndoFollowCommunity}, post::{ create::CreatePost, delete::DeletePost, @@ -43,46 +43,25 @@ use crate::activities::{ update::UpdatePrivateMessage, }, }; -use activitystreams::{base::AnyBase, primitives::OneOrMany, unparsed::Unparsed}; use lemmy_apub_lib::ActivityHandler; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; -use url::Url; +use serde::{Deserialize, Serialize}; -// TODO: would be nice if we could move this to lemmy_apub_lib crate. doing that gives error: -// "only traits defined in the current crate can be implemented for arbitrary types" -#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] -#[serde(rename_all = "camelCase")] -pub struct Activity { - #[serde(rename = "@context")] - context: OneOrMany, - id: Url, - pub(crate) actor: Url, - - /// type-specific fields - #[serde(flatten)] - pub inner: Kind, - - // unparsed fields - #[serde(flatten)] - unparsed: Unparsed, -} - -impl Activity { - pub fn id_unchecked(&self) -> &Url { - &self.id - } -} - -#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] -pub enum SharedInboxActivities { - FollowCommunity(FollowCommunity), +#[derive(Clone, Debug, Deserialize, Serialize)] +pub enum PersonInboxActivities { AcceptFollowCommunity(AcceptFollowCommunity), - UndoFollowCommunity(UndoFollowCommunity), CreatePrivateMessage(CreatePrivateMessage), UpdatePrivateMessage(UpdatePrivateMessage), DeletePrivateMessage(DeletePrivateMessage), UndoDeletePrivateMessage(UndoDeletePrivateMessage), + AnnounceActivity(Box), +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub enum GroupInboxActivities { + FollowCommunity(FollowCommunity), + UndoFollowCommunity(UndoFollowCommunity), CreateComment(CreateComment), UpdateComment(UpdateComment), LikeComment(LikeComment), @@ -103,16 +82,58 @@ pub enum SharedInboxActivities { UndoRemovePost(UndoRemovePost), UndoLikePost(UndoLikePost), UndoDislikePost(UndoDislikePost), - AnnounceActivity(AnnounceActivity), - UpdateCommunity(UpdateCommunity), + UpdateCommunity(Box), DeleteCommunity(DeleteCommunity), RemoveCommunity(RemoveCommunity), - AddMod(AddMod), - RemoveMod(RemoveMod), UndoDeleteCommunity(UndoDeleteCommunity), UndoRemoveCommunity(UndoRemoveCommunity), BlockUserFromCommunity(BlockUserFromCommunity), UndoBlockUserFromCommunity(UndoBlockUserFromCommunity), + AddMod(AddMod), + RemoveMod(RemoveMod), +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub enum SharedInboxActivities { + // received by person + AcceptFollowCommunity(AcceptFollowCommunity), + CreatePrivateMessage(CreatePrivateMessage), + UpdatePrivateMessage(UpdatePrivateMessage), + DeletePrivateMessage(DeletePrivateMessage), + UndoDeletePrivateMessage(UndoDeletePrivateMessage), + AnnounceActivity(Box), + // received by group + FollowCommunity(FollowCommunity), + UndoFollowCommunity(UndoFollowCommunity), + CreateComment(CreateComment), + UpdateComment(UpdateComment), + LikeComment(LikeComment), + DislikeComment(DislikeComment), + UndoLikeComment(UndoLikeComment), + UndoDislikeComment(UndoDislikeComment), + DeleteComment(DeleteComment), + UndoDeleteComment(UndoDeleteComment), + RemoveComment(RemoveComment), + UndoRemoveComment(UndoRemoveComment), + CreatePost(CreatePost), + UpdatePost(UpdatePost), + LikePost(LikePost), + DislikePost(DislikePost), + DeletePost(DeletePost), + UndoDeletePost(UndoDeletePost), + RemovePost(RemovePost), + UndoRemovePost(UndoRemovePost), + UndoLikePost(UndoLikePost), + UndoDislikePost(UndoDislikePost), + UpdateCommunity(Box), + DeleteCommunity(DeleteCommunity), + RemoveCommunity(RemoveCommunity), + UndoDeleteCommunity(UndoDeleteCommunity), + UndoRemoveCommunity(UndoRemoveCommunity), + BlockUserFromCommunity(BlockUserFromCommunity), + UndoBlockUserFromCommunity(UndoBlockUserFromCommunity), + AddMod(AddMod), + RemoveMod(RemoveMod), } #[async_trait::async_trait(?Send)] @@ -132,3 +153,39 @@ impl ActivityHandler for SharedInboxActivities { self.receive(actor, context, request_counter).await } } + +#[async_trait::async_trait(?Send)] +impl ActivityHandler for PersonInboxActivities { + type Actor = lemmy_apub::fetcher::Actor; + + async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { + self.verify(context).await + } + + async fn receive( + &self, + actor: Self::Actor, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + self.receive(actor, context, request_counter).await + } +} + +#[async_trait::async_trait(?Send)] +impl ActivityHandler for GroupInboxActivities { + type Actor = lemmy_apub::fetcher::Actor; + + async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { + self.verify(context).await + } + + async fn receive( + &self, + actor: Self::Actor, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + self.receive(actor, context, request_counter).await + } +} diff --git a/crates/apub_receive/src/http/mod.rs b/crates/apub_receive/src/http/mod.rs index 531c37890..2f40cd65b 100644 --- a/crates/apub_receive/src/http/mod.rs +++ b/crates/apub_receive/src/http/mod.rs @@ -1,19 +1,90 @@ -use actix_web::{body::Body, web, HttpResponse}; +use actix_web::{body::Body, web, HttpRequest, HttpResponse}; use http::StatusCode; -use lemmy_api_common::blocking; -use lemmy_apub::APUB_JSON_CONTENT_TYPE; -use lemmy_db_queries::source::activity::Activity_; -use lemmy_db_schema::source::activity::Activity; -use lemmy_utils::{settings::structs::Settings, LemmyError}; -use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use url::Url; +use crate::{activities::LemmyActivity, http::inbox_enums::SharedInboxActivities}; +use anyhow::{anyhow, Context}; +use lemmy_api_common::blocking; +use lemmy_apub::{ + check_is_apub_id_valid, + extensions::signatures::verify_signature, + fetcher::{get_or_fetch_and_upsert_actor, Actor}, + insert_activity, + APUB_JSON_CONTENT_TYPE, +}; +use lemmy_apub_lib::ActivityHandler; +use lemmy_db_queries::{source::activity::Activity_, DbPool}; +use lemmy_db_schema::source::activity::Activity; +use lemmy_utils::{location_info, settings::structs::Settings, LemmyError}; +use lemmy_websocket::LemmyContext; +use std::fmt::Debug; + pub mod comment; pub mod community; +pub mod inbox_enums; pub mod person; pub mod post; +pub async fn shared_inbox( + request: HttpRequest, + input: web::Json>, + context: web::Data, +) -> Result { + receive_activity(request, input.into_inner(), None, context).await +} + +async fn receive_activity( + request: HttpRequest, + activity: LemmyActivity, + expected_name: Option, + context: web::Data, +) -> Result +where + T: ActivityHandler + + Clone + + Serialize + + std::fmt::Debug + + Send + + 'static, +{ + // TODO: which order to check things? + // Do nothing if we received the same activity before + if is_activity_already_known(context.pool(), &activity.id_unchecked()).await? { + return Ok(HttpResponse::Ok().finish()); + } + assert_activity_not_local(&activity)?; + check_is_apub_id_valid(&activity.actor, false)?; + activity.inner.verify(&context).await?; + + let request_counter = &mut 0; + let actor: Actor = + get_or_fetch_and_upsert_actor(&activity.actor, &context, request_counter).await?; + if let Some(expected) = expected_name { + if expected != actor.name() { + return Ok(HttpResponse::BadRequest().finish()); + } + } + verify_signature(&request, &actor.public_key().context(location_info!())?)?; + + // Log the activity, so we avoid receiving and parsing it twice. Note that this could still happen + // if we receive the same activity twice in very quick succession. + insert_activity( + &activity.id_unchecked(), + activity.clone(), + false, + true, + context.pool(), + ) + .await?; + + activity + .inner + .receive(actor, &context, request_counter) + .await?; + Ok(HttpResponse::Ok().finish()) +} + /// Convert the data to json and turn it into an HTTP Response with the correct ActivityPub /// headers. fn create_apub_response(data: &T) -> HttpResponse @@ -36,14 +107,14 @@ where } #[derive(Deserialize)] -pub struct CommunityQuery { +pub struct ActivityQuery { type_: String, id: String, } -/// Return the ActivityPub json representation of a local community over HTTP. +/// Return the ActivityPub json representation of a local activity over HTTP. pub(crate) async fn get_activity( - info: web::Path, + info: web::Path, context: web::Data, ) -> Result, LemmyError> { let settings = Settings::get(); @@ -66,3 +137,35 @@ pub(crate) async fn get_activity( Ok(create_apub_response(&activity.data)) } } + +pub(crate) async fn is_activity_already_known( + pool: &DbPool, + activity_id: &Url, +) -> Result { + let activity_id = activity_id.to_owned().into(); + let existing = blocking(pool, move |conn| { + Activity::read_from_apub_id(&conn, &activity_id) + }) + .await?; + match existing { + Ok(_) => Ok(true), + Err(_) => Ok(false), + } +} + +pub(in crate::http) fn assert_activity_not_local( + activity: &LemmyActivity, +) -> Result<(), LemmyError> { + let activity_domain = activity.id_unchecked().domain().context(location_info!())?; + + if activity_domain == Settings::get().hostname() { + return Err( + anyhow!( + "Error: received activity which was sent by local instance: {:?}", + activity + ) + .into(), + ); + } + Ok(()) +} diff --git a/crates/apub_receive/src/http/person.rs b/crates/apub_receive/src/http/person.rs index 69598ec2a..b26b88caa 100644 --- a/crates/apub_receive/src/http/person.rs +++ b/crates/apub_receive/src/http/person.rs @@ -1,9 +1,17 @@ -use crate::http::{create_apub_response, create_apub_tombstone_response}; +use crate::{ + activities::LemmyActivity, + http::{ + create_apub_response, + create_apub_tombstone_response, + inbox_enums::PersonInboxActivities, + receive_activity, + }, +}; use activitystreams::{ base::BaseExt, collection::{CollectionExt, OrderedCollection}, }; -use actix_web::{body::Body, web, HttpResponse}; +use actix_web::{body::Body, web, HttpRequest, HttpResponse}; use lemmy_api_common::blocking; use lemmy_apub::{extensions::context::lemmy_context, objects::ToApub, ActorType}; use lemmy_db_queries::source::person::Person_; @@ -39,6 +47,15 @@ pub(crate) async fn get_apub_person_http( } } +pub async fn person_inbox( + request: HttpRequest, + input: web::Json>, + path: web::Path, + context: web::Data, +) -> Result { + receive_activity(request, input.into_inner(), Some(path.0), context).await +} + pub(crate) async fn get_apub_person_outbox( info: web::Path, context: web::Data, diff --git a/crates/apub_receive/src/inbox/community_inbox.rs b/crates/apub_receive/src/inbox/community_inbox.rs deleted file mode 100644 index 310b08097..000000000 --- a/crates/apub_receive/src/inbox/community_inbox.rs +++ /dev/null @@ -1,14 +0,0 @@ -use crate::inbox::new_inbox_routing::{Activity, SharedInboxActivities}; -use actix_web::{web, HttpRequest, HttpResponse}; -use lemmy_utils::LemmyError; -use lemmy_websocket::LemmyContext; - -/// Handler for all incoming receive to community inboxes. -pub async fn community_inbox( - _request: HttpRequest, - _input: web::Json>>, - _path: web::Path, - _context: web::Data, -) -> Result { - todo!() -} diff --git a/crates/apub_receive/src/inbox/mod.rs b/crates/apub_receive/src/inbox/mod.rs deleted file mode 100644 index bb566c8c5..000000000 --- a/crates/apub_receive/src/inbox/mod.rs +++ /dev/null @@ -1,45 +0,0 @@ -use crate::inbox::new_inbox_routing::Activity; -use anyhow::{anyhow, Context}; -use lemmy_api_common::blocking; -use lemmy_db_queries::{source::activity::Activity_, DbPool}; -use lemmy_db_schema::source::activity::Activity as DbActivity; -use lemmy_utils::{location_info, settings::structs::Settings, LemmyError}; -use std::fmt::Debug; -use url::Url; - -pub mod community_inbox; -pub mod new_inbox_routing; -pub mod person_inbox; -pub mod shared_inbox; - -pub(crate) async fn is_activity_already_known( - pool: &DbPool, - activity_id: &Url, -) -> Result { - let activity_id = activity_id.to_owned().into(); - let existing = blocking(pool, move |conn| { - DbActivity::read_from_apub_id(&conn, &activity_id) - }) - .await?; - match existing { - Ok(_) => Ok(true), - Err(_) => Ok(false), - } -} - -pub(in crate::inbox) fn assert_activity_not_local( - activity: &Activity, -) -> Result<(), LemmyError> { - let activity_domain = activity.id_unchecked().domain().context(location_info!())?; - - if activity_domain == Settings::get().hostname() { - return Err( - anyhow!( - "Error: received activity which was sent by local instance: {:?}", - activity - ) - .into(), - ); - } - Ok(()) -} diff --git a/crates/apub_receive/src/inbox/person_inbox.rs b/crates/apub_receive/src/inbox/person_inbox.rs deleted file mode 100644 index e53b6f02c..000000000 --- a/crates/apub_receive/src/inbox/person_inbox.rs +++ /dev/null @@ -1,13 +0,0 @@ -use crate::inbox::new_inbox_routing::{Activity, SharedInboxActivities}; -use actix_web::{web, HttpRequest, HttpResponse}; -use lemmy_utils::LemmyError; -use lemmy_websocket::LemmyContext; - -pub async fn person_inbox( - _request: HttpRequest, - _input: web::Json>>, - _path: web::Path, - _context: web::Data, -) -> Result { - todo!() -} diff --git a/crates/apub_receive/src/inbox/shared_inbox.rs b/crates/apub_receive/src/inbox/shared_inbox.rs deleted file mode 100644 index 971b29d14..000000000 --- a/crates/apub_receive/src/inbox/shared_inbox.rs +++ /dev/null @@ -1,57 +0,0 @@ -use crate::inbox::{ - assert_activity_not_local, - is_activity_already_known, - new_inbox_routing::{Activity, SharedInboxActivities}, -}; -use actix_web::{web, HttpRequest, HttpResponse}; -use anyhow::Context; -use lemmy_apub::{ - check_is_apub_id_valid, - extensions::signatures::verify_signature, - fetcher::{get_or_fetch_and_upsert_actor2, Actor}, - insert_activity, -}; -use lemmy_apub_lib::ActivityHandler; -use lemmy_utils::{location_info, LemmyError}; -use lemmy_websocket::LemmyContext; - -pub async fn shared_inbox( - request: HttpRequest, - input: web::Json>, - context: web::Data, -) -> Result { - let activity = input.into_inner(); - - // Do nothing if we received the same activity before - if is_activity_already_known(context.pool(), &activity.id_unchecked()).await? { - return Ok(HttpResponse::Ok().finish()); - } - assert_activity_not_local(&activity)?; - check_is_apub_id_valid(&activity.actor, false)?; - activity.inner.verify(&context).await?; - - let request_counter = &mut 0; - let actor = get_or_fetch_and_upsert_actor2(&activity.actor, &context, request_counter).await?; - let public_key = match &actor { - Actor::Person(p) => p.public_key.as_ref().context(location_info!())?, - Actor::Community(c) => c.public_key.as_ref().context(location_info!())?, - }; - verify_signature(&request, &public_key)?; - - // Log the activity, so we avoid receiving and parsing it twice. Note that this could still happen - // if we receive the same activity twice in very quick succession. - insert_activity( - &activity.id_unchecked(), - activity.clone(), - false, - true, - context.pool(), - ) - .await?; - - activity - .inner - .receive(actor, &context, request_counter) - .await?; - return Ok(HttpResponse::Ok().finish()); -} diff --git a/crates/apub_receive/src/lib.rs b/crates/apub_receive/src/lib.rs index 849369e79..d6b772a05 100644 --- a/crates/apub_receive/src/lib.rs +++ b/crates/apub_receive/src/lib.rs @@ -1,4 +1,3 @@ -pub mod activities; +mod activities; mod http; -mod inbox; pub mod routes; diff --git a/crates/apub_receive/src/routes.rs b/crates/apub_receive/src/routes.rs index d112afbea..929df38bb 100644 --- a/crates/apub_receive/src/routes.rs +++ b/crates/apub_receive/src/routes.rs @@ -1,22 +1,17 @@ -use crate::{ - http::{ - comment::get_apub_comment, - community::{ - get_apub_community_followers, - get_apub_community_http, - get_apub_community_inbox, - get_apub_community_moderators, - get_apub_community_outbox, - }, - get_activity, - person::{get_apub_person_http, get_apub_person_inbox, get_apub_person_outbox}, - post::get_apub_post, - }, - inbox::{ - community_inbox::community_inbox, - person_inbox::person_inbox, - shared_inbox::shared_inbox, +use crate::http::{ + comment::get_apub_comment, + community::{ + community_inbox, + get_apub_community_followers, + get_apub_community_http, + get_apub_community_inbox, + get_apub_community_moderators, + get_apub_community_outbox, }, + get_activity, + person::{get_apub_person_http, get_apub_person_inbox, get_apub_person_outbox, person_inbox}, + post::get_apub_post, + shared_inbox, }; use actix_web::*; use http_signature_normalization_actix::digest::middleware::VerifyDigest;