From bd3352423a792bb8a6c14c1970a9a4822a27546a Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Wed, 3 Nov 2021 18:33:51 +0100 Subject: [PATCH] Remove ActivityFields trait, deserialize into another struct instead --- .../activities/comment/create_or_update.rs | 30 +++-- .../apub/src/activities/community/add_mod.rs | 2 +- .../apub/src/activities/community/announce.rs | 14 ++- .../src/activities/community/block_user.rs | 2 +- .../src/activities/community/remove_mod.rs | 2 +- .../apub/src/activities/community/report.rs | 28 ++--- .../activities/community/undo_block_user.rs | 2 +- .../apub/src/activities/community/update.rs | 2 +- crates/apub/src/activities/deletion/delete.rs | 38 +++--- crates/apub/src/activities/deletion/mod.rs | 38 +++--- .../src/activities/deletion/undo_delete.rs | 36 +++--- .../apub/src/activities/following/accept.rs | 8 +- .../apub/src/activities/following/follow.rs | 2 +- .../src/activities/following/undo_follow.rs | 6 +- crates/apub/src/activities/mod.rs | 8 +- .../src/activities/post/create_or_update.rs | 30 +++-- .../private_message/create_or_update.rs | 2 +- .../src/activities/private_message/delete.rs | 2 +- .../activities/private_message/undo_delete.rs | 8 +- .../apub/src/activities/voting/undo_vote.rs | 29 ++--- crates/apub/src/activities/voting/vote.rs | 33 +++-- crates/apub/src/activity_lists.rs | 10 +- crates/apub/src/fetcher/mod.rs | 32 +---- crates/apub/src/fetcher/post_or_comment.rs | 30 ++--- crates/apub/src/fetcher/user_or_community.rs | 113 ++++++++++++++++++ crates/apub/src/http/community.rs | 11 +- crates/apub/src/http/mod.rs | 44 ++++--- crates/apub/src/http/person.rs | 7 +- .../protocol/activities/community/add_mod.rs | 3 +- .../protocol/activities/community/announce.rs | 3 +- .../activities/community/block_user.rs | 3 +- .../activities/community/remove_mod.rs | 3 +- .../protocol/activities/community/report.rs | 3 +- .../activities/community/undo_block_user.rs | 3 +- .../protocol/activities/community/update.rs | 3 +- .../activities/create_or_update/comment.rs | 3 +- .../activities/create_or_update/post.rs | 3 +- .../protocol/activities/deletion/delete.rs | 3 +- .../activities/deletion/undo_delete.rs | 11 +- .../protocol/activities/following/accept.rs | 3 +- .../protocol/activities/following/follow.rs | 3 +- .../activities/following/undo_follow.rs | 3 +- .../private_message/create_or_update.rs | 3 +- .../activities/private_message/delete.rs | 3 +- .../activities/private_message/undo_delete.rs | 3 +- .../protocol/activities/voting/undo_vote.rs | 11 +- .../src/protocol/activities/voting/vote.rs | 3 +- crates/apub_lib/src/traits.rs | 5 - crates/apub_lib_derive/src/lib.rs | 37 ------ 49 files changed, 344 insertions(+), 340 deletions(-) create mode 100644 crates/apub/src/fetcher/user_or_community.rs diff --git a/crates/apub/src/activities/comment/create_or_update.rs b/crates/apub/src/activities/comment/create_or_update.rs index 10666932..84f6d3f2 100644 --- a/crates/apub/src/activities/comment/create_or_update.rs +++ b/crates/apub/src/activities/comment/create_or_update.rs @@ -1,18 +1,3 @@ -use activitystreams::public; - -use lemmy_api_common::{blocking, check_post_deleted_or_removed}; -use lemmy_apub_lib::{ - data::Data, - traits::{ActivityHandler, ActorType, ApubObject}, - verify::verify_domains_match, -}; -use lemmy_db_schema::{ - source::{community::Community, post::Post}, - traits::Crud, -}; -use lemmy_utils::LemmyError; -use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperationCrud}; - use crate::{ activities::{ check_community_deleted_or_removed, @@ -28,6 +13,19 @@ use crate::{ objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson}, protocol::activities::{create_or_update::comment::CreateOrUpdateComment, CreateOrUpdateType}, }; +use activitystreams::public; +use lemmy_api_common::{blocking, check_post_deleted_or_removed}; +use lemmy_apub_lib::{ + data::Data, + traits::{ActivityHandler, ActorType, ApubObject}, + verify::verify_domains_match, +}; +use lemmy_db_schema::{ + source::{community::Community, post::Post}, + traits::Crud, +}; +use lemmy_utils::LemmyError; +use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperationCrud}; impl CreateOrUpdateComment { pub async fn send( @@ -81,7 +79,7 @@ impl ActivityHandler for CreateOrUpdateComment { let post = self.object.get_parents(context, request_counter).await?.0; let community = self.get_community(context, request_counter).await?; - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; verify_person_in_community(&self.actor, &community, context, request_counter).await?; verify_domains_match(self.actor.inner(), self.object.id.inner())?; check_community_deleted_or_removed(&community)?; diff --git a/crates/apub/src/activities/community/add_mod.rs b/crates/apub/src/activities/community/add_mod.rs index b18e50ad..11dc5a0b 100644 --- a/crates/apub/src/activities/community/add_mod.rs +++ b/crates/apub/src/activities/community/add_mod.rs @@ -65,7 +65,7 @@ impl ActivityHandler for AddMod { request_counter: &mut i32, ) -> Result<(), LemmyError> { verify_is_public(&self.to)?; - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; let community = self.get_community(context, request_counter).await?; verify_person_in_community(&self.actor, &community, context, request_counter).await?; verify_mod_action(&self.actor, &community, context, request_counter).await?; diff --git a/crates/apub/src/activities/community/announce.rs b/crates/apub/src/activities/community/announce.rs index f560b09f..b245a1b8 100644 --- a/crates/apub/src/activities/community/announce.rs +++ b/crates/apub/src/activities/community/announce.rs @@ -2,7 +2,7 @@ use crate::{ activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_is_public}, activity_lists::AnnouncableActivities, fetcher::object_id::ObjectId, - http::is_activity_already_known, + http::{is_activity_already_known, ActivityCommonFields}, insert_activity, objects::community::ApubCommunity, protocol::activities::community::announce::AnnounceActivity, @@ -10,7 +10,7 @@ use crate::{ use activitystreams::{activity::kind::AnnounceType, public}; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityHandler, ActorType}, }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; @@ -60,7 +60,7 @@ impl ActivityHandler for AnnounceActivity { request_counter: &mut i32, ) -> Result<(), LemmyError> { verify_is_public(&self.to)?; - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; self.object.verify(context, request_counter).await?; Ok(()) } @@ -70,11 +70,15 @@ impl ActivityHandler for AnnounceActivity { context: &Data, request_counter: &mut i32, ) -> Result<(), LemmyError> { - if is_activity_already_known(context.pool(), self.object.id_unchecked()).await? { + // TODO: this is pretty ugly, but i cant think of a much better way + let object = serde_json::to_string(&self.object)?; + let object_data: ActivityCommonFields = serde_json::from_str(&object)?; + + if is_activity_already_known(context.pool(), &object_data.id).await? { return Ok(()); } insert_activity( - self.object.id_unchecked(), + &object_data.id, self.object.clone(), false, true, diff --git a/crates/apub/src/activities/community/block_user.rs b/crates/apub/src/activities/community/block_user.rs index dfe6c4c9..d756ed25 100644 --- a/crates/apub/src/activities/community/block_user.rs +++ b/crates/apub/src/activities/community/block_user.rs @@ -76,7 +76,7 @@ impl ActivityHandler for BlockUserFromCommunity { request_counter: &mut i32, ) -> Result<(), LemmyError> { verify_is_public(&self.to)?; - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; let community = self.get_community(context, request_counter).await?; verify_person_in_community(&self.actor, &community, context, request_counter).await?; verify_mod_action(&self.actor, &community, context, request_counter).await?; diff --git a/crates/apub/src/activities/community/remove_mod.rs b/crates/apub/src/activities/community/remove_mod.rs index 02ff3c06..1c79e70d 100644 --- a/crates/apub/src/activities/community/remove_mod.rs +++ b/crates/apub/src/activities/community/remove_mod.rs @@ -64,7 +64,7 @@ impl ActivityHandler for RemoveMod { request_counter: &mut i32, ) -> Result<(), LemmyError> { verify_is_public(&self.to)?; - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; let community = self.get_community(context, request_counter).await?; verify_person_in_community(&self.actor, &community, context, request_counter).await?; verify_mod_action(&self.actor, &community, context, request_counter).await?; diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index 1e7cc5fa..5b02490b 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -1,5 +1,16 @@ +use crate::{ + activities::{ + generate_activity_id, + send_lemmy_activity, + verify_activity, + verify_person_in_community, + }, + fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::community::report::Report, + PostOrComment, +}; use activitystreams::activity::kind::FlagType; - use lemmy_api_common::{blocking, comment::CommentReportResponse, post::PostReportResponse}; use lemmy_apub_lib::{ data::Data, @@ -16,19 +27,6 @@ use lemmy_db_views::{comment_report_view::CommentReportView, post_report_view::P use lemmy_utils::LemmyError; use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation}; -use crate::{ - activities::{ - generate_activity_id, - send_lemmy_activity, - verify_activity, - verify_person_in_community, - }, - fetcher::object_id::ObjectId, - objects::{community::ApubCommunity, person::ApubPerson}, - protocol::activities::community::report::Report, - PostOrComment, -}; - impl Report { pub async fn send( object_id: ObjectId, @@ -72,7 +70,7 @@ impl ActivityHandler for Report { context: &Data, request_counter: &mut i32, ) -> Result<(), LemmyError> { - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; let community = self.to[0].dereference(context, request_counter).await?; verify_person_in_community(&self.actor, &community, context, request_counter).await?; Ok(()) diff --git a/crates/apub/src/activities/community/undo_block_user.rs b/crates/apub/src/activities/community/undo_block_user.rs index 2bda9444..467237eb 100644 --- a/crates/apub/src/activities/community/undo_block_user.rs +++ b/crates/apub/src/activities/community/undo_block_user.rs @@ -66,7 +66,7 @@ impl ActivityHandler for UndoBlockUserFromCommunity { request_counter: &mut i32, ) -> Result<(), LemmyError> { verify_is_public(&self.to)?; - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; let community = self.get_community(context, request_counter).await?; verify_person_in_community(&self.actor, &community, context, request_counter).await?; verify_mod_action(&self.actor, &community, context, request_counter).await?; diff --git a/crates/apub/src/activities/community/update.rs b/crates/apub/src/activities/community/update.rs index 28de0db0..9acb8909 100644 --- a/crates/apub/src/activities/community/update.rs +++ b/crates/apub/src/activities/community/update.rs @@ -59,7 +59,7 @@ impl ActivityHandler for UpdateCommunity { request_counter: &mut i32, ) -> Result<(), LemmyError> { verify_is_public(&self.to)?; - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; let community = self.get_community(context, request_counter).await?; verify_person_in_community(&self.actor, &community, context, request_counter).await?; verify_mod_action(&self.actor, &community, context, request_counter).await?; diff --git a/crates/apub/src/activities/deletion/delete.rs b/crates/apub/src/activities/deletion/delete.rs index a4112a0a..605daf8f 100644 --- a/crates/apub/src/activities/deletion/delete.rs +++ b/crates/apub/src/activities/deletion/delete.rs @@ -1,7 +1,22 @@ +use crate::{ + activities::{ + community::{announce::GetCommunity, send_to_community}, + deletion::{ + receive_delete_action, + verify_delete_activity, + DeletableObjects, + }, + generate_activity_id, + verify_activity, + verify_is_public, + }, + activity_lists::AnnouncableActivities, + fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::deletion::delete::Delete, +}; use activitystreams::{activity::kind::DeleteType, public}; use anyhow::anyhow; -use url::Url; - use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, @@ -29,20 +44,7 @@ use lemmy_websocket::{ LemmyContext, UserOperationCrud, }; - -use crate::{ - activities::{ - community::{announce::GetCommunity, send_to_community}, - deletion::{receive_delete_action, verify_delete_activity, DeletableObjects}, - generate_activity_id, - verify_activity, - verify_is_public, - }, - activity_lists::AnnouncableActivities, - fetcher::object_id::ObjectId, - objects::{community::ApubCommunity, person::ApubPerson}, - protocol::activities::deletion::delete::Delete, -}; +use url::Url; #[async_trait::async_trait(?Send)] impl ActivityHandler for Delete { @@ -53,11 +55,11 @@ impl ActivityHandler for Delete { request_counter: &mut i32, ) -> Result<(), LemmyError> { verify_is_public(&self.to)?; - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; let community = self.get_community(context, request_counter).await?; verify_delete_activity( &self.object, - self, + &self.actor, &community, self.summary.is_some(), context, diff --git a/crates/apub/src/activities/deletion/mod.rs b/crates/apub/src/activities/deletion/mod.rs index 3e9a7a3a..1be3bccf 100644 --- a/crates/apub/src/activities/deletion/mod.rs +++ b/crates/apub/src/activities/deletion/mod.rs @@ -1,8 +1,12 @@ -use url::Url; - +use crate::{ + activities::{verify_mod_action, verify_person_in_community}, + fetcher::object_id::ObjectId, + objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost}, + protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete}, +}; use lemmy_api_common::blocking; use lemmy_apub_lib::{ - traits::{ActivityFields, ActorType, ApubObject}, + traits::{ActorType, ApubObject}, verify::verify_domains_match, }; use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post}; @@ -12,13 +16,7 @@ use lemmy_websocket::{ LemmyContext, UserOperationCrud, }; - -use crate::{ - activities::{verify_mod_action, verify_person_in_community}, - fetcher::object_id::ObjectId, - objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost}, - protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete}, -}; +use url::Url; pub mod delete; pub mod undo_delete; @@ -80,27 +78,26 @@ impl DeletableObjects { pub(in crate::activities) async fn verify_delete_activity( object: &Url, - activity: &dyn ActivityFields, + actor: &ObjectId, community: &ApubCommunity, is_mod_action: bool, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { let object = DeletableObjects::read_from_db(object, context).await?; - let actor = ObjectId::new(activity.actor().clone()); match object { DeletableObjects::Community(community) => { if community.local { // can only do this check for local community, in remote case it would try to fetch the // deleted community (which fails) - verify_person_in_community(&actor, &community, context, request_counter).await?; + verify_person_in_community(actor, &community, context, request_counter).await?; } // community deletion is always a mod (or admin) action - verify_mod_action(&actor, &community, context, request_counter).await?; + verify_mod_action(actor, &community, context, request_counter).await?; } DeletableObjects::Post(p) => { verify_delete_activity_post_or_comment( - activity, + actor, &p.ap_id.clone().into(), community, is_mod_action, @@ -111,7 +108,7 @@ pub(in crate::activities) async fn verify_delete_activity( } DeletableObjects::Comment(c) => { verify_delete_activity_post_or_comment( - activity, + actor, &c.ap_id.clone().into(), community, is_mod_action, @@ -125,20 +122,19 @@ pub(in crate::activities) async fn verify_delete_activity( } async fn verify_delete_activity_post_or_comment( - activity: &dyn ActivityFields, + actor: &ObjectId, object_id: &Url, community: &ApubCommunity, is_mod_action: bool, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - let actor = ObjectId::new(activity.actor().clone()); - verify_person_in_community(&actor, community, context, request_counter).await?; + verify_person_in_community(actor, community, context, request_counter).await?; if is_mod_action { - verify_mod_action(&actor, community, context, request_counter).await?; + verify_mod_action(actor, community, context, request_counter).await?; } else { // domain of post ap_id and post.creator ap_id are identical, so we just check the former - verify_domains_match(activity.actor(), object_id)?; + verify_domains_match(actor.inner(), object_id)?; } Ok(()) } diff --git a/crates/apub/src/activities/deletion/undo_delete.rs b/crates/apub/src/activities/deletion/undo_delete.rs index 2de4aefd..93338a3f 100644 --- a/crates/apub/src/activities/deletion/undo_delete.rs +++ b/crates/apub/src/activities/deletion/undo_delete.rs @@ -1,20 +1,3 @@ -use activitystreams::{activity::kind::UndoType, public}; -use anyhow::anyhow; -use url::Url; - -use lemmy_api_common::blocking; -use lemmy_apub_lib::{ - data::Data, - traits::{ActivityHandler, ActorType}, -}; -use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post}; -use lemmy_utils::LemmyError; -use lemmy_websocket::{ - send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message}, - LemmyContext, - UserOperationCrud, -}; - use crate::{ activities::{ community::{announce::GetCommunity, send_to_community}, @@ -28,6 +11,21 @@ use crate::{ objects::{community::ApubCommunity, person::ApubPerson}, protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete}, }; +use activitystreams::{activity::kind::UndoType, public}; +use anyhow::anyhow; +use lemmy_api_common::blocking; +use lemmy_apub_lib::{ + data::Data, + traits::{ActivityHandler, ActorType}, +}; +use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post}; +use lemmy_utils::LemmyError; +use lemmy_websocket::{ + send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message}, + LemmyContext, + UserOperationCrud, +}; +use url::Url; #[async_trait::async_trait(?Send)] impl ActivityHandler for UndoDelete { @@ -38,12 +36,12 @@ impl ActivityHandler for UndoDelete { request_counter: &mut i32, ) -> Result<(), LemmyError> { verify_is_public(&self.to)?; - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; self.object.verify(context, request_counter).await?; let community = self.get_community(context, request_counter).await?; verify_delete_activity( &self.object.object, - self, + &self.actor, &community, self.object.summary.is_some(), context, diff --git a/crates/apub/src/activities/following/accept.rs b/crates/apub/src/activities/following/accept.rs index 984d622a..68c8ca45 100644 --- a/crates/apub/src/activities/following/accept.rs +++ b/crates/apub/src/activities/following/accept.rs @@ -7,7 +7,7 @@ use activitystreams::activity::kind::AcceptType; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityHandler, ActorType}, verify::verify_urls_match, }; use lemmy_db_schema::{source::community::CommunityFollower, traits::Followable}; @@ -51,9 +51,9 @@ impl ActivityHandler for AcceptFollowCommunity { context: &Data, request_counter: &mut i32, ) -> Result<(), LemmyError> { - verify_activity(self, &context.settings())?; - verify_urls_match(self.to[0].inner(), self.object.actor())?; - verify_urls_match(self.actor(), self.object.to[0].inner())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; + verify_urls_match(self.to[0].inner(), self.object.actor.inner())?; + verify_urls_match(self.actor.inner(), self.object.to[0].inner())?; self.object.verify(context, request_counter).await?; Ok(()) } diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs index e048907f..30c77fe8 100644 --- a/crates/apub/src/activities/following/follow.rs +++ b/crates/apub/src/activities/following/follow.rs @@ -71,7 +71,7 @@ impl ActivityHandler for FollowCommunity { context: &Data, request_counter: &mut i32, ) -> Result<(), LemmyError> { - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; verify_urls_match(self.to[0].inner(), self.object.inner())?; verify_person(&self.actor, context, request_counter).await?; let community = self.to[0].dereference(context, request_counter).await?; diff --git a/crates/apub/src/activities/following/undo_follow.rs b/crates/apub/src/activities/following/undo_follow.rs index c3fd78b5..bdc5a4b0 100644 --- a/crates/apub/src/activities/following/undo_follow.rs +++ b/crates/apub/src/activities/following/undo_follow.rs @@ -8,7 +8,7 @@ use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityHandler, ActorType}, verify::verify_urls_match, }; use lemmy_db_schema::{ @@ -49,9 +49,9 @@ impl ActivityHandler for UndoFollowCommunity { context: &Data, request_counter: &mut i32, ) -> Result<(), LemmyError> { - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; verify_urls_match(self.to[0].inner(), self.object.object.inner())?; - verify_urls_match(self.actor(), self.object.actor())?; + verify_urls_match(self.actor.inner(), self.object.actor.inner())?; verify_person(&self.actor, context, request_counter).await?; self.object.verify(context, request_counter).await?; Ok(()) diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index bc6cfb51..e23926f8 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -11,7 +11,7 @@ use anyhow::anyhow; use lemmy_api_common::blocking; use lemmy_apub_lib::{ activity_queue::send_activity, - traits::{ActivityFields, ActorType}, + traits::ActorType, verify::verify_domains_match, }; use lemmy_db_schema::source::community::Community; @@ -71,9 +71,9 @@ pub(crate) async fn verify_person_in_community( Ok(()) } -fn verify_activity(activity: &dyn ActivityFields, settings: &Settings) -> Result<(), LemmyError> { - check_is_apub_id_valid(activity.actor(), false, settings)?; - verify_domains_match(activity.id_unchecked(), activity.actor())?; +fn verify_activity(id: &Url, actor: &Url, settings: &Settings) -> Result<(), LemmyError> { + check_is_apub_id_valid(actor, false, settings)?; + verify_domains_match(id, actor)?; Ok(()) } diff --git a/crates/apub/src/activities/post/create_or_update.rs b/crates/apub/src/activities/post/create_or_update.rs index 677ce2dc..e574dda9 100644 --- a/crates/apub/src/activities/post/create_or_update.rs +++ b/crates/apub/src/activities/post/create_or_update.rs @@ -1,16 +1,3 @@ -use activitystreams::public; -use anyhow::anyhow; - -use lemmy_api_common::blocking; -use lemmy_apub_lib::{ - data::Data, - traits::{ActivityFields, ActivityHandler, ActorType, ApubObject}, - verify::{verify_domains_match, verify_urls_match}, -}; -use lemmy_db_schema::{source::community::Community, traits::Crud}; -use lemmy_utils::LemmyError; -use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud}; - use crate::{ activities::{ check_community_deleted_or_removed, @@ -26,6 +13,17 @@ use crate::{ objects::{community::ApubCommunity, person::ApubPerson, post::ApubPost}, protocol::activities::{create_or_update::post::CreateOrUpdatePost, CreateOrUpdateType}, }; +use activitystreams::public; +use anyhow::anyhow; +use lemmy_api_common::blocking; +use lemmy_apub_lib::{ + data::Data, + traits::{ActivityHandler, ActorType, ApubObject}, + verify::{verify_domains_match, verify_urls_match}, +}; +use lemmy_db_schema::{source::community::Community, traits::Crud}; +use lemmy_utils::LemmyError; +use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud}; impl CreateOrUpdatePost { pub(crate) async fn new( @@ -77,7 +75,7 @@ impl ActivityHandler for CreateOrUpdatePost { request_counter: &mut i32, ) -> Result<(), LemmyError> { verify_is_public(&self.to)?; - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; let community = self.get_community(context, request_counter).await?; verify_person_in_community(&self.actor, &community, context, request_counter).await?; check_community_deleted_or_removed(&community)?; @@ -85,7 +83,7 @@ impl ActivityHandler for CreateOrUpdatePost { match self.kind { CreateOrUpdateType::Create => { verify_domains_match(self.actor.inner(), self.object.id.inner())?; - verify_urls_match(self.actor(), self.object.attributed_to.inner())?; + verify_urls_match(self.actor.inner(), self.object.attributed_to.inner())?; // Check that the post isnt locked or stickied, as that isnt possible for newly created posts. // However, when fetching a remote post we generate a new create activity with the current // locked/stickied value, so this check may fail. So only check if its a local community, @@ -102,7 +100,7 @@ impl ActivityHandler for CreateOrUpdatePost { verify_mod_action(&self.actor, &community, context, request_counter).await?; } else { verify_domains_match(self.actor.inner(), self.object.id.inner())?; - verify_urls_match(self.actor(), self.object.attributed_to.inner())?; + verify_urls_match(self.actor.inner(), self.object.attributed_to.inner())?; } } } diff --git a/crates/apub/src/activities/private_message/create_or_update.rs b/crates/apub/src/activities/private_message/create_or_update.rs index e441718a..52b6fa74 100644 --- a/crates/apub/src/activities/private_message/create_or_update.rs +++ b/crates/apub/src/activities/private_message/create_or_update.rs @@ -54,7 +54,7 @@ impl ActivityHandler for CreateOrUpdatePrivateMessage { context: &Data, request_counter: &mut i32, ) -> Result<(), LemmyError> { - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; verify_person(&self.actor, context, request_counter).await?; verify_domains_match(self.actor.inner(), self.object.id.inner())?; self.object.verify(context, request_counter).await?; diff --git a/crates/apub/src/activities/private_message/delete.rs b/crates/apub/src/activities/private_message/delete.rs index da3b6472..4547b22b 100644 --- a/crates/apub/src/activities/private_message/delete.rs +++ b/crates/apub/src/activities/private_message/delete.rs @@ -62,7 +62,7 @@ impl ActivityHandler for DeletePrivateMessage { context: &Data, request_counter: &mut i32, ) -> Result<(), LemmyError> { - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; verify_person(&self.actor, context, request_counter).await?; verify_domains_match(self.actor.inner(), self.object.inner())?; Ok(()) diff --git a/crates/apub/src/activities/private_message/undo_delete.rs b/crates/apub/src/activities/private_message/undo_delete.rs index bba9e0f2..1272328b 100644 --- a/crates/apub/src/activities/private_message/undo_delete.rs +++ b/crates/apub/src/activities/private_message/undo_delete.rs @@ -11,7 +11,7 @@ use activitystreams::activity::kind::UndoType; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityHandler, ActorType}, verify::{verify_domains_match, verify_urls_match}, }; use lemmy_db_schema::{ @@ -59,10 +59,10 @@ impl ActivityHandler for UndoDeletePrivateMessage { context: &Data, request_counter: &mut i32, ) -> Result<(), LemmyError> { - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; verify_person(&self.actor, context, request_counter).await?; - verify_urls_match(self.actor(), self.object.actor())?; - verify_domains_match(self.actor(), self.object.object.inner())?; + verify_urls_match(self.actor.inner(), self.object.actor.inner())?; + verify_domains_match(self.actor.inner(), self.object.object.inner())?; self.object.verify(context, request_counter).await?; Ok(()) } diff --git a/crates/apub/src/activities/voting/undo_vote.rs b/crates/apub/src/activities/voting/undo_vote.rs index e95d2517..786d5119 100644 --- a/crates/apub/src/activities/voting/undo_vote.rs +++ b/crates/apub/src/activities/voting/undo_vote.rs @@ -1,17 +1,3 @@ -use std::ops::Deref; - -use activitystreams::{activity::kind::UndoType, public}; - -use lemmy_api_common::blocking; -use lemmy_apub_lib::{ - data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, - verify::verify_urls_match, -}; -use lemmy_db_schema::{newtypes::CommunityId, source::community::Community, traits::Crud}; -use lemmy_utils::LemmyError; -use lemmy_websocket::LemmyContext; - use crate::{ activities::{ community::{announce::GetCommunity, send_to_community}, @@ -30,6 +16,17 @@ use crate::{ }, PostOrComment, }; +use activitystreams::{activity::kind::UndoType, public}; +use lemmy_api_common::blocking; +use lemmy_apub_lib::{ + data::Data, + traits::{ActivityHandler, ActorType}, + verify::verify_urls_match, +}; +use lemmy_db_schema::{newtypes::CommunityId, source::community::Community, traits::Crud}; +use lemmy_utils::LemmyError; +use lemmy_websocket::LemmyContext; +use std::ops::Deref; impl UndoVote { pub async fn send( @@ -73,10 +70,10 @@ impl ActivityHandler for UndoVote { request_counter: &mut i32, ) -> Result<(), LemmyError> { verify_is_public(&self.to)?; - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; let community = self.get_community(context, request_counter).await?; verify_person_in_community(&self.actor, &community, context, request_counter).await?; - verify_urls_match(self.actor(), self.object.actor())?; + verify_urls_match(self.actor.inner(), self.object.actor.inner())?; self.object.verify(context, request_counter).await?; Ok(()) } diff --git a/crates/apub/src/activities/voting/vote.rs b/crates/apub/src/activities/voting/vote.rs index 01df4b93..82b9b84e 100644 --- a/crates/apub/src/activities/voting/vote.rs +++ b/crates/apub/src/activities/voting/vote.rs @@ -1,20 +1,3 @@ -use std::ops::Deref; - -use activitystreams::public; - -use lemmy_api_common::blocking; -use lemmy_apub_lib::{ - data::Data, - traits::{ActivityHandler, ActorType}, -}; -use lemmy_db_schema::{ - newtypes::CommunityId, - source::{community::Community, post::Post}, - traits::Crud, -}; -use lemmy_utils::LemmyError; -use lemmy_websocket::LemmyContext; - use crate::{ activities::{ community::{announce::GetCommunity, send_to_community}, @@ -30,6 +13,20 @@ use crate::{ protocol::activities::voting::vote::{Vote, VoteType}, PostOrComment, }; +use activitystreams::public; +use lemmy_api_common::blocking; +use lemmy_apub_lib::{ + data::Data, + traits::{ActivityHandler, ActorType}, +}; +use lemmy_db_schema::{ + newtypes::CommunityId, + source::{community::Community, post::Post}, + traits::Crud, +}; +use lemmy_utils::LemmyError; +use lemmy_websocket::LemmyContext; +use std::ops::Deref; impl Vote { pub(in crate::activities::voting) fn new( @@ -79,7 +76,7 @@ impl ActivityHandler for Vote { request_counter: &mut i32, ) -> Result<(), LemmyError> { verify_is_public(&self.to)?; - verify_activity(self, &context.settings())?; + verify_activity(&self.id, self.actor.inner(), &context.settings())?; let community = self.get_community(context, request_counter).await?; verify_person_in_community(&self.actor, &community, context, request_counter).await?; Ok(()) diff --git a/crates/apub/src/activity_lists.rs b/crates/apub/src/activity_lists.rs index 1197af85..6c866b83 100644 --- a/crates/apub/src/activity_lists.rs +++ b/crates/apub/src/activity_lists.rs @@ -26,12 +26,12 @@ use crate::{ voting::{undo_vote::UndoVote, vote::Vote}, }, }; -use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler}; +use lemmy_apub_lib::traits::ActivityHandler; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler)] #[serde(untagged)] #[activity_handler(LemmyContext)] pub enum SharedInboxActivities { @@ -41,7 +41,7 @@ pub enum SharedInboxActivities { PersonInboxActivities(PersonInboxActivities), } -#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler)] #[serde(untagged)] #[activity_handler(LemmyContext)] pub enum GroupInboxActivities { @@ -51,7 +51,7 @@ pub enum GroupInboxActivities { Report(Report), } -#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler)] #[serde(untagged)] #[activity_handler(LemmyContext)] pub enum PersonInboxActivities { @@ -64,7 +64,7 @@ pub enum PersonInboxActivities { AnnounceActivity(Box), } -#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler)] #[serde(untagged)] #[activity_handler(LemmyContext)] pub enum AnnouncableActivities { diff --git a/crates/apub/src/fetcher/mod.rs b/crates/apub/src/fetcher/mod.rs index db39d228..8246f4ce 100644 --- a/crates/apub/src/fetcher/mod.rs +++ b/crates/apub/src/fetcher/mod.rs @@ -1,44 +1,14 @@ pub mod object_id; pub mod post_or_comment; pub mod search; +pub mod user_or_community; -use crate::{ - fetcher::object_id::ObjectId, - objects::{community::ApubCommunity, person::ApubPerson}, -}; use chrono::NaiveDateTime; -use lemmy_apub_lib::traits::ActorType; use lemmy_db_schema::naive_now; -use lemmy_utils::LemmyError; -use lemmy_websocket::LemmyContext; -use url::Url; static ACTOR_REFETCH_INTERVAL_SECONDS: i64 = 24 * 60 * 60; static ACTOR_REFETCH_INTERVAL_SECONDS_DEBUG: i64 = 10; -/// 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. -pub(crate) async fn get_or_fetch_and_upsert_actor( - apub_id: Url, - context: &LemmyContext, - recursion_counter: &mut i32, -) -> Result, LemmyError> { - let community_id = ObjectId::::new(apub_id.clone()); - let community = community_id.dereference(context, recursion_counter).await; - let actor: Box = match community { - Ok(c) => Box::new(c), - Err(_) => { - let person_id = ObjectId::new(apub_id); - let person: ApubPerson = person_id.dereference(context, recursion_counter).await?; - Box::new(person) - } - }; - Ok(actor) -} - /// Determines when a remote actor should be refetched from its instance. In release builds, this is /// `ACTOR_REFETCH_INTERVAL_SECONDS` after the last refetch, in debug builds /// `ACTOR_REFETCH_INTERVAL_SECONDS_DEBUG`. diff --git a/crates/apub/src/fetcher/post_or_comment.rs b/crates/apub/src/fetcher/post_or_comment.rs index c0bc46a8..ef4e59e1 100644 --- a/crates/apub/src/fetcher/post_or_comment.rs +++ b/crates/apub/src/fetcher/post_or_comment.rs @@ -1,16 +1,13 @@ -use chrono::NaiveDateTime; -use serde::Deserialize; -use url::Url; - -use lemmy_apub_lib::traits::ApubObject; -use lemmy_db_schema::source::{comment::CommentForm, post::PostForm}; -use lemmy_utils::LemmyError; -use lemmy_websocket::LemmyContext; - use crate::{ objects::{comment::ApubComment, post::ApubPost}, protocol::objects::{note::Note, page::Page}, }; +use chrono::NaiveDateTime; +use lemmy_apub_lib::traits::ApubObject; +use lemmy_utils::LemmyError; +use lemmy_websocket::LemmyContext; +use serde::Deserialize; +use url::Url; #[derive(Clone, Debug)] pub enum PostOrComment { @@ -18,11 +15,6 @@ pub enum PostOrComment { Comment(ApubComment), } -pub enum PostOrCommentForm { - PostForm(Box), - CommentForm(CommentForm), -} - #[derive(Deserialize)] #[serde(untagged)] pub enum PageOrNote { @@ -44,10 +36,7 @@ impl ApubObject for PostOrComment { async fn read_from_apub_id( object_id: Url, data: &Self::DataType, - ) -> Result, LemmyError> - where - Self: Sized, - { + ) -> Result, LemmyError> { let post = ApubPost::read_from_apub_id(object_id.clone(), data).await?; Ok(match post { Some(o) => Some(PostOrComment::Post(Box::new(o))), @@ -77,10 +66,7 @@ impl ApubObject for PostOrComment { context: &LemmyContext, expected_domain: &Url, request_counter: &mut i32, - ) -> Result - where - Self: Sized, - { + ) -> Result { Ok(match apub { PageOrNote::Page(p) => PostOrComment::Post(Box::new( ApubPost::from_apub(p, context, expected_domain, request_counter).await?, diff --git a/crates/apub/src/fetcher/user_or_community.rs b/crates/apub/src/fetcher/user_or_community.rs new file mode 100644 index 00000000..16a1d822 --- /dev/null +++ b/crates/apub/src/fetcher/user_or_community.rs @@ -0,0 +1,113 @@ +use crate::{ + objects::{community::ApubCommunity, person::ApubPerson}, + protocol::objects::{group::Group, person::Person}, +}; +use activitystreams::{chrono::NaiveDateTime, url::Url}; +use lemmy_apub_lib::traits::{ActorType, ApubObject}; +use lemmy_utils::LemmyError; +use lemmy_websocket::LemmyContext; +use serde::Deserialize; + +#[derive(Clone, Debug)] +pub enum UserOrCommunity { + User(ApubPerson), + Community(ApubCommunity), +} + +#[derive(Deserialize)] +#[serde(untagged)] +pub enum PersonOrGroup { + Person(Person), + Group(Group), +} + +#[async_trait::async_trait(?Send)] +impl ApubObject for UserOrCommunity { + type DataType = LemmyContext; + type ApubType = PersonOrGroup; + type TombstoneType = (); + + fn last_refreshed_at(&self) -> Option { + Some(match self { + UserOrCommunity::User(p) => p.last_refreshed_at, + UserOrCommunity::Community(p) => p.last_refreshed_at, + }) + } + + async fn read_from_apub_id( + object_id: Url, + data: &Self::DataType, + ) -> Result, LemmyError> { + let person = ApubPerson::read_from_apub_id(object_id.clone(), data).await?; + Ok(match person { + Some(o) => Some(UserOrCommunity::User(o)), + None => ApubCommunity::read_from_apub_id(object_id, data) + .await? + .map(UserOrCommunity::Community), + }) + } + + async fn delete(self, data: &Self::DataType) -> Result<(), LemmyError> { + match self { + UserOrCommunity::User(p) => p.delete(data).await, + UserOrCommunity::Community(p) => p.delete(data).await, + } + } + + async fn to_apub(&self, _data: &Self::DataType) -> Result { + unimplemented!() + } + + fn to_tombstone(&self) -> Result { + unimplemented!() + } + + async fn from_apub( + apub: &Self::ApubType, + data: &Self::DataType, + expected_domain: &Url, + request_counter: &mut i32, + ) -> Result { + Ok(match apub { + PersonOrGroup::Person(p) => UserOrCommunity::User( + ApubPerson::from_apub(p, data, expected_domain, request_counter).await?, + ), + PersonOrGroup::Group(p) => UserOrCommunity::Community( + ApubCommunity::from_apub(p, data, expected_domain, request_counter).await?, + ), + }) + } +} + +impl ActorType for UserOrCommunity { + fn is_local(&self) -> bool { + todo!() + } + + fn actor_id(&self) -> Url { + todo!() + } + + fn name(&self) -> String { + todo!() + } + + fn public_key(&self) -> Option { + match self { + UserOrCommunity::User(p) => p.public_key(), + UserOrCommunity::Community(p) => p.public_key(), + } + } + + fn private_key(&self) -> Option { + todo!() + } + + fn inbox_url(&self) -> Url { + todo!() + } + + fn shared_inbox_url(&self) -> Option { + todo!() + } +} diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs index 4110d2b2..c208f71e 100644 --- a/crates/apub/src/http/community.rs +++ b/crates/apub/src/http/community.rs @@ -14,6 +14,7 @@ use crate::{ create_apub_tombstone_response, payload_to_string, receive_activity, + ActivityCommonFields, }, objects::community::ApubCommunity, protocol::{ @@ -23,7 +24,7 @@ use crate::{ }; use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; use lemmy_api_common::blocking; -use lemmy_apub_lib::traits::{ActivityFields, ApubObject}; +use lemmy_apub_lib::traits::ApubObject; use lemmy_db_schema::source::community::Community; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; @@ -64,23 +65,25 @@ pub async fn community_inbox( ) -> Result { let unparsed = payload_to_string(payload).await?; info!("Received community inbox activity {}", unparsed); + let activity_data: ActivityCommonFields = serde_json::from_str(&unparsed)?; let activity = serde_json::from_str::>(&unparsed)?; - receive_group_inbox(activity.inner(), request, &context).await?; + receive_group_inbox(activity.inner(), activity_data, request, &context).await?; Ok(HttpResponse::Ok().finish()) } pub(in crate::http) async fn receive_group_inbox( activity: GroupInboxActivities, + activity_data: ActivityCommonFields, request: HttpRequest, context: &LemmyContext, ) -> Result { - let res = receive_activity(request, activity.clone(), context).await; + let actor_id = ObjectId::new(activity_data.actor.clone()); + let res = receive_activity(request, activity.clone(), activity_data, context).await; if let GroupInboxActivities::AnnouncableActivities(announcable) = activity { let community = announcable.get_community(context, &mut 0).await?; - let actor_id = ObjectId::new(announcable.actor().clone()); verify_person_in_community(&actor_id, &community, context, &mut 0).await?; if community.local { AnnounceActivity::send(announcable, &community, vec![], context).await?; diff --git a/crates/apub/src/http/mod.rs b/crates/apub/src/http/mod.rs index 9c61c274..450b937d 100644 --- a/crates/apub/src/http/mod.rs +++ b/crates/apub/src/http/mod.rs @@ -2,7 +2,7 @@ use crate::{ activity_lists::SharedInboxActivities, check_is_apub_id_valid, context::WithContext, - fetcher::get_or_fetch_and_upsert_actor, + fetcher::{object_id::ObjectId, user_or_community::UserOrCommunity}, http::{community::receive_group_inbox, person::receive_person_inbox}, insert_activity, }; @@ -20,7 +20,7 @@ use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, signatures::verify_signature, - traits::{ActivityFields, ActivityHandler}, + traits::{ActivityHandler, ActorType}, APUB_JSON_CONTENT_TYPE, }; use lemmy_db_schema::{source::activity::Activity, DbPool}; @@ -44,13 +44,14 @@ pub async fn shared_inbox( ) -> Result { let unparsed = payload_to_string(payload).await?; info!("Received shared inbox activity {}", unparsed); + let activity_data: ActivityCommonFields = serde_json::from_str(&unparsed)?; let activity = serde_json::from_str::>(&unparsed)?; match activity.inner() { SharedInboxActivities::GroupInboxActivities(g) => { - receive_group_inbox(g, request, &context).await + receive_group_inbox(g, activity_data, request, &context).await } SharedInboxActivities::PersonInboxActivities(p) => { - receive_person_inbox(p, request, &context).await + receive_person_inbox(p, activity_data, request, &context).await } } } @@ -65,15 +66,22 @@ async fn payload_to_string(mut payload: Payload) -> Result { Ok(unparsed) } +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct ActivityCommonFields { + pub(crate) id: Url, + pub(crate) actor: Url, +} + // TODO: move most of this code to library async fn receive_activity<'a, T>( request: HttpRequest, activity: T, + activity_data: ActivityCommonFields, context: &LemmyContext, ) -> Result where T: ActivityHandler - + ActivityFields + Clone + Deserialize<'a> + Serialize @@ -81,26 +89,27 @@ where + Send + 'static, { + check_is_apub_id_valid(&activity_data.actor, false, &context.settings())?; let request_counter = &mut 0; - let actor = - get_or_fetch_and_upsert_actor(activity.actor().clone(), context, request_counter).await?; + let actor = ObjectId::::new(activity_data.actor) + .dereference(context, request_counter) + .await?; verify_signature(&request, &actor.public_key().context(location_info!())?)?; // Do nothing if we received the same activity before - if is_activity_already_known(context.pool(), activity.id_unchecked()).await? { + if is_activity_already_known(context.pool(), &activity_data.id).await? { return Ok(HttpResponse::Ok().finish()); } - check_is_apub_id_valid(activity.actor(), false, &context.settings())?; - info!("Verifying activity {}", activity.id_unchecked().to_string()); + info!("Verifying activity {}", activity_data.id.to_string()); activity .verify(&Data::new(context.clone()), request_counter) .await?; - assert_activity_not_local(&activity, &context.settings().hostname)?; + assert_activity_not_local(&activity_data.id, &context.settings().hostname)?; // 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_data.id, activity.clone(), false, true, @@ -108,7 +117,7 @@ where ) .await?; - info!("Receiving activity {}", activity.id_unchecked().to_string()); + info!("Receiving activity {}", activity_data.id.to_string()); activity .receive(&Data::new(context.clone()), request_counter) .await?; @@ -183,17 +192,14 @@ pub(crate) async fn is_activity_already_known( } } -fn assert_activity_not_local( - activity: &T, - hostname: &str, -) -> Result<(), LemmyError> { - let activity_domain = activity.id_unchecked().domain().context(location_info!())?; +fn assert_activity_not_local(id: &Url, hostname: &str) -> Result<(), LemmyError> { + let activity_domain = id.domain().context(location_info!())?; if activity_domain == hostname { return Err( anyhow!( "Error: received activity which was sent by local instance: {:?}", - activity + id ) .into(), ); diff --git a/crates/apub/src/http/person.rs b/crates/apub/src/http/person.rs index a5ea4ad1..193689c5 100644 --- a/crates/apub/src/http/person.rs +++ b/crates/apub/src/http/person.rs @@ -6,6 +6,7 @@ use crate::{ create_apub_tombstone_response, payload_to_string, receive_activity, + ActivityCommonFields, }, objects::person::ApubPerson, protocol::collections::person_outbox::PersonOutbox, @@ -54,16 +55,18 @@ pub async fn person_inbox( ) -> Result { let unparsed = payload_to_string(payload).await?; info!("Received person inbox activity {}", unparsed); + let activity_data: ActivityCommonFields = serde_json::from_str(&unparsed)?; let activity = serde_json::from_str::>(&unparsed)?; - receive_person_inbox(activity.inner(), request, &context).await + receive_person_inbox(activity.inner(), activity_data, request, &context).await } pub(in crate::http) async fn receive_person_inbox( activity: PersonInboxActivities, + activity_data: ActivityCommonFields, request: HttpRequest, context: &LemmyContext, ) -> Result { - receive_activity(request, activity, context).await + receive_activity(request, activity, activity_data, context).await } pub(crate) async fn get_apub_person_outbox( diff --git a/crates/apub/src/protocol/activities/community/add_mod.rs b/crates/apub/src/protocol/activities/community/add_mod.rs index 74ec4645..6938f01d 100644 --- a/crates/apub/src/protocol/activities/community/add_mod.rs +++ b/crates/apub/src/protocol/activities/community/add_mod.rs @@ -1,10 +1,9 @@ use crate::{fetcher::object_id::ObjectId, objects::person::ApubPerson}; use activitystreams::{activity::kind::AddType, unparsed::Unparsed}; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct AddMod { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/community/announce.rs b/crates/apub/src/protocol/activities/community/announce.rs index 2f4e9bd2..07fbda63 100644 --- a/crates/apub/src/protocol/activities/community/announce.rs +++ b/crates/apub/src/protocol/activities/community/announce.rs @@ -4,11 +4,10 @@ use crate::{ objects::community::ApubCommunity, }; use activitystreams::{activity::kind::AnnounceType, unparsed::Unparsed}; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct AnnounceActivity { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/community/block_user.rs b/crates/apub/src/protocol/activities/community/block_user.rs index 4ede06ae..ec95e6e9 100644 --- a/crates/apub/src/protocol/activities/community/block_user.rs +++ b/crates/apub/src/protocol/activities/community/block_user.rs @@ -3,11 +3,10 @@ use crate::{ objects::{community::ApubCommunity, person::ApubPerson}, }; use activitystreams::{activity::kind::BlockType, unparsed::Unparsed}; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct BlockUserFromCommunity { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/community/remove_mod.rs b/crates/apub/src/protocol/activities/community/remove_mod.rs index db30ddbe..cca26354 100644 --- a/crates/apub/src/protocol/activities/community/remove_mod.rs +++ b/crates/apub/src/protocol/activities/community/remove_mod.rs @@ -1,10 +1,9 @@ use crate::{fetcher::object_id::ObjectId, objects::person::ApubPerson}; use activitystreams::{activity::kind::RemoveType, unparsed::Unparsed}; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct RemoveMod { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/community/report.rs b/crates/apub/src/protocol/activities/community/report.rs index 5efdd792..d10a9d28 100644 --- a/crates/apub/src/protocol/activities/community/report.rs +++ b/crates/apub/src/protocol/activities/community/report.rs @@ -3,11 +3,10 @@ use crate::{ objects::{community::ApubCommunity, person::ApubPerson}, }; use activitystreams::{activity::kind::FlagType, unparsed::Unparsed}; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct Report { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/community/undo_block_user.rs b/crates/apub/src/protocol/activities/community/undo_block_user.rs index 0e89f87e..24356fab 100644 --- a/crates/apub/src/protocol/activities/community/undo_block_user.rs +++ b/crates/apub/src/protocol/activities/community/undo_block_user.rs @@ -4,11 +4,10 @@ use crate::{ protocol::activities::community::block_user::BlockUserFromCommunity, }; use activitystreams::{activity::kind::UndoType, unparsed::Unparsed}; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoBlockUserFromCommunity { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/community/update.rs b/crates/apub/src/protocol/activities/community/update.rs index 4ba1ed84..686938aa 100644 --- a/crates/apub/src/protocol/activities/community/update.rs +++ b/crates/apub/src/protocol/activities/community/update.rs @@ -4,13 +4,12 @@ use crate::{ protocol::objects::group::Group, }; use activitystreams::{activity::kind::UpdateType, unparsed::Unparsed}; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; /// This activity is received from a remote community mod, and updates the description or other /// fields of a local community. -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct UpdateCommunity { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/create_or_update/comment.rs b/crates/apub/src/protocol/activities/create_or_update/comment.rs index ede7417b..4e5b412d 100644 --- a/crates/apub/src/protocol/activities/create_or_update/comment.rs +++ b/crates/apub/src/protocol/activities/create_or_update/comment.rs @@ -4,11 +4,10 @@ use crate::{ protocol::{activities::CreateOrUpdateType, objects::note::Note}, }; use activitystreams::{link::Mention, unparsed::Unparsed}; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct CreateOrUpdateComment { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/create_or_update/post.rs b/crates/apub/src/protocol/activities/create_or_update/post.rs index 03b283e3..b1851c0d 100644 --- a/crates/apub/src/protocol/activities/create_or_update/post.rs +++ b/crates/apub/src/protocol/activities/create_or_update/post.rs @@ -4,11 +4,10 @@ use crate::{ protocol::{activities::CreateOrUpdateType, objects::page::Page}, }; use activitystreams::unparsed::Unparsed; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct CreateOrUpdatePost { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/deletion/delete.rs b/crates/apub/src/protocol/activities/deletion/delete.rs index f8e81b47..af502279 100644 --- a/crates/apub/src/protocol/activities/deletion/delete.rs +++ b/crates/apub/src/protocol/activities/deletion/delete.rs @@ -1,12 +1,11 @@ use crate::{fetcher::object_id::ObjectId, objects::person::ApubPerson}; use activitystreams::{activity::kind::DeleteType, unparsed::Unparsed}; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use url::Url; #[skip_serializing_none] -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct Delete { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/deletion/undo_delete.rs b/crates/apub/src/protocol/activities/deletion/undo_delete.rs index d962820b..8a30546e 100644 --- a/crates/apub/src/protocol/activities/deletion/undo_delete.rs +++ b/crates/apub/src/protocol/activities/deletion/undo_delete.rs @@ -1,16 +1,13 @@ -use activitystreams::{activity::kind::UndoType, unparsed::Unparsed}; -use serde::{Deserialize, Serialize}; -use url::Url; - -use lemmy_apub_lib::traits::ActivityFields; - use crate::{ fetcher::object_id::ObjectId, objects::person::ApubPerson, protocol::activities::deletion::delete::Delete, }; +use activitystreams::{activity::kind::UndoType, unparsed::Unparsed}; +use serde::{Deserialize, Serialize}; +use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoDelete { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/following/accept.rs b/crates/apub/src/protocol/activities/following/accept.rs index 502a908c..7eeb3a41 100644 --- a/crates/apub/src/protocol/activities/following/accept.rs +++ b/crates/apub/src/protocol/activities/following/accept.rs @@ -4,11 +4,10 @@ use crate::{ protocol::activities::following::follow::FollowCommunity, }; use activitystreams::{activity::kind::AcceptType, unparsed::Unparsed}; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct AcceptFollowCommunity { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/following/follow.rs b/crates/apub/src/protocol/activities/following/follow.rs index 9dfec216..651ab1d2 100644 --- a/crates/apub/src/protocol/activities/following/follow.rs +++ b/crates/apub/src/protocol/activities/following/follow.rs @@ -3,11 +3,10 @@ use crate::{ objects::{community::ApubCommunity, person::ApubPerson}, }; use activitystreams::{activity::kind::FollowType, unparsed::Unparsed}; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct FollowCommunity { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/following/undo_follow.rs b/crates/apub/src/protocol/activities/following/undo_follow.rs index be6a7ab8..3abeabd2 100644 --- a/crates/apub/src/protocol/activities/following/undo_follow.rs +++ b/crates/apub/src/protocol/activities/following/undo_follow.rs @@ -4,11 +4,10 @@ use crate::{ protocol::activities::following::follow::FollowCommunity, }; use activitystreams::{activity::kind::UndoType, unparsed::Unparsed}; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoFollowCommunity { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/private_message/create_or_update.rs b/crates/apub/src/protocol/activities/private_message/create_or_update.rs index 7632ef9f..5092a164 100644 --- a/crates/apub/src/protocol/activities/private_message/create_or_update.rs +++ b/crates/apub/src/protocol/activities/private_message/create_or_update.rs @@ -4,11 +4,10 @@ use crate::{ protocol::{activities::CreateOrUpdateType, objects::chat_message::ChatMessage}, }; use activitystreams::unparsed::Unparsed; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct CreateOrUpdatePrivateMessage { pub(crate) id: Url, diff --git a/crates/apub/src/protocol/activities/private_message/delete.rs b/crates/apub/src/protocol/activities/private_message/delete.rs index 499d7d1d..87da3c31 100644 --- a/crates/apub/src/protocol/activities/private_message/delete.rs +++ b/crates/apub/src/protocol/activities/private_message/delete.rs @@ -3,11 +3,10 @@ use crate::{ objects::{person::ApubPerson, private_message::ApubPrivateMessage}, }; use activitystreams::{activity::kind::DeleteType, unparsed::Unparsed}; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct DeletePrivateMessage { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/private_message/undo_delete.rs b/crates/apub/src/protocol/activities/private_message/undo_delete.rs index 699f6eec..16d82492 100644 --- a/crates/apub/src/protocol/activities/private_message/undo_delete.rs +++ b/crates/apub/src/protocol/activities/private_message/undo_delete.rs @@ -4,11 +4,10 @@ use crate::{ protocol::activities::private_message::delete::DeletePrivateMessage, }; use activitystreams::{activity::kind::UndoType, unparsed::Unparsed}; -use lemmy_apub_lib::traits::ActivityFields; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoDeletePrivateMessage { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/voting/undo_vote.rs b/crates/apub/src/protocol/activities/voting/undo_vote.rs index 0d3e6636..05606dbe 100644 --- a/crates/apub/src/protocol/activities/voting/undo_vote.rs +++ b/crates/apub/src/protocol/activities/voting/undo_vote.rs @@ -1,16 +1,13 @@ -use activitystreams::{activity::kind::UndoType, unparsed::Unparsed}; -use serde::{Deserialize, Serialize}; -use url::Url; - -use lemmy_apub_lib::traits::ActivityFields; - use crate::{ fetcher::object_id::ObjectId, objects::person::ApubPerson, protocol::activities::voting::vote::Vote, }; +use activitystreams::{activity::kind::UndoType, unparsed::Unparsed}; +use serde::{Deserialize, Serialize}; +use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoVote { pub(crate) actor: ObjectId, diff --git a/crates/apub/src/protocol/activities/voting/vote.rs b/crates/apub/src/protocol/activities/voting/vote.rs index fdc87a3b..6d82ccc4 100644 --- a/crates/apub/src/protocol/activities/voting/vote.rs +++ b/crates/apub/src/protocol/activities/voting/vote.rs @@ -4,14 +4,13 @@ use crate::{ }; use activitystreams::unparsed::Unparsed; use anyhow::anyhow; -use lemmy_apub_lib::traits::ActivityFields; use lemmy_utils::LemmyError; use serde::{Deserialize, Serialize}; use std::convert::TryFrom; use strum_macros::ToString; use url::Url; -#[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct Vote { pub(crate) actor: ObjectId, diff --git a/crates/apub_lib/src/traits.rs b/crates/apub_lib/src/traits.rs index 8d819a27..2d542408 100644 --- a/crates/apub_lib/src/traits.rs +++ b/crates/apub_lib/src/traits.rs @@ -5,11 +5,6 @@ pub use lemmy_apub_lib_derive::*; use lemmy_utils::{location_info, LemmyError}; use url::Url; -pub trait ActivityFields { - fn id_unchecked(&self) -> &Url; - fn actor(&self) -> &Url; -} - #[async_trait::async_trait(?Send)] pub trait ActivityHandler { type DataType; diff --git a/crates/apub_lib_derive/src/lib.rs b/crates/apub_lib_derive/src/lib.rs index 1f8d12a7..72e00fe2 100644 --- a/crates/apub_lib_derive/src/lib.rs +++ b/crates/apub_lib_derive/src/lib.rs @@ -127,40 +127,3 @@ fn generate_match_arm(enum_name: &Ident, variant: &Variant, body: &TokenStream) _ => unimplemented!(), } } - -#[proc_macro_derive(ActivityFields)] -pub fn derive_activity_fields(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let input = parse_macro_input!(input as DeriveInput); - - let name = input.ident; - - let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); - - let expanded = match input.data { - Data::Enum(e) => { - let variants = e.variants; - let impl_id = variants - .iter() - .map(|v| generate_match_arm(&name, v, "e! {a.id_unchecked()})); - let impl_actor = variants - .iter() - .map(|v| generate_match_arm(&name, v, "e! {a.actor()})); - quote! { - impl #impl_generics lemmy_apub_lib::traits::ActivityFields for #name #ty_generics #where_clause { - fn id_unchecked(&self) -> &url::Url { match self { #(#impl_id)* } } - fn actor(&self) -> &url::Url { match self { #(#impl_actor)* } } - } - } - } - Data::Struct(_) => { - quote! { - impl #impl_generics lemmy_apub_lib::traits::ActivityFields for #name #ty_generics #where_clause { - fn id_unchecked(&self) -> &url::Url { &self.id } - fn actor(&self) -> &url::Url { &self.actor.inner() } - } - } - } - _ => unimplemented!(), - }; - expanded.into() -}