From 6d447c81cf08f276c08452f87f09cd845022c60a Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Tue, 29 Jun 2021 05:28:18 +0200 Subject: [PATCH] reimplement http signature verification and other checks --- .../src/activities/comment/create.rs | 14 ++--- .../src/activities/comment/delete.rs | 9 ++- .../src/activities/comment/dislike.rs | 9 ++- .../src/activities/comment/like.rs | 9 ++- .../src/activities/comment/remove.rs | 9 ++- .../src/activities/comment/undo_delete.rs | 9 ++- .../src/activities/comment/undo_dislike.rs | 11 ++-- .../src/activities/comment/undo_like.rs | 11 ++-- .../src/activities/comment/undo_remove.rs | 9 ++- .../src/activities/comment/update.rs | 14 ++--- .../src/activities/community/add_mod.rs | 9 ++- .../src/activities/community/announce.rs | 11 ++-- .../src/activities/community/block_user.rs | 9 ++- .../src/activities/community/delete.rs | 16 +++-- .../src/activities/community/remove.rs | 11 ++-- .../src/activities/community/remove_mod.rs | 9 ++- .../activities/community/undo_block_user.rs | 9 ++- .../src/activities/community/undo_delete.rs | 16 +++-- .../src/activities/community/undo_remove.rs | 11 ++-- .../src/activities/community/update.rs | 9 ++- .../src/activities/follow/accept.rs | 9 ++- .../src/activities/follow/follow.rs | 10 ++-- .../src/activities/follow/undo.rs | 10 ++-- .../src/activities/post/create.rs | 12 ++-- .../src/activities/post/delete.rs | 9 ++- .../src/activities/post/dislike.rs | 9 ++- .../apub_receive/src/activities/post/like.rs | 16 ++--- .../src/activities/post/remove.rs | 9 ++- .../src/activities/post/undo_delete.rs | 9 ++- .../src/activities/post/undo_dislike.rs | 11 ++-- .../src/activities/post/undo_like.rs | 11 ++-- .../src/activities/post/undo_remove.rs | 9 ++- .../src/activities/post/update.rs | 12 ++-- .../src/activities/private_message/create.rs | 11 ++-- .../src/activities/private_message/delete.rs | 9 ++- .../activities/private_message/undo_delete.rs | 9 ++- .../src/activities/private_message/update.rs | 11 ++-- crates/apub_receive/src/inbox/mod.rs | 59 +++++++------------ .../src/inbox/new_inbox_routing.rs | 5 +- crates/apub_receive/src/inbox/shared_inbox.rs | 39 +++++++++++- 40 files changed, 229 insertions(+), 264 deletions(-) diff --git a/crates/apub_receive/src/activities/comment/create.rs b/crates/apub_receive/src/activities/comment/create.rs index 569da807f..c50fd50fd 100644 --- a/crates/apub_receive/src/activities/comment/create.rs +++ b/crates/apub_receive/src/activities/comment/create.rs @@ -10,10 +10,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct CreateComment { - actor: Url, to: PublicUrl, object: NoteExt, cc: Vec, @@ -24,9 +23,9 @@ pub struct CreateComment { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(self.id_unchecked(), &self.inner.actor)?; - self.inner.object.id(self.inner.actor.as_str())?; - check_is_apub_id_valid(&self.inner.actor, false) + verify_domains_match(&self.actor, self.id_unchecked())?; + self.inner.object.id(self.actor.as_str())?; + check_is_apub_id_valid(&self.actor, false) } } @@ -40,13 +39,12 @@ impl ReceiveActivity for Activity { let comment = Comment::from_apub( &self.inner.object, context, - self.inner.actor.clone(), + self.actor.clone(), request_counter, false, ) .await?; - let recipients = - get_notif_recipients(&self.inner.actor, &comment, context, request_counter).await?; + let recipients = get_notif_recipients(&self.actor, &comment, context, request_counter).await?; send_websocket_message( comment.id, recipients, diff --git a/crates/apub_receive/src/activities/comment/delete.rs b/crates/apub_receive/src/activities/comment/delete.rs index 75931d149..d82ee501c 100644 --- a/crates/apub_receive/src/activities/comment/delete.rs +++ b/crates/apub_receive/src/activities/comment/delete.rs @@ -9,10 +9,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct DeleteComment { - pub(in crate::activities::comment) actor: Url, to: PublicUrl, pub(in crate::activities::comment) object: Url, cc: [Url; 1], @@ -23,9 +22,9 @@ pub struct DeleteComment { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.actor, &self.inner.object)?; - check_is_apub_id_valid(&self.inner.actor, false) + verify_domains_match(&self.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, &self.inner.object)?; + check_is_apub_id_valid(&self.actor, false) } } diff --git a/crates/apub_receive/src/activities/comment/dislike.rs b/crates/apub_receive/src/activities/comment/dislike.rs index 50aaaf660..5a0cb1cec 100644 --- a/crates/apub_receive/src/activities/comment/dislike.rs +++ b/crates/apub_receive/src/activities/comment/dislike.rs @@ -6,10 +6,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct DislikeComment { - actor: Url, to: PublicUrl, pub(in crate::activities::comment) object: Url, cc: [Url; 1], @@ -20,8 +19,8 @@ pub struct DislikeComment { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.inner.actor, false) + verify_domains_match(&self.actor, self.id_unchecked())?; + check_is_apub_id_valid(&self.actor, false) } } @@ -34,7 +33,7 @@ impl ReceiveActivity for Activity { ) -> Result<(), LemmyError> { like_or_dislike_comment( -1, - &self.inner.actor, + &self.actor, &self.inner.object, context, request_counter, diff --git a/crates/apub_receive/src/activities/comment/like.rs b/crates/apub_receive/src/activities/comment/like.rs index bfb1867da..ea1bad49b 100644 --- a/crates/apub_receive/src/activities/comment/like.rs +++ b/crates/apub_receive/src/activities/comment/like.rs @@ -6,10 +6,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct LikeComment { - actor: Url, to: PublicUrl, pub(in crate::activities::comment) object: Url, cc: [Url; 1], @@ -20,8 +19,8 @@ pub struct LikeComment { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.inner.actor, false) + verify_domains_match(&self.actor, self.id_unchecked())?; + check_is_apub_id_valid(&self.actor, false) } } @@ -34,7 +33,7 @@ impl ReceiveActivity for Activity { ) -> Result<(), LemmyError> { like_or_dislike_comment( -1, - &self.inner.actor, + &self.actor, &self.inner.object, context, request_counter, diff --git a/crates/apub_receive/src/activities/comment/remove.rs b/crates/apub_receive/src/activities/comment/remove.rs index 172694eb8..d8f64154e 100644 --- a/crates/apub_receive/src/activities/comment/remove.rs +++ b/crates/apub_receive/src/activities/comment/remove.rs @@ -12,10 +12,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct RemoveComment { - actor: Url, to: PublicUrl, pub(in crate::activities::comment) object: Url, cc: [Url; 1], @@ -26,9 +25,9 @@ pub struct RemoveComment { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.inner.actor, false)?; - verify_mod_action(self.inner.actor.clone(), self.inner.cc[0].clone(), context).await + verify_domains_match(&self.actor, self.id_unchecked())?; + check_is_apub_id_valid(&self.actor, false)?; + verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await } } diff --git a/crates/apub_receive/src/activities/comment/undo_delete.rs b/crates/apub_receive/src/activities/comment/undo_delete.rs index 35f0ce58a..7eaa76f0d 100644 --- a/crates/apub_receive/src/activities/comment/undo_delete.rs +++ b/crates/apub_receive/src/activities/comment/undo_delete.rs @@ -12,10 +12,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoDeleteComment { - actor: Url, to: PublicUrl, object: Activity, cc: [Url; 1], @@ -26,9 +25,9 @@ pub struct UndoDeleteComment { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.actor, &self.inner.object.inner.actor)?; - check_is_apub_id_valid(&self.inner.actor, false)?; + verify_domains_match(&self.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, &self.inner.object.actor)?; + check_is_apub_id_valid(&self.actor, false)?; self.inner.object.verify(context).await } } diff --git a/crates/apub_receive/src/activities/comment/undo_dislike.rs b/crates/apub_receive/src/activities/comment/undo_dislike.rs index 4262e255a..d03db3160 100644 --- a/crates/apub_receive/src/activities/comment/undo_dislike.rs +++ b/crates/apub_receive/src/activities/comment/undo_dislike.rs @@ -9,10 +9,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoDislikeComment { - actor: Url, to: PublicUrl, object: Activity, cc: [Url; 1], @@ -23,9 +22,9 @@ pub struct UndoDislikeComment { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.actor, &self.inner.object.inner.object)?; - check_is_apub_id_valid(&self.inner.actor, false)?; + verify_domains_match(&self.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, &self.inner.object.inner.object)?; + check_is_apub_id_valid(&self.actor, false)?; self.inner.object.verify(context).await } } @@ -38,7 +37,7 @@ impl ReceiveActivity for Activity { request_counter: &mut i32, ) -> Result<(), LemmyError> { undo_like_or_dislike_comment( - &self.inner.actor, + &self.actor, &self.inner.object.inner.object, context, request_counter, diff --git a/crates/apub_receive/src/activities/comment/undo_like.rs b/crates/apub_receive/src/activities/comment/undo_like.rs index cefa73e4c..f0467f4f9 100644 --- a/crates/apub_receive/src/activities/comment/undo_like.rs +++ b/crates/apub_receive/src/activities/comment/undo_like.rs @@ -9,10 +9,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoLikeComment { - actor: Url, to: PublicUrl, object: Activity, cc: [Url; 1], @@ -23,9 +22,9 @@ pub struct UndoLikeComment { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.actor, &self.inner.object.inner.object)?; - check_is_apub_id_valid(&self.inner.actor, false)?; + verify_domains_match(&self.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, &self.inner.object.inner.object)?; + check_is_apub_id_valid(&self.actor, false)?; self.inner.object.verify(context).await } } @@ -38,7 +37,7 @@ impl ReceiveActivity for Activity { request_counter: &mut i32, ) -> Result<(), LemmyError> { undo_like_or_dislike_comment( - &self.inner.actor, + &self.actor, &self.inner.object.inner.object, context, request_counter, diff --git a/crates/apub_receive/src/activities/comment/undo_remove.rs b/crates/apub_receive/src/activities/comment/undo_remove.rs index 28d17f113..88e377fbf 100644 --- a/crates/apub_receive/src/activities/comment/undo_remove.rs +++ b/crates/apub_receive/src/activities/comment/undo_remove.rs @@ -15,10 +15,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoRemoveComment { - actor: Url, to: PublicUrl, object: Activity, cc: [Url; 1], @@ -29,9 +28,9 @@ pub struct UndoRemoveComment { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.inner.actor, false)?; - verify_mod_action(self.inner.actor.clone(), self.inner.cc[0].clone(), context).await?; + verify_domains_match(&self.actor, self.id_unchecked())?; + check_is_apub_id_valid(&self.actor, false)?; + verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?; self.inner.object.verify(context).await } } diff --git a/crates/apub_receive/src/activities/comment/update.rs b/crates/apub_receive/src/activities/comment/update.rs index 258457f31..191d720a7 100644 --- a/crates/apub_receive/src/activities/comment/update.rs +++ b/crates/apub_receive/src/activities/comment/update.rs @@ -10,10 +10,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UpdateComment { - actor: Url, to: PublicUrl, object: NoteExt, cc: Vec, @@ -24,9 +23,9 @@ pub struct UpdateComment { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(self.id_unchecked(), &self.inner.actor)?; - self.inner.object.id(self.inner.actor.as_str())?; - check_is_apub_id_valid(&self.inner.actor, false) + verify_domains_match(&self.actor, self.id_unchecked())?; + self.inner.object.id(self.actor.as_str())?; + check_is_apub_id_valid(&self.actor, false) } } @@ -40,14 +39,13 @@ impl ReceiveActivity for Activity { let comment = Comment::from_apub( &self.inner.object, context, - self.inner.actor.clone(), + self.actor.clone(), request_counter, false, ) .await?; - let recipients = - get_notif_recipients(&self.inner.actor, &comment, context, request_counter).await?; + let recipients = get_notif_recipients(&self.actor, &comment, context, request_counter).await?; send_websocket_message( comment.id, recipients, diff --git a/crates/apub_receive/src/activities/community/add_mod.rs b/crates/apub_receive/src/activities/community/add_mod.rs index b260f9870..86aeafee4 100644 --- a/crates/apub_receive/src/activities/community/add_mod.rs +++ b/crates/apub_receive/src/activities/community/add_mod.rs @@ -16,10 +16,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct AddModToCommunity { - actor: Url, to: PublicUrl, object: Url, target: Url, @@ -31,10 +30,10 @@ pub struct AddModToCommunity { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, self.id_unchecked())?; verify_domains_match(&self.inner.target, &self.inner.cc[0])?; - check_is_apub_id_valid(&self.inner.actor, false)?; - verify_mod_action(self.inner.actor.clone(), self.inner.cc[0].clone(), context).await?; + check_is_apub_id_valid(&self.actor, false)?; + verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?; verify_add_remove_moderator_target(&self.inner.target, self.inner.cc[0].clone()) } } diff --git a/crates/apub_receive/src/activities/community/announce.rs b/crates/apub_receive/src/activities/community/announce.rs index f189c011a..1b4d14ff0 100644 --- a/crates/apub_receive/src/activities/community/announce.rs +++ b/crates/apub_receive/src/activities/community/announce.rs @@ -43,7 +43,7 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] pub enum AnnouncableActivities { CreateComment(CreateComment), UpdateComment(UpdateComment), @@ -93,10 +93,9 @@ impl ReceiveActivity for AnnouncableActivities { } } -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct AnnounceActivity { - actor: Url, to: PublicUrl, object: Activity, cc: [Url; 1], @@ -107,9 +106,9 @@ pub struct AnnounceActivity { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.actor, &self.inner.cc[0])?; - check_is_apub_id_valid(&self.inner.actor, false)?; + verify_domains_match(&self.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, &self.inner.cc[0])?; + check_is_apub_id_valid(&self.actor, false)?; self.inner.object.inner.verify(context).await } } diff --git a/crates/apub_receive/src/activities/community/block_user.rs b/crates/apub_receive/src/activities/community/block_user.rs index 6a2b5a40d..9c2158e70 100644 --- a/crates/apub_receive/src/activities/community/block_user.rs +++ b/crates/apub_receive/src/activities/community/block_user.rs @@ -17,10 +17,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct BlockUserFromCommunity { - actor: Url, to: PublicUrl, pub(in crate::activities::community) object: Url, cc: [Url; 1], @@ -31,9 +30,9 @@ pub struct BlockUserFromCommunity { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.inner.actor, false)?; - verify_mod_action(self.inner.actor.clone(), self.inner.cc[0].clone(), context).await + verify_domains_match(&self.actor, self.id_unchecked())?; + check_is_apub_id_valid(&self.actor, false)?; + verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await } } diff --git a/crates/apub_receive/src/activities/community/delete.rs b/crates/apub_receive/src/activities/community/delete.rs index 96757c792..71722e9ed 100644 --- a/crates/apub_receive/src/activities/community/delete.rs +++ b/crates/apub_receive/src/activities/community/delete.rs @@ -20,10 +20,9 @@ use url::Url; // We have two possibilities which need to be handled: // 1. actor is remote mod, community id in object // 2. actor is community, cc is followers collection -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct DeleteCommunity { - actor: Url, to: PublicUrl, pub(in crate::activities::community) object: Url, cc: [Url; 1], @@ -34,7 +33,7 @@ pub struct DeleteCommunity { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, self.id_unchecked())?; let object = self.inner.object.clone(); let community = blocking(context.pool(), move |conn| { Community::read_from_apub_id(conn, &object.into()) @@ -43,13 +42,13 @@ impl VerifyActivity for Activity { // remote mod action on local community if let Ok(c) = community { verify_domains_match(&self.inner.object, &self.inner.cc[0])?; - check_is_apub_id_valid(&self.inner.actor, false)?; - verify_is_community_mod(self.inner.actor.clone(), c.actor_id(), context).await + check_is_apub_id_valid(&self.actor, false)?; + verify_is_community_mod(self.actor.clone(), c.actor_id(), context).await } // community action sent to followers else { - verify_domains_match(&self.inner.actor, &self.inner.object)?; - verify_domains_match(&self.inner.actor, &self.inner.cc[0]) + verify_domains_match(&self.actor, &self.inner.object)?; + verify_domains_match(&self.actor, &self.inner.cc[0]) } } } @@ -69,8 +68,7 @@ impl ReceiveActivity for Activity { let community_id = match community { Ok(c) => { // remote mod sent delete to local community, forward it to followers - let actor = - get_or_fetch_and_upsert_person(&self.inner.actor, context, request_counter).await?; + let actor = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?; c.send_delete(actor, context).await?; c.id } diff --git a/crates/apub_receive/src/activities/community/remove.rs b/crates/apub_receive/src/activities/community/remove.rs index fcc838363..7d08523cb 100644 --- a/crates/apub_receive/src/activities/community/remove.rs +++ b/crates/apub_receive/src/activities/community/remove.rs @@ -9,10 +9,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct RemoveCommunity { - actor: Url, to: PublicUrl, pub(in crate::activities::community) object: Url, cc: [Url; 1], @@ -23,10 +22,10 @@ pub struct RemoveCommunity { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.inner.actor, false)?; - verify_domains_match(&self.inner.actor, &self.inner.object)?; - verify_domains_match(&self.inner.actor, &self.inner.cc[0]) + verify_domains_match(&self.actor, self.id_unchecked())?; + check_is_apub_id_valid(&self.actor, false)?; + verify_domains_match(&self.actor, &self.inner.object)?; + verify_domains_match(&self.actor, &self.inner.cc[0]) } } diff --git a/crates/apub_receive/src/activities/community/remove_mod.rs b/crates/apub_receive/src/activities/community/remove_mod.rs index b9a5468e3..8a9cd4713 100644 --- a/crates/apub_receive/src/activities/community/remove_mod.rs +++ b/crates/apub_receive/src/activities/community/remove_mod.rs @@ -16,10 +16,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct RemoveModToCommunity { - actor: Url, to: PublicUrl, object: Url, target: Url, @@ -31,10 +30,10 @@ pub struct RemoveModToCommunity { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, self.id_unchecked())?; verify_domains_match(&self.inner.target, &self.inner.cc[0])?; - check_is_apub_id_valid(&self.inner.actor, false)?; - verify_mod_action(self.inner.actor.clone(), self.inner.cc[0].clone(), context).await?; + check_is_apub_id_valid(&self.actor, false)?; + verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?; verify_add_remove_moderator_target(&self.inner.target, self.inner.cc[0].clone()) } } 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 5701474f2..caa4218a8 100644 --- a/crates/apub_receive/src/activities/community/undo_block_user.rs +++ b/crates/apub_receive/src/activities/community/undo_block_user.rs @@ -15,10 +15,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoBlockUserFromCommunity { - actor: Url, to: PublicUrl, object: Activity, cc: [Url; 1], @@ -29,9 +28,9 @@ pub struct UndoBlockUserFromCommunity { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.inner.actor, false)?; - verify_mod_action(self.inner.actor.clone(), self.inner.cc[0].clone(), context).await?; + verify_domains_match(&self.actor, self.id_unchecked())?; + check_is_apub_id_valid(&self.actor, false)?; + verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?; self.inner.object.verify(context).await } } diff --git a/crates/apub_receive/src/activities/community/undo_delete.rs b/crates/apub_receive/src/activities/community/undo_delete.rs index 5549f1a21..80fb2695d 100644 --- a/crates/apub_receive/src/activities/community/undo_delete.rs +++ b/crates/apub_receive/src/activities/community/undo_delete.rs @@ -24,10 +24,9 @@ use url::Url; // We have two possibilities which need to be handled: // 1. actor is remote mod, community id in object // 2. actor is community, cc is followers collection -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoDeleteCommunity { - actor: Url, to: PublicUrl, object: Activity, cc: [Url; 1], @@ -38,7 +37,7 @@ pub struct UndoDeleteCommunity { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, self.id_unchecked())?; let object = self.inner.object.inner.object.clone(); let community = blocking(context.pool(), move |conn| { Community::read_from_apub_id(conn, &object.into()) @@ -47,13 +46,13 @@ impl VerifyActivity for Activity { // remote mod action on local community if let Ok(c) = community { verify_domains_match(&self.inner.object.inner.object, &self.inner.cc[0])?; - check_is_apub_id_valid(&self.inner.actor, false)?; - verify_is_community_mod(self.inner.actor.clone(), c.actor_id(), context).await?; + check_is_apub_id_valid(&self.actor, false)?; + verify_is_community_mod(self.actor.clone(), c.actor_id(), context).await?; } // community action sent to followers else { - verify_domains_match(&self.inner.actor, &self.inner.object.inner.object)?; - verify_domains_match(&self.inner.actor, &self.inner.cc[0])?; + verify_domains_match(&self.actor, &self.inner.object.inner.object)?; + verify_domains_match(&self.actor, &self.inner.cc[0])?; } self.inner.object.verify(context).await } @@ -74,8 +73,7 @@ impl ReceiveActivity for Activity { let community_id = match community { Ok(c) => { // remote mod sent undo to local community, forward it to followers - let actor = - get_or_fetch_and_upsert_person(&self.inner.actor, context, request_counter).await?; + let actor = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?; c.send_delete(actor, context).await?; c.id } diff --git a/crates/apub_receive/src/activities/community/undo_remove.rs b/crates/apub_receive/src/activities/community/undo_remove.rs index 0686e7922..843db5bb6 100644 --- a/crates/apub_receive/src/activities/community/undo_remove.rs +++ b/crates/apub_receive/src/activities/community/undo_remove.rs @@ -12,10 +12,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoRemoveCommunity { - actor: Url, to: PublicUrl, object: Activity, cc: [Url; 1], @@ -26,10 +25,10 @@ pub struct UndoRemoveCommunity { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.inner.actor, false)?; - verify_domains_match(&self.inner.actor, &self.inner.object.inner.object)?; - verify_domains_match(&self.inner.actor, &self.inner.cc[0])?; + verify_domains_match(&self.actor, self.id_unchecked())?; + check_is_apub_id_valid(&self.actor, false)?; + verify_domains_match(&self.actor, &self.inner.object.inner.object)?; + verify_domains_match(&self.actor, &self.inner.cc[0])?; self.inner.object.verify(context).await } } diff --git a/crates/apub_receive/src/activities/community/update.rs b/crates/apub_receive/src/activities/community/update.rs index b938c6cda..552150f05 100644 --- a/crates/apub_receive/src/activities/community/update.rs +++ b/crates/apub_receive/src/activities/community/update.rs @@ -14,10 +14,9 @@ use url::Url; /// This activity is received from a remote community mod, and updates the description or other /// fields of a local community. -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UpdateCommunity { - actor: Url, to: PublicUrl, object: GroupExt, cc: [Url; 1], @@ -28,10 +27,10 @@ pub struct UpdateCommunity { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, self.id_unchecked())?; self.inner.object.id(self.inner.cc[0].as_str())?; - check_is_apub_id_valid(&self.inner.actor, false)?; - verify_is_community_mod(self.inner.actor.clone(), self.inner.cc[0].clone(), context).await + check_is_apub_id_valid(&self.actor, false)?; + verify_is_community_mod(self.actor.clone(), self.inner.cc[0].clone(), context).await } } diff --git a/crates/apub_receive/src/activities/follow/accept.rs b/crates/apub_receive/src/activities/follow/accept.rs index a077ff2bf..b758b209e 100644 --- a/crates/apub_receive/src/activities/follow/accept.rs +++ b/crates/apub_receive/src/activities/follow/accept.rs @@ -12,10 +12,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct AcceptFollowCommunity { - actor: Url, to: Url, object: Activity, #[serde(rename = "type")] @@ -25,8 +24,8 @@ pub struct AcceptFollowCommunity { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.inner.actor, false)?; + verify_domains_match(&self.actor, self.id_unchecked())?; + check_is_apub_id_valid(&self.actor, false)?; self.inner.object.verify(context).await } } @@ -40,7 +39,7 @@ impl ReceiveActivity for Activity { request_counter: &mut i32, ) -> Result<(), LemmyError> { let community = - get_or_fetch_and_upsert_community(&self.inner.actor, context, request_counter).await?; + get_or_fetch_and_upsert_community(&self.actor, context, request_counter).await?; let person = get_or_fetch_and_upsert_person(&self.inner.to, context, request_counter).await?; // This will throw an error if no follow was requested blocking(&context.pool(), move |conn| { diff --git a/crates/apub_receive/src/activities/follow/follow.rs b/crates/apub_receive/src/activities/follow/follow.rs index 92158c77f..8da7136d2 100644 --- a/crates/apub_receive/src/activities/follow/follow.rs +++ b/crates/apub_receive/src/activities/follow/follow.rs @@ -17,10 +17,9 @@ use lemmy_utils::{location_info, LemmyError}; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct FollowCommunity { - actor: Url, to: Url, pub(in crate::activities::follow) object: Url, #[serde(rename = "type")] @@ -30,9 +29,9 @@ pub struct FollowCommunity { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, self.id_unchecked())?; verify_domains_match(&self.inner.to, &self.inner.object)?; - check_is_apub_id_valid(&self.inner.actor, false) + check_is_apub_id_valid(&self.actor, false) } } @@ -45,8 +44,7 @@ impl ReceiveActivity for Activity { ) -> Result<(), LemmyError> { let community = get_or_fetch_and_upsert_community(&self.inner.object, context, request_counter).await?; - let person = - get_or_fetch_and_upsert_person(&self.inner.actor, context, request_counter).await?; + let person = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?; let community_follower_form = CommunityFollowerForm { community_id: community.id, person_id: person.id, diff --git a/crates/apub_receive/src/activities/follow/undo.rs b/crates/apub_receive/src/activities/follow/undo.rs index 680e6b557..030fdebcd 100644 --- a/crates/apub_receive/src/activities/follow/undo.rs +++ b/crates/apub_receive/src/activities/follow/undo.rs @@ -12,10 +12,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoFollowCommunity { - actor: Url, to: Url, object: Activity, #[serde(rename = "type")] @@ -25,9 +24,9 @@ pub struct UndoFollowCommunity { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, self.id_unchecked())?; verify_domains_match(&self.inner.to, &self.inner.object.inner.object)?; - check_is_apub_id_valid(&self.inner.actor, false)?; + check_is_apub_id_valid(&self.actor, false)?; self.inner.object.verify(context).await } } @@ -41,8 +40,7 @@ impl ReceiveActivity for Activity { ) -> Result<(), LemmyError> { let community = get_or_fetch_and_upsert_community(&self.inner.to, context, request_counter).await?; - let person = - get_or_fetch_and_upsert_person(&self.inner.actor, context, request_counter).await?; + let person = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?; let community_follower_form = CommunityFollowerForm { community_id: community.id, diff --git a/crates/apub_receive/src/activities/post/create.rs b/crates/apub_receive/src/activities/post/create.rs index 8fddd177e..87324eb10 100644 --- a/crates/apub_receive/src/activities/post/create.rs +++ b/crates/apub_receive/src/activities/post/create.rs @@ -13,10 +13,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct CreatePost { - actor: Url, to: PublicUrl, object: PageExt, cc: Vec, @@ -27,9 +26,9 @@ pub struct CreatePost { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(self.id_unchecked(), &self.inner.actor)?; - self.inner.object.id(self.inner.actor.as_str())?; - check_is_apub_id_valid(&self.inner.actor, false) + verify_domains_match(self.id_unchecked(), &self.actor)?; + self.inner.object.id(self.actor.as_str())?; + check_is_apub_id_valid(&self.actor, false) } } @@ -40,8 +39,7 @@ impl ReceiveActivity for Activity { context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - let person = - get_or_fetch_and_upsert_person(&self.inner.actor, context, request_counter).await?; + let person = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?; let post = Post::from_apub( &self.inner.object, diff --git a/crates/apub_receive/src/activities/post/delete.rs b/crates/apub_receive/src/activities/post/delete.rs index 84baa112b..270ec028d 100644 --- a/crates/apub_receive/src/activities/post/delete.rs +++ b/crates/apub_receive/src/activities/post/delete.rs @@ -9,10 +9,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct DeletePost { - pub(in crate::activities::post) actor: Url, to: PublicUrl, pub(in crate::activities::post) object: Url, cc: [Url; 1], @@ -23,9 +22,9 @@ pub struct DeletePost { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.actor, &self.inner.object)?; - check_is_apub_id_valid(&self.inner.actor, false) + verify_domains_match(&self.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, &self.inner.object)?; + check_is_apub_id_valid(&self.actor, false) } } diff --git a/crates/apub_receive/src/activities/post/dislike.rs b/crates/apub_receive/src/activities/post/dislike.rs index 4c06aabde..e53254d1c 100644 --- a/crates/apub_receive/src/activities/post/dislike.rs +++ b/crates/apub_receive/src/activities/post/dislike.rs @@ -6,10 +6,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct DislikePost { - actor: Url, to: PublicUrl, pub(in crate::activities::post) object: Url, cc: [Url; 1], @@ -20,8 +19,8 @@ pub struct DislikePost { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.inner.actor, false) + verify_domains_match(&self.actor, self.id_unchecked())?; + check_is_apub_id_valid(&self.actor, false) } } @@ -34,7 +33,7 @@ impl ReceiveActivity for Activity { ) -> Result<(), LemmyError> { like_or_dislike_post( -1, - &self.inner.actor, + &self.actor, &self.inner.object, context, request_counter, diff --git a/crates/apub_receive/src/activities/post/like.rs b/crates/apub_receive/src/activities/post/like.rs index 4a815a2f1..2dbf4e63c 100644 --- a/crates/apub_receive/src/activities/post/like.rs +++ b/crates/apub_receive/src/activities/post/like.rs @@ -6,10 +6,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct LikePost { - actor: Url, to: PublicUrl, pub(in crate::activities::post) object: Url, cc: [Url; 1], @@ -20,8 +19,8 @@ pub struct LikePost { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.inner.actor, false) + verify_domains_match(&self.actor, self.id_unchecked())?; + check_is_apub_id_valid(&self.actor, false) } } @@ -32,13 +31,6 @@ impl ReceiveActivity for Activity { context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - like_or_dislike_post( - 1, - &self.inner.actor, - &self.inner.object, - context, - request_counter, - ) - .await + like_or_dislike_post(1, &self.actor, &self.inner.object, context, request_counter).await } } diff --git a/crates/apub_receive/src/activities/post/remove.rs b/crates/apub_receive/src/activities/post/remove.rs index 4bf6b708d..756ddca4c 100644 --- a/crates/apub_receive/src/activities/post/remove.rs +++ b/crates/apub_receive/src/activities/post/remove.rs @@ -12,10 +12,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct RemovePost { - actor: Url, to: PublicUrl, pub(in crate::activities::post) object: Url, cc: [Url; 1], @@ -26,9 +25,9 @@ pub struct RemovePost { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.inner.actor, false)?; - verify_mod_action(self.inner.actor.clone(), self.inner.cc[0].clone(), context).await + verify_domains_match(&self.actor, self.id_unchecked())?; + check_is_apub_id_valid(&self.actor, false)?; + verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await } } diff --git a/crates/apub_receive/src/activities/post/undo_delete.rs b/crates/apub_receive/src/activities/post/undo_delete.rs index c71c69272..b845c82b4 100644 --- a/crates/apub_receive/src/activities/post/undo_delete.rs +++ b/crates/apub_receive/src/activities/post/undo_delete.rs @@ -12,10 +12,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoDeletePost { - actor: Url, to: PublicUrl, object: Activity, cc: [Url; 1], @@ -26,9 +25,9 @@ pub struct UndoDeletePost { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.actor, &self.inner.object.inner.actor)?; - check_is_apub_id_valid(&self.inner.actor, false)?; + verify_domains_match(&self.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, &self.inner.object.actor)?; + check_is_apub_id_valid(&self.actor, false)?; self.inner.object.verify(context).await } } diff --git a/crates/apub_receive/src/activities/post/undo_dislike.rs b/crates/apub_receive/src/activities/post/undo_dislike.rs index e01223a6a..dbc29d777 100644 --- a/crates/apub_receive/src/activities/post/undo_dislike.rs +++ b/crates/apub_receive/src/activities/post/undo_dislike.rs @@ -9,10 +9,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoDislikePost { - actor: Url, to: PublicUrl, object: Activity, cc: [Url; 1], @@ -23,9 +22,9 @@ pub struct UndoDislikePost { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.actor, &self.inner.object.inner.object)?; - check_is_apub_id_valid(&self.inner.actor, false)?; + verify_domains_match(&self.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, &self.inner.object.inner.object)?; + check_is_apub_id_valid(&self.actor, false)?; self.inner.object.verify(context).await } } @@ -38,7 +37,7 @@ impl ReceiveActivity for Activity { request_counter: &mut i32, ) -> Result<(), LemmyError> { undo_like_or_dislike_post( - &self.inner.actor, + &self.actor, &self.inner.object.inner.object, context, request_counter, diff --git a/crates/apub_receive/src/activities/post/undo_like.rs b/crates/apub_receive/src/activities/post/undo_like.rs index 7079b1f19..7a9b33af4 100644 --- a/crates/apub_receive/src/activities/post/undo_like.rs +++ b/crates/apub_receive/src/activities/post/undo_like.rs @@ -9,10 +9,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoLikePost { - actor: Url, to: PublicUrl, object: Activity, cc: [Url; 1], @@ -23,9 +22,9 @@ pub struct UndoLikePost { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.actor, &self.inner.object.inner.object)?; - check_is_apub_id_valid(&self.inner.actor, false)?; + verify_domains_match(&self.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, &self.inner.object.inner.object)?; + check_is_apub_id_valid(&self.actor, false)?; self.inner.object.verify(context).await } } @@ -38,7 +37,7 @@ impl ReceiveActivity for Activity { request_counter: &mut i32, ) -> Result<(), LemmyError> { undo_like_or_dislike_post( - &self.inner.actor, + &self.actor, &self.inner.object.inner.object, context, request_counter, diff --git a/crates/apub_receive/src/activities/post/undo_remove.rs b/crates/apub_receive/src/activities/post/undo_remove.rs index d22a72489..6b9e9c6e0 100644 --- a/crates/apub_receive/src/activities/post/undo_remove.rs +++ b/crates/apub_receive/src/activities/post/undo_remove.rs @@ -15,10 +15,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoRemovePost { - actor: Url, to: PublicUrl, object: Activity, cc: [Url; 1], @@ -29,9 +28,9 @@ pub struct UndoRemovePost { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - check_is_apub_id_valid(&self.inner.actor, false)?; - verify_mod_action(self.inner.actor.clone(), self.inner.cc[0].clone(), context).await?; + verify_domains_match(&self.actor, self.id_unchecked())?; + check_is_apub_id_valid(&self.actor, false)?; + verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?; self.inner.object.verify(context).await } } diff --git a/crates/apub_receive/src/activities/post/update.rs b/crates/apub_receive/src/activities/post/update.rs index 9bd2fa734..1a420b5a8 100644 --- a/crates/apub_receive/src/activities/post/update.rs +++ b/crates/apub_receive/src/activities/post/update.rs @@ -22,10 +22,9 @@ use lemmy_utils::{location_info, LemmyError}; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UpdatePost { - actor: Url, to: PublicUrl, object: PageExt, cc: Vec, @@ -36,9 +35,9 @@ pub struct UpdatePost { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(self.id_unchecked(), &self.inner.actor)?; - self.inner.object.id(self.inner.actor.as_str())?; - check_is_apub_id_valid(&self.inner.actor, false) + verify_domains_match(&self.actor, self.id_unchecked())?; + self.inner.object.id(self.actor.as_str())?; + check_is_apub_id_valid(&self.actor, false) } } @@ -49,8 +48,7 @@ impl ReceiveActivity for Activity { context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { - let person = - get_or_fetch_and_upsert_person(&self.inner.actor, context, request_counter).await?; + let person = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?; let temp_post = PostForm::from_apub( &self.inner.object, context, diff --git a/crates/apub_receive/src/activities/private_message/create.rs b/crates/apub_receive/src/activities/private_message/create.rs index 5f973e15f..e1a01237b 100644 --- a/crates/apub_receive/src/activities/private_message/create.rs +++ b/crates/apub_receive/src/activities/private_message/create.rs @@ -10,10 +10,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct CreatePrivateMessage { - actor: Url, to: Url, object: NoteExt, #[serde(rename = "type")] @@ -23,9 +22,9 @@ pub struct CreatePrivateMessage { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(self.id_unchecked(), &self.inner.actor)?; - self.inner.object.id(self.inner.actor.as_str())?; - check_is_apub_id_valid(&self.inner.actor, false) + verify_domains_match(self.id_unchecked(), &self.actor)?; + self.inner.object.id(self.actor.as_str())?; + check_is_apub_id_valid(&self.actor, false) } } @@ -39,7 +38,7 @@ impl ReceiveActivity for Activity { let private_message = PrivateMessage::from_apub( &self.inner.object, context, - self.inner.actor.clone(), + self.actor.clone(), request_counter, false, ) diff --git a/crates/apub_receive/src/activities/private_message/delete.rs b/crates/apub_receive/src/activities/private_message/delete.rs index 68654bd42..4c4e8b04d 100644 --- a/crates/apub_receive/src/activities/private_message/delete.rs +++ b/crates/apub_receive/src/activities/private_message/delete.rs @@ -12,10 +12,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct DeletePrivateMessage { - actor: Url, to: Url, pub(in crate::activities::private_message) object: Url, #[serde(rename = "type")] @@ -25,9 +24,9 @@ pub struct DeletePrivateMessage { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.actor, &self.inner.object)?; - check_is_apub_id_valid(&self.inner.actor, false) + verify_domains_match(&self.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, &self.inner.object)?; + check_is_apub_id_valid(&self.actor, false) } } 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 63a0ee5cb..691f911db 100644 --- a/crates/apub_receive/src/activities/private_message/undo_delete.rs +++ b/crates/apub_receive/src/activities/private_message/undo_delete.rs @@ -12,10 +12,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UndoDeletePrivateMessage { - actor: Url, to: Url, object: Activity, #[serde(rename = "type")] @@ -25,9 +24,9 @@ pub struct UndoDeletePrivateMessage { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(&self.inner.actor, self.id_unchecked())?; - verify_domains_match(&self.inner.actor, &self.inner.object.id_unchecked())?; - check_is_apub_id_valid(&self.inner.actor, false)?; + verify_domains_match(&self.actor, self.id_unchecked())?; + verify_domains_match(&self.actor, &self.inner.object.id_unchecked())?; + check_is_apub_id_valid(&self.actor, false)?; self.inner.object.verify(context).await } } diff --git a/crates/apub_receive/src/activities/private_message/update.rs b/crates/apub_receive/src/activities/private_message/update.rs index 398ed0702..4124a6c84 100644 --- a/crates/apub_receive/src/activities/private_message/update.rs +++ b/crates/apub_receive/src/activities/private_message/update.rs @@ -10,10 +10,9 @@ use lemmy_utils::LemmyError; use lemmy_websocket::{LemmyContext, UserOperationCrud}; use url::Url; -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct UpdatePrivateMessage { - actor: Url, to: Url, object: NoteExt, #[serde(rename = "type")] @@ -23,9 +22,9 @@ pub struct UpdatePrivateMessage { #[async_trait::async_trait(?Send)] impl VerifyActivity for Activity { async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> { - verify_domains_match(self.id_unchecked(), &self.inner.actor)?; - self.inner.object.id(self.inner.actor.as_str())?; - check_is_apub_id_valid(&self.inner.actor, false) + verify_domains_match(self.id_unchecked(), &self.actor)?; + self.inner.object.id(self.actor.as_str())?; + check_is_apub_id_valid(&self.actor, false) } } @@ -39,7 +38,7 @@ impl ReceiveActivity for Activity { let private_message = PrivateMessage::from_apub( &self.inner.object, context, - self.inner.actor.clone(), + self.actor.clone(), request_counter, false, ) diff --git a/crates/apub_receive/src/inbox/mod.rs b/crates/apub_receive/src/inbox/mod.rs index 0e541b2f4..bb566c8c5 100644 --- a/crates/apub_receive/src/inbox/mod.rs +++ b/crates/apub_receive/src/inbox/mod.rs @@ -1,22 +1,10 @@ -use activitystreams::{ - activity::ActorAndObjectRefExt, - base::{AsBase, Extends}, - object::AsObject, -}; -use actix_web::HttpRequest; -use anyhow::Context; +use crate::inbox::new_inbox_routing::Activity; +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, - ActorType, -}; use lemmy_db_queries::{source::activity::Activity_, DbPool}; -use lemmy_db_schema::source::activity::Activity; -use lemmy_utils::{location_info, LemmyError}; -use lemmy_websocket::LemmyContext; -use serde::Serialize; +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; @@ -30,7 +18,7 @@ pub(crate) async fn is_activity_already_known( ) -> Result { let activity_id = activity_id.to_owned().into(); let existing = blocking(pool, move |conn| { - Activity::read_from_apub_id(&conn, &activity_id) + DbActivity::read_from_apub_id(&conn, &activity_id) }) .await?; match existing { @@ -39,24 +27,19 @@ pub(crate) async fn is_activity_already_known( } } -pub(crate) async fn inbox_verify_http_signature( - activity: &T, - context: &LemmyContext, - request: HttpRequest, - request_counter: &mut i32, -) -> Result, LemmyError> -where - T: AsObject + ActorAndObjectRefExt + Extends + AsBase, - Kind: Serialize, - >::Error: From + Send + Sync + 'static, -{ - let actor_id = activity - .actor()? - .to_owned() - .single_xsd_any_uri() - .context(location_info!())?; - check_is_apub_id_valid(&actor_id, false)?; - let actor = get_or_fetch_and_upsert_actor(&actor_id, &context, request_counter).await?; - verify_signature(&request, actor.as_ref())?; - Ok(actor) +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/new_inbox_routing.rs b/crates/apub_receive/src/inbox/new_inbox_routing.rs index 615d54a15..ff0bb5a0f 100644 --- a/crates/apub_receive/src/inbox/new_inbox_routing.rs +++ b/crates/apub_receive/src/inbox/new_inbox_routing.rs @@ -49,12 +49,13 @@ use url::Url; // 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(Debug, Clone, serde::Deserialize, serde::Serialize)] +#[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)] @@ -71,7 +72,7 @@ impl Activity { } } -#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] pub enum SharedInboxActivities { FollowCommunity(FollowCommunity), AcceptFollowCommunity(AcceptFollowCommunity), diff --git a/crates/apub_receive/src/inbox/shared_inbox.rs b/crates/apub_receive/src/inbox/shared_inbox.rs index 262979775..1fb986d0e 100644 --- a/crates/apub_receive/src/inbox/shared_inbox.rs +++ b/crates/apub_receive/src/inbox/shared_inbox.rs @@ -1,17 +1,50 @@ -use crate::inbox::new_inbox_routing::{Activity, SharedInboxActivities}; +use crate::inbox::{ + assert_activity_not_local, + is_activity_already_known, + new_inbox_routing::{Activity, SharedInboxActivities}, +}; use actix_web::{web, HttpRequest, HttpResponse}; +use lemmy_apub::{ + check_is_apub_id_valid, + extensions::signatures::verify_signature, + fetcher::get_or_fetch_and_upsert_actor, + insert_activity, +}; use lemmy_apub_lib::{ReceiveActivity, VerifyActivity}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; pub async fn shared_inbox( - _request: HttpRequest, + 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_actor(&activity.actor, &context, request_counter).await?; + verify_signature(&request, actor.as_ref())?; + + // 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?; + + // TODO: pass the actor in somehow activity.inner.receive(&context, request_counter).await?; - todo!() + return Ok(HttpResponse::Ok().finish()); }