Remove ActivityFields trait, deserialize into another struct instead
authorFelix Ableitner <me@nutomic.com>
Wed, 3 Nov 2021 17:33:51 +0000 (18:33 +0100)
committerFelix Ableitner <me@nutomic.com>
Fri, 5 Nov 2021 20:14:19 +0000 (21:14 +0100)
49 files changed:
crates/apub/src/activities/comment/create_or_update.rs
crates/apub/src/activities/community/add_mod.rs
crates/apub/src/activities/community/announce.rs
crates/apub/src/activities/community/block_user.rs
crates/apub/src/activities/community/remove_mod.rs
crates/apub/src/activities/community/report.rs
crates/apub/src/activities/community/undo_block_user.rs
crates/apub/src/activities/community/update.rs
crates/apub/src/activities/deletion/delete.rs
crates/apub/src/activities/deletion/mod.rs
crates/apub/src/activities/deletion/undo_delete.rs
crates/apub/src/activities/following/accept.rs
crates/apub/src/activities/following/follow.rs
crates/apub/src/activities/following/undo_follow.rs
crates/apub/src/activities/mod.rs
crates/apub/src/activities/post/create_or_update.rs
crates/apub/src/activities/private_message/create_or_update.rs
crates/apub/src/activities/private_message/delete.rs
crates/apub/src/activities/private_message/undo_delete.rs
crates/apub/src/activities/voting/undo_vote.rs
crates/apub/src/activities/voting/vote.rs
crates/apub/src/activity_lists.rs
crates/apub/src/fetcher/mod.rs
crates/apub/src/fetcher/post_or_comment.rs
crates/apub/src/fetcher/user_or_community.rs [new file with mode: 0644]
crates/apub/src/http/community.rs
crates/apub/src/http/mod.rs
crates/apub/src/http/person.rs
crates/apub/src/protocol/activities/community/add_mod.rs
crates/apub/src/protocol/activities/community/announce.rs
crates/apub/src/protocol/activities/community/block_user.rs
crates/apub/src/protocol/activities/community/remove_mod.rs
crates/apub/src/protocol/activities/community/report.rs
crates/apub/src/protocol/activities/community/undo_block_user.rs
crates/apub/src/protocol/activities/community/update.rs
crates/apub/src/protocol/activities/create_or_update/comment.rs
crates/apub/src/protocol/activities/create_or_update/post.rs
crates/apub/src/protocol/activities/deletion/delete.rs
crates/apub/src/protocol/activities/deletion/undo_delete.rs
crates/apub/src/protocol/activities/following/accept.rs
crates/apub/src/protocol/activities/following/follow.rs
crates/apub/src/protocol/activities/following/undo_follow.rs
crates/apub/src/protocol/activities/private_message/create_or_update.rs
crates/apub/src/protocol/activities/private_message/delete.rs
crates/apub/src/protocol/activities/private_message/undo_delete.rs
crates/apub/src/protocol/activities/voting/undo_vote.rs
crates/apub/src/protocol/activities/voting/vote.rs
crates/apub_lib/src/traits.rs
crates/apub_lib_derive/src/lib.rs

index 10666932e942bd4cad7cd8b8eff4f1a4c19a8e97..84f6d3f280b5e7b172c7233eb05f1ee154fa141b 100644 (file)
@@ -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)?;
index b18e50adaf7d2bc07909d7b592b6a34b7969d907..11dc5a0b9e382d10cad6651f567bdd7897b685b0 100644 (file)
@@ -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?;
index f560b09f6e78b73b9af5fc00739218f1a78eae71..b245a1b88ab73aef673ab129ac0c5b7d8203c579 100644 (file)
@@ -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<LemmyContext>,
     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,
index dfe6c4c9256ed588039286413a3a22788287d89d..d756ed2512e7cf1728b7aeb772002e004826a364 100644 (file)
@@ -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?;
index 02ff3c0641ad77abd81882d665c6024b2264a32c..1c79e70d2d83ab136d3b6db9e2ad0f216f8358a1 100644 (file)
@@ -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?;
index 1e7cc5fad96a570895f400ea9b08e781da0346e4..5b02490b0071d246d3b8c5046a0d2040054ee428 100644 (file)
@@ -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<PostOrComment>,
@@ -72,7 +70,7 @@ impl ActivityHandler for Report {
     context: &Data<LemmyContext>,
     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(())
index 2bda94441f2e0eb3f6037ee3c6aebfaf449c0aa5..467237eb8b70125bbe203107188b74b6d6f44e19 100644 (file)
@@ -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?;
index 28de0db006b2797ba2419233a396a581192358de..9acb89098b0ff6cc7d90a4e288736d5cb4bfecf6 100644 (file)
@@ -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?;
index a4112a0af5550f173a9fdb2985b256f0e4a535f9..605daf8ffaaf7385101699e8d139205c077420b9 100644 (file)
@@ -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,
index 3e9a7a3a2c21b0aa0f9a93c1e2772842600b5146..1be3bccf65478bfaf3d74a5373b8756978c3fcee 100644 (file)
@@ -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<ApubPerson>,
   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<ApubPerson>,
   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(())
 }
index 2de4aefd3e8268a0baf6cd6ba260325e7b2bea30..93338a3f3f42584dc4a043facd10cdf38f47bc14 100644 (file)
@@ -1,7 +1,18 @@
+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, undo_delete::UndoDelete},
+};
 use activitystreams::{activity::kind::UndoType, public};
 use anyhow::anyhow;
-use url::Url;
-
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
   data::Data,
@@ -14,20 +25,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, undo_delete::UndoDelete},
-};
+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,
index 984d622a877b28b3118b9e3222285956216fd2bf..68c8ca45407eae85dd43b88fe99eb2e6dcd1905a 100644 (file)
@@ -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<LemmyContext>,
     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(())
   }
index e048907fe06f462785cffb97ad26925d19cc6b71..30c77fe8161f3906673a5796bc59e9ef5837ee88 100644 (file)
@@ -71,7 +71,7 @@ impl ActivityHandler for FollowCommunity {
     context: &Data<LemmyContext>,
     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?;
index c3fd78b51b81dd229a28cfd405cbf15c08721ab0..bdc5a4b09f5368b3a9589c1e2fa4b45437d031aa 100644 (file)
@@ -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<LemmyContext>,
     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(())
index bc6cfb512b9f3cef88fe7fd0de77cad6bdb74360..e23926f8cdb18953a504d4369cf1da69c047bcfa 100644 (file)
@@ -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(())
 }
 
index 677ce2dc14ee25c1cb4a5518320af17ec884e13f..e574dda9699f77fe62a610ef5d4b4a9213590432 100644 (file)
@@ -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())?;
         }
       }
     }
index e441718ab47ff871ef8030b37d042a566a1890ec..52b6fa74c3dfb83ee12567e52b1541258309f418 100644 (file)
@@ -54,7 +54,7 @@ impl ActivityHandler for CreateOrUpdatePrivateMessage {
     context: &Data<LemmyContext>,
     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?;
index da3b6472d100187c40aac117e3f55194082d0ea5..4547b22b8125079173dd23f7a62fbfb2b3cafad5 100644 (file)
@@ -62,7 +62,7 @@ impl ActivityHandler for DeletePrivateMessage {
     context: &Data<LemmyContext>,
     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(())
index bba9e0f22d04a122570dba8c51e3576737ea7a17..1272328b1fce828bd742b7c607f97ee059decd23 100644 (file)
@@ -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<LemmyContext>,
     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(())
   }
index e95d251799633580889aaad26461a5fa2a9a6029..786d51192a97b78995b6838240e32b6bcc64cf16 100644 (file)
@@ -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(())
   }
index 01df4b93eea7cfa22cc1be8d7ab7de96abd0b057..82b9b84e95e34d033fa24ce0427957c19e25963c 100644 (file)
@@ -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(())
index 1197af85fc51873ee9e14cdf73a2a0bd6d5bc3df..6c866b83b632423b8c3ed9a6a3d0d3213a7b7bae 100644 (file)
@@ -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<AnnounceActivity>),
 }
 
-#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)]
+#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler)]
 #[serde(untagged)]
 #[activity_handler(LemmyContext)]
 pub enum AnnouncableActivities {
index db39d2282b2c47520ea333b41de1a131cc76156b..8246f4ce6f48192e2ccd2b5574ff5c53c53ad876 100644 (file)
@@ -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<Box<dyn ActorType>, LemmyError> {
-  let community_id = ObjectId::<ApubCommunity>::new(apub_id.clone());
-  let community = community_id.dereference(context, recursion_counter).await;
-  let actor: Box<dyn ActorType> = 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`.
index c0bc46a8148ab2bc02f8273a287f3b61b482114e..ef4e59e1d5b61cd00c23c4769f3b37c0697d1b2e 100644 (file)
@@ -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<PostForm>),
-  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<Option<Self>, LemmyError>
-  where
-    Self: Sized,
-  {
+  ) -> Result<Option<Self>, 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<Self, LemmyError>
-  where
-    Self: Sized,
-  {
+  ) -> Result<Self, LemmyError> {
     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 (file)
index 0000000..16a1d82
--- /dev/null
@@ -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<NaiveDateTime> {
+    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<Option<Self>, 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<Self::ApubType, LemmyError> {
+    unimplemented!()
+  }
+
+  fn to_tombstone(&self) -> Result<Self::TombstoneType, LemmyError> {
+    unimplemented!()
+  }
+
+  async fn from_apub(
+    apub: &Self::ApubType,
+    data: &Self::DataType,
+    expected_domain: &Url,
+    request_counter: &mut i32,
+  ) -> Result<Self, LemmyError> {
+    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<String> {
+    match self {
+      UserOrCommunity::User(p) => p.public_key(),
+      UserOrCommunity::Community(p) => p.public_key(),
+    }
+  }
+
+  fn private_key(&self) -> Option<String> {
+    todo!()
+  }
+
+  fn inbox_url(&self) -> Url {
+    todo!()
+  }
+
+  fn shared_inbox_url(&self) -> Option<Url> {
+    todo!()
+  }
+}
index 4110d2b20999de5645383ce71604048e3fb1cd05..c208f71edd191e60e54d85140c90951bfe4493f5 100644 (file)
@@ -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<HttpResponse, LemmyError> {
   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::<WithContext<GroupInboxActivities>>(&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<HttpResponse, LemmyError> {
-  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?;
index 9c61c2747411591bcd459384662ae7606f43c71b..450b937d58bd1fb88a9d29b27e2bf785f6bb23a2 100644 (file)
@@ -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<HttpResponse, LemmyError> {
   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::<WithContext<SharedInboxActivities>>(&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<String, LemmyError> {
   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<HttpResponse, LemmyError>
 where
   T: ActivityHandler<DataType = LemmyContext>
-    + 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::<UserOrCommunity>::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<T: Debug + ActivityFields>(
-  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(),
     );
index a5ea4ad17124f47f07eadd4da919fdbe0c8d1afb..193689c5ea0b9710765f1471d432061f53bcef7b 100644 (file)
@@ -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<HttpResponse, LemmyError> {
   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::<WithContext<PersonInboxActivities>>(&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<HttpResponse, LemmyError> {
-  receive_activity(request, activity, context).await
+  receive_activity(request, activity, activity_data, context).await
 }
 
 pub(crate) async fn get_apub_person_outbox(
index 74ec46457c143d1a84540d4ca406f2025d47e522..6938f01d456f8d21ec38474c1399b96c97f24084 100644 (file)
@@ -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<ApubPerson>,
index 2f4e9bd26f9636de37ef90a142d93e09c650b548..07fbda635f533b33277913b16d1956b5ae62b4e0 100644 (file)
@@ -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<ApubCommunity>,
index 4ede06ae1e0b5e4a568889935186d860514de888..ec95e6e9b0696dc068112a90a848e8e5cc8725f0 100644 (file)
@@ -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<ApubPerson>,
index db30ddbe4a1d7d4dd30e2331a61a5162ebf5c6de..cca263549676f24c303fb23c5d123e127501a2ee 100644 (file)
@@ -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<ApubPerson>,
index 5efdd792e10c0d7e6685ea94221dd92d5b4ac70d..d10a9d285a41c413e210a1cbea8568d0fa1728bf 100644 (file)
@@ -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<ApubPerson>,
index 0e89f87efbf8a4d83c22c05b0252f0317ae2f99d..24356fab28856151602dbc85e022c63a99d94303 100644 (file)
@@ -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<ApubPerson>,
index 4ba1ed8432b1a6bd32b215fc79a82326d31b67da..686938aa487f8df649a4245429130fc3b7cee00b 100644 (file)
@@ -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<ApubPerson>,
index ede7417bc29c98dca37653001304ecd086b6634b..4e5b412d7db530f7f428ff77e5fb33f4977a30fc 100644 (file)
@@ -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<ApubPerson>,
index 03b283e3ca8d139faa58e3a4d0fce96ff6b1f1c3..b1851c0d9d2af6be7bec457edf765d2a5ab183c0 100644 (file)
@@ -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<ApubPerson>,
index f8e81b47a74bd9a21111b998ee21166863a0e632..af50227994df63e2aa905dcd8d8b7d58c7b129e6 100644 (file)
@@ -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<ApubPerson>,
index d962820b36de1ece4a40b1e8eea39079bf5a9ba1..8a30546e56ec064926a526380baf32c0b9569d2d 100644 (file)
@@ -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<ApubPerson>,
index 502a908c215ce48f4bf0654a9b9c5385a6183185..7eeb3a41843258d4450122bd89bd9fb93373b7e3 100644 (file)
@@ -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<ApubCommunity>,
index 9dfec216305ae8f5202d026007ef7a6035d77128..651ab1d2d223cf5db7a9681c3089078b9b334622 100644 (file)
@@ -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<ApubPerson>,
index be6a7ab8963503b163eb736c036da4382e45b60b..3abeabd296b708a6709d3f9d3372298e28186bee 100644 (file)
@@ -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<ApubPerson>,
index 7632ef9fe34a45c37a971778fc31679a69bc1a51..5092a1640f3124dd57de59823c0af20dc2ba80db 100644 (file)
@@ -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,
index 499d7d1d6cb3546ae0dac1fbb9799c2786b8ad24..87da3c310ab5b05441762244748230df4c6096b8 100644 (file)
@@ -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<ApubPerson>,
index 699f6eec916177a8f7ae9b765c212c6553f0e4c2..16d82492c2b3703e6da1bff56c94273d607c58cc 100644 (file)
@@ -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<ApubPerson>,
index 0d3e66360c85292f033335f0a2e305d03e44dff9..05606dbe99062b083b3e34fca8180c563529ee27 100644 (file)
@@ -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<ApubPerson>,
index fdc87a3bd7e497f5316643b87bb9d10f4a170eb2..6d82ccc42c6ae4d841b343f7065781face728f59 100644 (file)
@@ -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<ApubPerson>,
index 8d819a27bce280f808f0b2996b609cc34575cf79..2d54240824943be027565b4488675066efbbead9 100644 (file)
@@ -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;
index 1f8d12a7d3b7c944a4cacc89b4001eceee8931b2..72e00fe2b869443b33cea4fa338121a7e74f2053 100644 (file)
@@ -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, &quote! {a.id_unchecked()}));
-      let impl_actor = variants
-        .iter()
-        .map(|v| generate_match_arm(&name, v, &quote! {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()
-}