]> Untitled Git - lemmy.git/commitdiff
Merge different delete activities for better compatibility (fixes #2066) (#2073)
authorNutomic <me@nutomic.com>
Mon, 14 Feb 2022 15:14:24 +0000 (15:14 +0000)
committerGitHub <noreply@github.com>
Mon, 14 Feb 2022 15:14:24 +0000 (10:14 -0500)
38 files changed:
crates/api_crud/src/comment/delete.rs
crates/api_crud/src/community/delete.rs
crates/api_crud/src/post/delete.rs
crates/api_crud/src/private_message/create.rs
crates/api_crud/src/private_message/delete.rs
crates/api_crud/src/private_message/update.rs
crates/apub/assets/lemmy/activities/create_or_update/create_private_message.json [moved from crates/apub/assets/lemmy/activities/private_message/create.json with 100% similarity]
crates/apub/assets/lemmy/activities/deletion/delete_page.json
crates/apub/assets/lemmy/activities/deletion/delete_private_message.json [moved from crates/apub/assets/lemmy/activities/private_message/delete.json with 100% similarity]
crates/apub/assets/lemmy/activities/deletion/remove_note.json
crates/apub/assets/lemmy/activities/deletion/undo_delete_page.json
crates/apub/assets/lemmy/activities/deletion/undo_delete_private_message.json [moved from crates/apub/assets/lemmy/activities/private_message/undo_delete.json with 100% similarity]
crates/apub/assets/lemmy/activities/deletion/undo_remove_note.json
crates/apub/assets/mastodon/activities/delete.json [new file with mode: 0644]
crates/apub/assets/pleroma/activities/delete.json [new file with mode: 0644]
crates/apub/src/activities/create_or_update/comment.rs [moved from crates/apub/src/activities/comment/create_or_update.rs with 97% similarity]
crates/apub/src/activities/create_or_update/mod.rs [moved from crates/apub/src/activities/comment/mod.rs with 92% similarity]
crates/apub/src/activities/create_or_update/post.rs [moved from crates/apub/src/activities/post/create_or_update.rs with 100% similarity]
crates/apub/src/activities/create_or_update/private_message.rs [moved from crates/apub/src/activities/private_message/create_or_update.rs with 97% similarity]
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/mod.rs
crates/apub/src/activities/post/mod.rs [deleted file]
crates/apub/src/activities/private_message/delete.rs [deleted file]
crates/apub/src/activities/private_message/mod.rs [deleted file]
crates/apub/src/activities/private_message/undo_delete.rs [deleted file]
crates/apub/src/activity_lists.rs
crates/apub/src/http/community.rs
crates/apub/src/protocol/activities/create_or_update/mod.rs
crates/apub/src/protocol/activities/create_or_update/private_message.rs [moved from crates/apub/src/protocol/activities/private_message/create_or_update.rs with 100% similarity]
crates/apub/src/protocol/activities/deletion/delete.rs
crates/apub/src/protocol/activities/deletion/mod.rs
crates/apub/src/protocol/activities/deletion/undo_delete.rs
crates/apub/src/protocol/activities/mod.rs
crates/apub/src/protocol/activities/private_message/delete.rs [deleted file]
crates/apub/src/protocol/activities/private_message/mod.rs [deleted file]
crates/apub/src/protocol/activities/private_message/undo_delete.rs [deleted file]

index 84be30fae336aced26f561170bf7edcd5323c1af..adbc3cc5b668496becce853120184a54e699a2f2 100644 (file)
@@ -7,7 +7,7 @@ use lemmy_api_common::{
   get_local_user_view_from_jwt,
   is_mod_or_admin,
 };
-use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove, DeletableObjects};
+use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects};
 use lemmy_db_schema::{
   source::{
     comment::Comment,
@@ -83,30 +83,34 @@ impl PerformCrud for DeleteComment {
     )
     .await?;
 
+    let res = send_comment_ws_message(
+      data.comment_id,
+      UserOperationCrud::DeleteComment,
+      websocket_id,
+      None, // TODO a comment delete might clear forms?
+      Some(local_user_view.person.id),
+      recipient_ids,
+      context,
+    )
+    .await?;
+
     // Send the apub message
     let community = blocking(context.pool(), move |conn| {
       Community::read(conn, orig_comment.post.community_id)
     })
     .await??;
-    send_apub_delete(
-      &local_user_view.person.clone().into(),
-      &community.clone().into(),
-      DeletableObjects::Comment(Box::new(updated_comment.into())),
+    let deletable = DeletableObjects::Comment(Box::new(updated_comment.clone().into()));
+    send_apub_delete_in_community(
+      local_user_view.person,
+      community,
+      deletable,
+      None,
       deleted,
       context,
     )
     .await?;
 
-    send_comment_ws_message(
-      data.comment_id,
-      UserOperationCrud::DeleteComment,
-      websocket_id,
-      None, // TODO a comment delete might clear forms?
-      Some(local_user_view.person.id),
-      recipient_ids,
-      context,
-    )
-    .await
+    Ok(res)
   }
 }
 
@@ -178,30 +182,33 @@ impl PerformCrud for RemoveComment {
     )
     .await?;
 
+    let res = send_comment_ws_message(
+      data.comment_id,
+      UserOperationCrud::RemoveComment,
+      websocket_id,
+      None, // TODO maybe this might clear other forms
+      Some(local_user_view.person.id),
+      recipient_ids,
+      context,
+    )
+    .await?;
+
     // Send the apub message
     let community = blocking(context.pool(), move |conn| {
       Community::read(conn, orig_comment.post.community_id)
     })
     .await??;
-    send_apub_remove(
-      &local_user_view.person.clone().into(),
-      &community.into(),
-      DeletableObjects::Comment(Box::new(updated_comment.into())),
-      data.reason.clone().unwrap_or_else(|| "".to_string()),
+    let deletable = DeletableObjects::Comment(Box::new(updated_comment.clone().into()));
+    send_apub_delete_in_community(
+      local_user_view.person,
+      community,
+      deletable,
+      data.reason.clone().or_else(|| Some("".to_string())),
       removed,
       context,
     )
     .await?;
 
-    send_comment_ws_message(
-      data.comment_id,
-      UserOperationCrud::RemoveComment,
-      websocket_id,
-      None, // TODO maybe this might clear other forms
-      Some(local_user_view.person.id),
-      recipient_ids,
-      context,
-    )
-    .await
+    Ok(res)
   }
 }
index 5769bc536cf8d39dd74329d86999cf4522296b03..17ad70035030756e2b28058f9027ead7bf6d2180 100644 (file)
@@ -1,7 +1,7 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{blocking, community::*, get_local_user_view_from_jwt, is_admin};
-use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove, DeletableObjects};
+use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects};
 use lemmy_db_schema::{
   source::{
     community::Community,
@@ -49,24 +49,28 @@ impl PerformCrud for DeleteCommunity {
     .map_err(LemmyError::from)
     .map_err(|e| e.with_message("couldnt_update_community"))?;
 
-    // Send apub messages
-    send_apub_delete(
-      &local_user_view.person.clone().into(),
-      &updated_community.clone().into(),
-      DeletableObjects::Community(Box::new(updated_community.into())),
-      deleted,
-      context,
-    )
-    .await?;
-
-    send_community_ws_message(
+    let res = send_community_ws_message(
       data.community_id,
       UserOperationCrud::DeleteCommunity,
       websocket_id,
       Some(local_user_view.person.id),
       context,
     )
-    .await
+    .await?;
+
+    // Send apub messages
+    let deletable = DeletableObjects::Community(Box::new(updated_community.clone().into()));
+    send_apub_delete_in_community(
+      local_user_view.person,
+      updated_community,
+      deletable,
+      None,
+      deleted,
+      context,
+    )
+    .await?;
+
+    Ok(res)
   }
 }
 
@@ -111,24 +115,26 @@ impl PerformCrud for RemoveCommunity {
     })
     .await??;
 
-    // Apub messages
-    send_apub_remove(
-      &local_user_view.person.clone().into(),
-      &updated_community.clone().into(),
-      DeletableObjects::Community(Box::new(updated_community.into())),
-      data.reason.clone().unwrap_or_else(|| "".to_string()),
-      removed,
-      context,
-    )
-    .await?;
-
-    send_community_ws_message(
+    let res = send_community_ws_message(
       data.community_id,
       UserOperationCrud::RemoveCommunity,
       websocket_id,
       Some(local_user_view.person.id),
       context,
     )
-    .await
+    .await?;
+
+    // Apub messages
+    let deletable = DeletableObjects::Community(Box::new(updated_community.clone().into()));
+    send_apub_delete_in_community(
+      local_user_view.person,
+      updated_community,
+      deletable,
+      data.reason.clone().or_else(|| Some("".to_string())),
+      removed,
+      context,
+    )
+    .await?;
+    Ok(res)
   }
 }
index 0777153b0974828390caff272722444c2fe750a4..05c395b5b3dcf5cdc6be9bc77363ee8ccf0b2fb0 100644 (file)
@@ -8,7 +8,7 @@ use lemmy_api_common::{
   is_mod_or_admin,
   post::*,
 };
-use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove, DeletableObjects};
+use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects};
 use lemmy_db_schema::{
   source::{
     community::Community,
@@ -63,28 +63,31 @@ impl PerformCrud for DeletePost {
     })
     .await??;
 
+    let res = send_post_ws_message(
+      data.post_id,
+      UserOperationCrud::DeletePost,
+      websocket_id,
+      Some(local_user_view.person.id),
+      context,
+    )
+    .await?;
+
     // apub updates
     let community = blocking(context.pool(), move |conn| {
       Community::read(conn, orig_post.community_id)
     })
     .await??;
-    send_apub_delete(
-      &local_user_view.person.clone().into(),
-      &community.into(),
-      DeletableObjects::Post(Box::new(updated_post.into())),
+    let deletable = DeletableObjects::Post(Box::new(updated_post.into()));
+    send_apub_delete_in_community(
+      local_user_view.person,
+      community,
+      deletable,
+      None,
       deleted,
       context,
     )
     .await?;
-
-    send_post_ws_message(
-      data.post_id,
-      UserOperationCrud::DeletePost,
-      websocket_id,
-      Some(local_user_view.person.id),
-      context,
-    )
-    .await
+    Ok(res)
   }
 }
 
@@ -140,28 +143,30 @@ impl PerformCrud for RemovePost {
     })
     .await??;
 
+    let res = send_post_ws_message(
+      data.post_id,
+      UserOperationCrud::RemovePost,
+      websocket_id,
+      Some(local_user_view.person.id),
+      context,
+    )
+    .await?;
+
     // apub updates
     let community = blocking(context.pool(), move |conn| {
       Community::read(conn, orig_post.community_id)
     })
     .await??;
-    send_apub_remove(
-      &local_user_view.person.clone().into(),
-      &community.into(),
-      DeletableObjects::Post(Box::new(updated_post.into())),
-      data.reason.clone().unwrap_or_else(|| "".to_string()),
+    let deletable = DeletableObjects::Post(Box::new(updated_post.into()));
+    send_apub_delete_in_community(
+      local_user_view.person,
+      community,
+      deletable,
+      data.reason.clone().or_else(|| Some("".to_string())),
       removed,
       context,
     )
     .await?;
-
-    send_post_ws_message(
-      data.post_id,
-      UserOperationCrud::RemovePost,
-      websocket_id,
-      Some(local_user_view.person.id),
-      context,
-    )
-    .await
+    Ok(res)
   }
 }
index 54edc24083b5b4a47a8badcddd5e57667441e76c..3eddf0a5c5a1752444f0ad803cd2dfa80f93d10d 100644 (file)
@@ -10,7 +10,7 @@ use lemmy_api_common::{
 use lemmy_apub::{
   generate_local_apub_endpoint,
   protocol::activities::{
-    private_message::create_or_update::CreateOrUpdatePrivateMessage,
+    create_or_update::private_message::CreateOrUpdatePrivateMessage,
     CreateOrUpdateType,
   },
   EndpointType,
index e28712cf7ecd576032aaaa83ce3a5748cf97d0fc..f11e9657c7ba71e916e628b519ea36207bc94a9c 100644 (file)
@@ -5,14 +5,8 @@ use lemmy_api_common::{
   get_local_user_view_from_jwt,
   person::{DeletePrivateMessage, PrivateMessageResponse},
 };
-use lemmy_apub::protocol::activities::private_message::{
-  delete::DeletePrivateMessage as DeletePrivateMessageApub,
-  undo_delete::UndoDeletePrivateMessage,
-};
-use lemmy_db_schema::{
-  source::private_message::PrivateMessage,
-  traits::{Crud, DeleteableOrRemoveable},
-};
+use lemmy_apub::activities::deletion::send_apub_delete_private_message;
+use lemmy_db_schema::{source::private_message::PrivateMessage, traits::Crud};
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
 
@@ -51,23 +45,13 @@ impl PerformCrud for DeletePrivateMessage {
     .map_err(|e| e.with_message("couldnt_update_private_message"))?;
 
     // Send the apub update
-    if data.deleted {
-      DeletePrivateMessageApub::send(
-        &local_user_view.person.into(),
-        &updated_private_message
-          .blank_out_deleted_or_removed_info()
-          .into(),
-        context,
-      )
-      .await?;
-    } else {
-      UndoDeletePrivateMessage::send(
-        &local_user_view.person.into(),
-        &updated_private_message.into(),
-        context,
-      )
-      .await?;
-    }
+    send_apub_delete_private_message(
+      &local_user_view.person.into(),
+      updated_private_message,
+      data.deleted,
+      context,
+    )
+    .await?;
 
     let op = UserOperationCrud::DeletePrivateMessage;
     send_pm_ws_message(data.private_message_id, op, websocket_id, context).await
index 83e75687369defa55bfcc5930525ee7cef49ef1b..15e84f2c6abe36b432c037677aa883c931a0e7d3 100644 (file)
@@ -6,7 +6,7 @@ use lemmy_api_common::{
   person::{EditPrivateMessage, PrivateMessageResponse},
 };
 use lemmy_apub::protocol::activities::{
-  private_message::create_or_update::CreateOrUpdatePrivateMessage,
+  create_or_update::private_message::CreateOrUpdatePrivateMessage,
   CreateOrUpdateType,
 };
 use lemmy_db_schema::{source::private_message::PrivateMessage, traits::Crud};
index 6b2aba37c0ab13c2f6c487cb82bd3e4c3f43d728..8dd26a109ebe48cf7d32b7119ae0bf70327beaf8 100644 (file)
@@ -3,10 +3,7 @@
   "to": [
     "https://www.w3.org/ns/activitystreams#Public"
   ],
-  "object": {
-    "id": "http://ds9.lemmy.ml/post/1",
-    "type": "Tombstone"
-  },
+  "object": "http://ds9.lemmy.ml/post/1",
   "cc": [
     "http://enterprise.lemmy.ml/c/main"
   ],
index 07ca4e5cf7d4f8c26bee5704c8e20a5a0655098f..8ea354044f84487143ea8859dc2df3399dc95779 100644 (file)
@@ -3,10 +3,7 @@
   "to": [
     "https://www.w3.org/ns/activitystreams#Public"
   ],
-  "object": {
-    "id": "http://ds9.lemmy.ml/comment/1",
-    "type": "Tombstone"
-  },
+  "object": "http://ds9.lemmy.ml/comment/1",
   "cc": [
     "http://enterprise.lemmy.ml/c/main"
   ],
index d2d5533f0fa3f80bf8e1ccc56f24dda85112d1c5..9f824fa1f8f0fb60610ac85385fffcee4ee3197c 100644 (file)
@@ -8,10 +8,7 @@
     "to": [
       "https://www.w3.org/ns/activitystreams#Public"
     ],
-    "object": {
-      "id": "http://ds9.lemmy.ml/post/1",
-      "type": "Tombstone"
-    },
+    "object": "http://ds9.lemmy.ml/post/1",
     "cc": [
       "http://enterprise.lemmy.ml/c/main"
     ],
index e4c9ee26fbd9bec56a8e7abdede58d15c610ca86..413cf16b4e4e605eb94aebaf0ffa8331489a8592 100644 (file)
@@ -8,10 +8,7 @@
     "to": [
       "https://www.w3.org/ns/activitystreams#Public"
     ],
-    "object": {
-      "id": "http://ds9.lemmy.ml/comment/1",
-      "type": "Tombstone"
-    },
+    "object": "http://ds9.lemmy.ml/comment/1",
     "cc": [
       "http://enterprise.lemmy.ml/c/main"
     ],
diff --git a/crates/apub/assets/mastodon/activities/delete.json b/crates/apub/assets/mastodon/activities/delete.json
new file mode 100644 (file)
index 0000000..dec21ca
--- /dev/null
@@ -0,0 +1,26 @@
+{
+  "@context": [
+    "https://www.w3.org/ns/activitystreams",
+    {
+      "ostatus": "http://ostatus.org#",
+      "atomUri": "ostatus:atomUri"
+    }
+  ],
+  "id": "https://mastodon.madrid/users/felix/statuses/107773559874184870#delete",
+  "type": "Delete",
+  "actor": "https://mastodon.madrid/users/felix",
+  "to": [
+    "https://www.w3.org/ns/activitystreams#Public"
+  ],
+  "object": {
+    "id": "https://mastodon.madrid/users/felix/statuses/107773559874184870",
+    "type": "Tombstone",
+    "atomUri": "https://mastodon.madrid/users/felix/statuses/107773559874184870"
+  },
+  "signature": {
+    "type": "RsaSignature2017",
+    "creator": "https://mastodon.madrid/users/felix#main-key",
+    "created": "2022-02-10T11:54:18Z",
+    "signatureValue": "NjGnbkvouSP/cSusR7+sz39iEYxWXCu6nFmBXU3t8ETPkmbpMF5ASeJixXvpTOqbOfkMoWfXncw+jDsbqZ3ELaHGG1gZ5wHWym7mk7YCjQokpF3oPhTWmlEJCVKgewXMrfI4Ok8GGsUMGzuki9EyBDGc/UNBMEAhcxV5Huu7QSQDowcbIwxS3ImxFmtKFceh6mv/kMiXUerCgkYSm6rYZeXZGMTUpvcn9gP6X6Ed6UsrLjCSb3Fj0Naz7LHtzZXRSZDZF/SX2Vw/xKJIgEGzSCv+LKZGvEEkK8PPfMJJhi8cBJebkqOnBGtE6gYK2z2cm/oGorZtXU2L05pXmLAlYQ=="
+  }
+}
\ No newline at end of file
diff --git a/crates/apub/assets/pleroma/activities/delete.json b/crates/apub/assets/pleroma/activities/delete.json
new file mode 100644 (file)
index 0000000..b5aa08e
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "@context": [
+    "https://www.w3.org/ns/activitystreams",
+    "https://greenish.red/schemas/litepub-0.1.jsonld",
+    {
+      "@language": "und"
+    }
+  ],
+  "actor": "https://greenish.red/users/vpzom",
+  "attachment": [],
+  "attributedTo": "https://greenish.red/users/vpzom",
+  "cc": [],
+  "conversation": null,
+  "id": "https://greenish.red/activities/52f0b259-596e-429f-8a1b-c0b455f8932b",
+  "object": "https://greenish.red/objects/38e2b983-ebf5-4387-9bc2-3b80305469c9",
+  "tag": [
+    {
+      "href": "https://voyager.lemmy.ml/c/main",
+      "name": "@main@voyager.lemmy.ml",
+      "type": "Mention"
+    },
+    {
+      "href": "https://voyager.lemmy.ml/u/dess_voy_41u2",
+      "name": "@dess_voy_41u2@voyager.lemmy.ml",
+      "type": "Mention"
+    }
+  ],
+  "to": [
+    "https://greenish.red/users/vpzom/followers",
+    "https://voyager.lemmy.ml/c/main",
+    "https://voyager.lemmy.ml/u/dess_voy_41u2",
+    "https://www.w3.org/ns/activitystreams#Public"
+  ],
+  "type": "Delete"
+}
\ No newline at end of file
similarity index 97%
rename from crates/apub/src/activities/comment/create_or_update.rs
rename to crates/apub/src/activities/create_or_update/comment.rs
index b0894ab1a4d3cf04e6cf35236b48c1e59a795ec8..7d6d89048369fb9627523fec82d3c6fd0c957565 100644 (file)
@@ -1,8 +1,8 @@
 use crate::{
   activities::{
     check_community_deleted_or_removed,
-    comment::get_notif_recipients,
     community::{announce::GetCommunity, send_activity_in_community},
+    create_or_update::get_comment_notif_recipients,
     generate_activity_id,
     verify_activity,
     verify_is_public,
@@ -114,7 +114,7 @@ impl ActivityHandler for CreateOrUpdateComment {
   ) -> Result<(), LemmyError> {
     let comment = ApubComment::from_apub(self.object, context, request_counter).await?;
     let do_send_email = self.kind == CreateOrUpdateType::Create;
-    let recipients = get_notif_recipients(
+    let recipients = get_comment_notif_recipients(
       &self.actor,
       &comment,
       do_send_email,
similarity index 92%
rename from crates/apub/src/activities/comment/mod.rs
rename to crates/apub/src/activities/create_or_update/mod.rs
index e26bdc06ad933f40df9621c84d44a9ed1936d573..3cdac71b29293f70c7c5b763b8aeda4e87fe7c6a 100644 (file)
@@ -9,10 +9,12 @@ use lemmy_db_schema::{
 use lemmy_utils::{utils::scrape_text_for_mentions, LemmyError};
 use lemmy_websocket::{send::send_local_notifs, LemmyContext};
 
-pub mod create_or_update;
+pub mod comment;
+pub mod post;
+pub mod private_message;
 
 #[tracing::instrument(skip_all)]
-async fn get_notif_recipients(
+async fn get_comment_notif_recipients(
   actor: &ObjectId<ApubPerson>,
   comment: &Comment,
   do_send_email: bool,
similarity index 97%
rename from crates/apub/src/activities/private_message/create_or_update.rs
rename to crates/apub/src/activities/create_or_update/private_message.rs
index 3374f224514200cbbd524962023900ccde54b6d7..bae430475a9358ea1baa0659bfa4a41f230719af 100644 (file)
@@ -2,7 +2,7 @@ use crate::{
   activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person},
   objects::{person::ApubPerson, private_message::ApubPrivateMessage},
   protocol::activities::{
-    private_message::create_or_update::CreateOrUpdatePrivateMessage,
+    create_or_update::private_message::CreateOrUpdatePrivateMessage,
     CreateOrUpdateType,
   },
 };
index 774582b1683ed04d4d5c3bb4f7d732ea1a12b42b..e141fcadd04087f9af2824211ba0b6d5377501d1 100644 (file)
@@ -1,22 +1,17 @@
 use crate::{
   activities::{
-    community::{announce::GetCommunity, send_activity_in_community},
+    community::announce::GetCommunity,
     deletion::{receive_delete_action, verify_delete_activity, DeletableObjects},
     generate_activity_id,
     verify_activity,
-    verify_is_public,
   },
-  activity_lists::AnnouncableActivities,
   objects::{community::ApubCommunity, person::ApubPerson},
-  protocol::activities::deletion::delete::Delete,
+  protocol::activities::deletion::delete::{Delete, IdOrNestedObject},
 };
-use activitystreams_kinds::{activity::DeleteType, public};
+use activitystreams_kinds::activity::DeleteType;
+use anyhow::anyhow;
 use lemmy_api_common::blocking;
-use lemmy_apub_lib::{
-  data::Data,
-  object_id::ObjectId,
-  traits::{ActivityHandler, ActorType},
-};
+use lemmy_apub_lib::{data::Data, object_id::ObjectId, traits::ActivityHandler};
 use lemmy_db_schema::{
   source::{
     comment::Comment,
@@ -29,6 +24,7 @@ use lemmy_db_schema::{
       ModRemovePost,
       ModRemovePostForm,
     },
+    person::Person,
     post::Post,
   },
   traits::Crud,
@@ -51,18 +47,8 @@ impl ActivityHandler for Delete {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_is_public(&self.to, &[])?;
     verify_activity(&self.id, self.actor.inner(), &context.settings())?;
-    let community = self.get_community(context, request_counter).await?;
-    verify_delete_activity(
-      &self.object.id,
-      &self.actor,
-      &community,
-      self.summary.is_some(),
-      context,
-      request_counter,
-    )
-    .await?;
+    verify_delete_activity(self, self.summary.is_some(), context, request_counter).await?;
     Ok(())
   }
 
@@ -82,53 +68,50 @@ impl ActivityHandler for Delete {
       };
       receive_remove_action(
         &self.actor,
-        &self.object.id,
+        self.object.id(),
         reason,
         context,
         request_counter,
       )
       .await
     } else {
-      receive_delete_action(&self.object.id, &self.actor, true, context, request_counter).await
+      receive_delete_action(
+        self.object.id(),
+        &self.actor,
+        true,
+        context,
+        request_counter,
+      )
+      .await
     }
   }
 }
 
 impl Delete {
   pub(in crate::activities::deletion) fn new(
-    actor: &ApubPerson,
+    actor: &Person,
     object: DeletableObjects,
+    to: Url,
+    community: Option<&Community>,
     summary: Option<String>,
     context: &LemmyContext,
   ) -> Result<Delete, LemmyError> {
+    let id = generate_activity_id(
+      DeleteType::Delete,
+      &context.settings().get_protocol_and_hostname(),
+    )?;
+    let cc: Option<Url> = community.map(|c| c.actor_id.clone().into());
     Ok(Delete {
-      actor: ObjectId::new(actor.actor_id()),
-      to: vec![public()],
-      object: object.to_tombstone()?,
+      actor: ObjectId::new(actor.actor_id.clone()),
+      to: vec![to],
+      object: IdOrNestedObject::Id(object.id()),
+      cc: cc.into_iter().collect(),
       kind: DeleteType::Delete,
       summary,
-      id: generate_activity_id(
-        DeleteType::Delete,
-        &context.settings().get_protocol_and_hostname(),
-      )?,
+      id,
       unparsed: Default::default(),
     })
   }
-
-  #[tracing::instrument(skip_all)]
-  pub(in crate::activities::deletion) async fn send(
-    actor: &ApubPerson,
-    community: &ApubCommunity,
-    object: DeletableObjects,
-    summary: Option<String>,
-    context: &LemmyContext,
-  ) -> Result<(), LemmyError> {
-    let delete = Delete::new(actor, object, summary, context)?;
-    let delete_id = delete.id.clone();
-
-    let activity = AnnouncableActivities::Delete(delete);
-    send_activity_in_community(activity, &delete_id, actor, community, vec![], context).await
-  }
 }
 
 #[tracing::instrument(skip_all)]
@@ -204,6 +187,7 @@ pub(in crate::activities) async fn receive_remove_action(
 
       send_comment_ws_message_simple(removed_comment.id, RemoveComment, context).await?;
     }
+    DeletableObjects::PrivateMessage(_) => unimplemented!(),
   }
   Ok(())
 }
@@ -216,13 +200,16 @@ impl GetCommunity for Delete {
     context: &LemmyContext,
     _request_counter: &mut i32,
   ) -> Result<ApubCommunity, LemmyError> {
-    let community_id = match DeletableObjects::read_from_db(&self.object.id, context).await? {
+    let community_id = match DeletableObjects::read_from_db(self.object.id(), context).await? {
       DeletableObjects::Community(c) => c.id,
       DeletableObjects::Comment(c) => {
         let post = blocking(context.pool(), move |conn| Post::read(conn, c.post_id)).await??;
         post.community_id
       }
       DeletableObjects::Post(p) => p.community_id,
+      DeletableObjects::PrivateMessage(_) => {
+        return Err(anyhow!("Private message is not part of community").into())
+      }
     };
     let community = blocking(context.pool(), move |conn| {
       Community::read(conn, community_id)
index 419469c95ca27a64c6e5a4fa4cbcefa8e43d045d..cc8319e80b656e6609ce5d078655a8651cb92b4a 100644 (file)
 use crate::{
-  activities::{verify_mod_action, verify_person_in_community},
-  objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost},
-  protocol::{
-    activities::deletion::{delete::Delete, undo_delete::UndoDelete},
-    objects::tombstone::Tombstone,
+  activities::{
+    community::{announce::GetCommunity, send_activity_in_community},
+    send_lemmy_activity,
+    verify_is_public,
+    verify_mod_action,
+    verify_person,
+    verify_person_in_community,
   },
+  activity_lists::AnnouncableActivities,
+  objects::{
+    comment::ApubComment,
+    community::ApubCommunity,
+    person::ApubPerson,
+    post::ApubPost,
+    private_message::ApubPrivateMessage,
+  },
+  protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete},
 };
+use activitystreams_kinds::public;
 use lemmy_api_common::blocking;
-use lemmy_apub_lib::{object_id::ObjectId, traits::ApubObject, verify::verify_domains_match};
-use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post};
+use lemmy_apub_lib::{
+  object_id::ObjectId,
+  traits::{ActorType, ApubObject},
+  verify::verify_domains_match,
+};
+use lemmy_db_schema::{
+  source::{
+    comment::Comment,
+    community::Community,
+    person::Person,
+    post::Post,
+    private_message::PrivateMessage,
+  },
+  traits::Crud,
+};
 use lemmy_utils::LemmyError;
 use lemmy_websocket::{
-  send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message},
+  send::{
+    send_comment_ws_message_simple,
+    send_community_ws_message,
+    send_pm_ws_message,
+    send_post_ws_message,
+  },
   LemmyContext,
   UserOperationCrud,
 };
+use std::ops::Deref;
 use url::Url;
 
 pub mod delete;
 pub mod undo_delete;
 
+/// Parameter `reason` being set indicates that this is a removal by a mod. If its unset, this
+/// action was done by a normal user.
 #[tracing::instrument(skip_all)]
-pub async fn send_apub_delete(
-  actor: &ApubPerson,
-  community: &ApubCommunity,
+pub async fn send_apub_delete_in_community(
+  actor: Person,
+  community: Community,
   object: DeletableObjects,
+  reason: Option<String>,
   deleted: bool,
   context: &LemmyContext,
 ) -> Result<(), LemmyError> {
-  if deleted {
-    Delete::send(actor, community, object, None, context).await
+  let (id, activity) = if deleted {
+    let delete = Delete::new(&actor, object, public(), Some(&community), reason, context)?;
+    (delete.id.clone(), AnnouncableActivities::Delete(delete))
   } else {
-    UndoDelete::send(actor, community, object, None, context).await
-  }
+    let undo = UndoDelete::new(&actor, object, public(), Some(&community), reason, context)?;
+    (undo.id.clone(), AnnouncableActivities::UndoDelete(undo))
+  };
+  send_activity_in_community(
+    activity,
+    &id,
+    &ApubPerson::from(actor),
+    &community.into(),
+    vec![],
+    context,
+  )
+  .await
 }
 
-// TODO: remove reason is actually optional in lemmy. we set an empty string in that case, but its
-//       ugly
 #[tracing::instrument(skip_all)]
-pub async fn send_apub_remove(
+pub async fn send_apub_delete_private_message(
   actor: &ApubPerson,
-  community: &ApubCommunity,
-  object: DeletableObjects,
-  reason: String,
-  removed: bool,
+  pm: PrivateMessage,
+  deleted: bool,
   context: &LemmyContext,
 ) -> Result<(), LemmyError> {
-  if removed {
-    Delete::send(actor, community, object, Some(reason), context).await
+  let recipient_id = pm.recipient_id;
+  let recipient: ApubPerson =
+    blocking(context.pool(), move |conn| Person::read(conn, recipient_id))
+      .await??
+      .into();
+
+  let deletable = DeletableObjects::PrivateMessage(Box::new(pm.into()));
+  let inbox = vec![recipient.shared_inbox_or_inbox_url()];
+  if deleted {
+    let delete = Delete::new(actor, deletable, recipient.actor_id(), None, None, context)?;
+    let id = delete.id.clone();
+    send_lemmy_activity(context, &delete, &id, actor, inbox, true).await?;
   } else {
-    UndoDelete::send(actor, community, object, Some(reason), context).await
-  }
+    let undo = UndoDelete::new(actor, deletable, recipient.actor_id(), None, None, context)?;
+    let id = undo.id.clone();
+    send_lemmy_activity(context, &undo, &id, actor, inbox, true).await?;
+  };
+  Ok(())
 }
 
 pub enum DeletableObjects {
   Community(Box<ApubCommunity>),
   Comment(Box<ApubComment>),
   Post(Box<ApubPost>),
+  PrivateMessage(Box<ApubPrivateMessage>),
 }
 
 impl DeletableObjects {
@@ -74,43 +129,47 @@ impl DeletableObjects {
     if let Some(c) = ApubComment::read_from_apub_id(ap_id.clone(), context).await? {
       return Ok(DeletableObjects::Comment(Box::new(c)));
     }
+    if let Some(p) = ApubPrivateMessage::read_from_apub_id(ap_id.clone(), context).await? {
+      return Ok(DeletableObjects::PrivateMessage(Box::new(p)));
+    }
     Err(diesel::NotFound.into())
   }
 
-  pub(crate) fn to_tombstone(&self) -> Result<Tombstone, LemmyError> {
+  pub(crate) fn id(&self) -> Url {
     match self {
-      DeletableObjects::Community(c) => c.to_tombstone(),
-      DeletableObjects::Comment(c) => c.to_tombstone(),
-      DeletableObjects::Post(p) => p.to_tombstone(),
+      DeletableObjects::Community(c) => c.actor_id(),
+      DeletableObjects::Comment(c) => c.ap_id.clone().into(),
+      DeletableObjects::Post(p) => p.ap_id.clone().into(),
+      DeletableObjects::PrivateMessage(p) => p.ap_id.clone().into(),
     }
   }
 }
 
 #[tracing::instrument(skip_all)]
 pub(in crate::activities) async fn verify_delete_activity(
-  object: &Url,
-  actor: &ObjectId<ApubPerson>,
-  community: &ApubCommunity,
+  activity: &Delete,
   is_mod_action: bool,
   context: &LemmyContext,
   request_counter: &mut i32,
 ) -> Result<(), LemmyError> {
-  let object = DeletableObjects::read_from_db(object, context).await?;
+  let object = DeletableObjects::read_from_db(activity.object.id(), context).await?;
   match object {
     DeletableObjects::Community(community) => {
+      verify_is_public(&activity.to, &[])?;
       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(&activity.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(&activity.actor, &community, context, request_counter).await?;
     }
     DeletableObjects::Post(p) => {
-      verify_delete_activity_post_or_comment(
-        actor,
+      verify_is_public(&activity.to, &[])?;
+      verify_delete_post_or_comment(
+        &activity.actor,
         &p.ap_id.clone().into(),
-        community,
+        &activity.get_community(context, request_counter).await?,
         is_mod_action,
         context,
         request_counter,
@@ -118,22 +177,27 @@ pub(in crate::activities) async fn verify_delete_activity(
       .await?;
     }
     DeletableObjects::Comment(c) => {
-      verify_delete_activity_post_or_comment(
-        actor,
+      verify_is_public(&activity.to, &[])?;
+      verify_delete_post_or_comment(
+        &activity.actor,
         &c.ap_id.clone().into(),
-        community,
+        &activity.get_community(context, request_counter).await?,
         is_mod_action,
         context,
         request_counter,
       )
       .await?;
     }
+    DeletableObjects::PrivateMessage(_) => {
+      verify_person(&activity.actor, context, request_counter).await?;
+      verify_domains_match(activity.actor.inner(), activity.object.id())?;
+    }
   }
   Ok(())
 }
 
 #[tracing::instrument(skip_all)]
-async fn verify_delete_activity_post_or_comment(
+async fn verify_delete_post_or_comment(
   actor: &ObjectId<ApubPerson>,
   object_id: &Url,
   community: &ApubCommunity,
@@ -152,8 +216,6 @@ async fn verify_delete_activity_post_or_comment(
 }
 
 /// Write deletion or restoring of an object to the database, and send websocket message.
-/// TODO: we should do something similar for receive_remove_action(), but its much more complicated
-///       because of the mod log
 #[tracing::instrument(skip_all)]
 async fn receive_delete_action(
   object: &Url,
@@ -165,11 +227,14 @@ async fn receive_delete_action(
   match DeletableObjects::read_from_db(object, context).await? {
     DeletableObjects::Community(community) => {
       if community.local {
-        let mod_ = actor
+        let mod_: Person = actor
           .dereference(context, context.client(), request_counter)
-          .await?;
+          .await?
+          .deref()
+          .clone();
         let object = DeletableObjects::Community(community.clone());
-        send_apub_delete(&mod_, &community.clone(), object, true, context).await?;
+        let c: Community = community.deref().deref().clone();
+        send_apub_delete_in_community(mod_, c, object, None, true, context).await?;
       }
 
       let community = blocking(context.pool(), move |conn| {
@@ -215,6 +280,20 @@ async fn receive_delete_action(
         .await?;
       }
     }
+    DeletableObjects::PrivateMessage(pm) => {
+      let deleted_private_message = blocking(context.pool(), move |conn| {
+        PrivateMessage::update_deleted(conn, pm.id, deleted)
+      })
+      .await??;
+
+      send_pm_ws_message(
+        deleted_private_message.id,
+        UserOperationCrud::DeletePrivateMessage,
+        None,
+        context,
+      )
+      .await?;
+    }
   }
   Ok(())
 }
index 167f8961a13fe3e44666924f1cf213018ec06fbd..7ee90b6e89b59938391793661769b88e2b61788e 100644 (file)
@@ -1,23 +1,17 @@
 use crate::{
   activities::{
-    community::{announce::GetCommunity, send_activity_in_community},
+    community::announce::GetCommunity,
     deletion::{receive_delete_action, verify_delete_activity, DeletableObjects},
     generate_activity_id,
     verify_activity,
-    verify_is_public,
   },
-  activity_lists::AnnouncableActivities,
-  objects::{community::ApubCommunity, person::ApubPerson},
+  objects::community::ApubCommunity,
   protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete},
 };
-use activitystreams_kinds::{activity::UndoType, public};
+use activitystreams_kinds::activity::UndoType;
 use lemmy_api_common::blocking;
-use lemmy_apub_lib::{
-  data::Data,
-  object_id::ObjectId,
-  traits::{ActivityHandler, ActorType},
-};
-use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post};
+use lemmy_apub_lib::{data::Data, object_id::ObjectId, traits::ActivityHandler};
+use lemmy_db_schema::source::{comment::Comment, community::Community, person::Person, post::Post};
 use lemmy_utils::LemmyError;
 use lemmy_websocket::{
   send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message},
@@ -36,14 +30,10 @@ impl ActivityHandler for UndoDelete {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    verify_is_public(&self.to, &self.cc)?;
     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.id,
-      &self.actor,
-      &community,
+      &self.object,
       self.object.summary.is_some(),
       context,
       request_counter,
@@ -59,10 +49,10 @@ impl ActivityHandler for UndoDelete {
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     if self.object.summary.is_some() {
-      UndoDelete::receive_undo_remove_action(&self.object.object.id, context).await
+      UndoDelete::receive_undo_remove_action(self.object.object.id(), context).await
     } else {
       receive_delete_action(
-        &self.object.object.id,
+        self.object.object.id(),
         &self.actor,
         false,
         context,
@@ -75,31 +65,30 @@ impl ActivityHandler for UndoDelete {
 
 impl UndoDelete {
   #[tracing::instrument(skip_all)]
-  pub(in crate::activities::deletion) async fn send(
-    actor: &ApubPerson,
-    community: &ApubCommunity,
+  pub(in crate::activities::deletion) fn new(
+    actor: &Person,
     object: DeletableObjects,
+    to: Url,
+    community: Option<&Community>,
     summary: Option<String>,
     context: &LemmyContext,
-  ) -> Result<(), LemmyError> {
-    let object = Delete::new(actor, object, summary, context)?;
+  ) -> Result<UndoDelete, LemmyError> {
+    let object = Delete::new(actor, object, to.clone(), community, summary, context)?;
 
     let id = generate_activity_id(
       UndoType::Undo,
       &context.settings().get_protocol_and_hostname(),
     )?;
-    let undo = UndoDelete {
-      actor: ObjectId::new(actor.actor_id()),
-      to: vec![public()],
+    let cc: Option<Url> = community.map(|c| c.actor_id.clone().into());
+    Ok(UndoDelete {
+      actor: ObjectId::new(actor.actor_id.clone()),
+      to: vec![to],
       object,
-      cc: vec![community.actor_id()],
+      cc: cc.into_iter().collect(),
       kind: UndoType::Undo,
-      id: id.clone(),
+      id,
       unparsed: Default::default(),
-    };
-
-    let activity = AnnouncableActivities::UndoDelete(undo);
-    send_activity_in_community(activity, &id, actor, community, vec![], context).await
+    })
   }
 
   #[tracing::instrument(skip_all)]
@@ -135,6 +124,7 @@ impl UndoDelete {
         .await??;
         send_comment_ws_message_simple(removed_comment.id, EditComment, context).await?;
       }
+      DeletableObjects::PrivateMessage(_) => unimplemented!(),
     }
     Ok(())
   }
index 343633c8f104169f51b68740fa4436985df7f411..0624b32f3384e1aa1c939707b034952a73d8f46e 100644 (file)
@@ -26,12 +26,10 @@ use url::{ParseError, Url};
 use uuid::Uuid;
 
 pub mod block;
-pub mod comment;
 pub mod community;
+pub mod create_or_update;
 pub mod deletion;
 pub mod following;
-pub mod post;
-pub mod private_message;
 pub mod voting;
 
 /// Checks that the specified Url actually identifies a Person (by fetching it), and that the person
diff --git a/crates/apub/src/activities/post/mod.rs b/crates/apub/src/activities/post/mod.rs
deleted file mode 100644 (file)
index e903f52..0000000
+++ /dev/null
@@ -1 +0,0 @@
-pub mod create_or_update;
diff --git a/crates/apub/src/activities/private_message/delete.rs b/crates/apub/src/activities/private_message/delete.rs
deleted file mode 100644 (file)
index af81db0..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-use crate::{
-  activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person},
-  objects::{person::ApubPerson, private_message::ApubPrivateMessage},
-  protocol::activities::private_message::delete::DeletePrivateMessage,
-};
-use activitystreams_kinds::activity::DeleteType;
-use lemmy_api_common::blocking;
-use lemmy_apub_lib::{
-  data::Data,
-  object_id::ObjectId,
-  traits::{ActivityHandler, ActorType},
-  verify::verify_domains_match,
-};
-use lemmy_db_schema::{
-  source::{person::Person, private_message::PrivateMessage},
-  traits::Crud,
-};
-use lemmy_utils::LemmyError;
-use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
-
-impl DeletePrivateMessage {
-  pub(in crate::activities::private_message) fn new(
-    actor: &ApubPerson,
-    pm: &PrivateMessage,
-    context: &LemmyContext,
-  ) -> Result<DeletePrivateMessage, LemmyError> {
-    Ok(DeletePrivateMessage {
-      actor: ObjectId::new(actor.actor_id()),
-      to: [ObjectId::new(actor.actor_id())],
-      object: ObjectId::new(pm.ap_id.clone()),
-      kind: DeleteType::Delete,
-      id: generate_activity_id(
-        DeleteType::Delete,
-        &context.settings().get_protocol_and_hostname(),
-      )?,
-      unparsed: Default::default(),
-    })
-  }
-
-  #[tracing::instrument(skip_all)]
-  pub async fn send(
-    actor: &ApubPerson,
-    pm: &ApubPrivateMessage,
-    context: &LemmyContext,
-  ) -> Result<(), LemmyError> {
-    let delete = DeletePrivateMessage::new(actor, pm, context)?;
-    let delete_id = delete.id.clone();
-
-    let recipient_id = pm.recipient_id;
-    let recipient: ApubPerson =
-      blocking(context.pool(), move |conn| Person::read(conn, recipient_id))
-        .await??
-        .into();
-    let inbox = vec![recipient.shared_inbox_or_inbox_url()];
-    send_lemmy_activity(context, &delete, &delete_id, actor, inbox, true).await
-  }
-}
-
-#[async_trait::async_trait(?Send)]
-impl ActivityHandler for DeletePrivateMessage {
-  type DataType = LemmyContext;
-
-  #[tracing::instrument(skip_all)]
-  async fn verify(
-    &self,
-    context: &Data<LemmyContext>,
-    request_counter: &mut i32,
-  ) -> Result<(), LemmyError> {
-    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(())
-  }
-
-  #[tracing::instrument(skip_all)]
-  async fn receive(
-    self,
-    context: &Data<LemmyContext>,
-    _request_counter: &mut i32,
-  ) -> Result<(), LemmyError> {
-    let private_message = self.object.dereference_local(context).await?;
-    let deleted_private_message = blocking(context.pool(), move |conn| {
-      PrivateMessage::update_deleted(conn, private_message.id, true)
-    })
-    .await??;
-
-    send_pm_ws_message(
-      deleted_private_message.id,
-      UserOperationCrud::DeletePrivateMessage,
-      None,
-      context,
-    )
-    .await?;
-
-    Ok(())
-  }
-}
diff --git a/crates/apub/src/activities/private_message/mod.rs b/crates/apub/src/activities/private_message/mod.rs
deleted file mode 100644 (file)
index 4bcda7c..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-pub mod create_or_update;
-pub mod delete;
-pub mod undo_delete;
diff --git a/crates/apub/src/activities/private_message/undo_delete.rs b/crates/apub/src/activities/private_message/undo_delete.rs
deleted file mode 100644 (file)
index dbd84bd..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-use crate::{
-  activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person},
-  objects::{person::ApubPerson, private_message::ApubPrivateMessage},
-  protocol::activities::private_message::{
-    delete::DeletePrivateMessage,
-    undo_delete::UndoDeletePrivateMessage,
-  },
-};
-use activitystreams_kinds::activity::UndoType;
-use lemmy_api_common::blocking;
-use lemmy_apub_lib::{
-  data::Data,
-  object_id::ObjectId,
-  traits::{ActivityHandler, ActorType},
-  verify::{verify_domains_match, verify_urls_match},
-};
-use lemmy_db_schema::{
-  source::{person::Person, private_message::PrivateMessage},
-  traits::Crud,
-};
-use lemmy_utils::LemmyError;
-use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
-
-impl UndoDeletePrivateMessage {
-  #[tracing::instrument(skip_all)]
-  pub async fn send(
-    actor: &ApubPerson,
-    pm: &ApubPrivateMessage,
-    context: &LemmyContext,
-  ) -> Result<(), LemmyError> {
-    let recipient_id = pm.recipient_id;
-    let recipient: ApubPerson =
-      blocking(context.pool(), move |conn| Person::read(conn, recipient_id))
-        .await??
-        .into();
-
-    let object = DeletePrivateMessage::new(actor, pm, context)?;
-    let id = generate_activity_id(
-      UndoType::Undo,
-      &context.settings().get_protocol_and_hostname(),
-    )?;
-    let undo = UndoDeletePrivateMessage {
-      actor: ObjectId::new(actor.actor_id()),
-      to: [ObjectId::new(recipient.actor_id())],
-      object,
-      kind: UndoType::Undo,
-      id: id.clone(),
-      unparsed: Default::default(),
-    };
-    let inbox = vec![recipient.shared_inbox_or_inbox_url()];
-    send_lemmy_activity(context, &undo, &id, actor, inbox, true).await
-  }
-}
-
-#[async_trait::async_trait(?Send)]
-impl ActivityHandler for UndoDeletePrivateMessage {
-  type DataType = LemmyContext;
-
-  #[tracing::instrument(skip_all)]
-  async fn verify(
-    &self,
-    context: &Data<LemmyContext>,
-    request_counter: &mut i32,
-  ) -> Result<(), LemmyError> {
-    verify_activity(&self.id, self.actor.inner(), &context.settings())?;
-    verify_person(&self.actor, context, request_counter).await?;
-    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(())
-  }
-
-  #[tracing::instrument(skip_all)]
-  async fn receive(
-    self,
-    context: &Data<LemmyContext>,
-    _request_counter: &mut i32,
-  ) -> Result<(), LemmyError> {
-    let ap_id = self.object.object.clone();
-    let private_message = ap_id.dereference_local(context).await?;
-
-    let deleted_private_message = blocking(context.pool(), move |conn| {
-      PrivateMessage::update_deleted(conn, private_message.id, false)
-    })
-    .await??;
-
-    send_pm_ws_message(
-      deleted_private_message.id,
-      UserOperationCrud::EditPrivateMessage,
-      None,
-      context,
-    )
-    .await?;
-
-    Ok(())
-  }
-}
index c8666b93a68add90f8f096422e4bc30196e2f41a..a24ac8e4851e1ae5cc9f32fc9f7c15b7eea256a7 100644 (file)
@@ -11,18 +11,17 @@ use crate::{
         report::Report,
         update::UpdateCommunity,
       },
-      create_or_update::{comment::CreateOrUpdateComment, post::CreateOrUpdatePost},
+      create_or_update::{
+        comment::CreateOrUpdateComment,
+        post::CreateOrUpdatePost,
+        private_message::CreateOrUpdatePrivateMessage,
+      },
       deletion::{delete::Delete, undo_delete::UndoDelete},
       following::{
         accept::AcceptFollowCommunity,
         follow::FollowCommunity,
         undo_follow::UndoFollowCommunity,
       },
-      private_message::{
-        create_or_update::CreateOrUpdatePrivateMessage,
-        delete::DeletePrivateMessage,
-        undo_delete::UndoDeletePrivateMessage,
-      },
       voting::{undo_vote::UndoVote, vote::Vote},
     },
     objects::page::Page,
@@ -61,8 +60,8 @@ pub enum PersonInboxActivities {
   /// Some activities can also be sent from user to user, eg a comment with mentions
   AnnouncableActivities(AnnouncableActivities),
   CreateOrUpdatePrivateMessage(CreateOrUpdatePrivateMessage),
-  DeletePrivateMessage(DeletePrivateMessage),
-  UndoDeletePrivateMessage(UndoDeletePrivateMessage),
+  Delete(Delete),
+  UndoDelete(UndoDelete),
   AnnounceActivity(AnnounceActivity),
 }
 
index 5483d58d14171de8c17b5ce9dd75b7367de262ee..c049c6aef16dea14a7af31bc5723cc9407965082 100644 (file)
@@ -84,10 +84,14 @@ pub(in crate::http) async fn receive_group_inbox(
   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?;
-    verify_person_in_community(&actor_id, &community, context, &mut 0).await?;
-    if community.local {
-      AnnounceActivity::send(*announcable, &community, context).await?;
+    // Ignore failures in get_community(). those happen because Delete/PrivateMessage is not in a
+    // community, but looks identical to Delete/Post or Delete/Comment which are in a community.
+    let community = announcable.get_community(context, &mut 0).await;
+    if let Ok(community) = community {
+      if community.local {
+        verify_person_in_community(&actor_id, &community, context, &mut 0).await?;
+        AnnounceActivity::send(*announcable, &community, context).await?;
+      }
     }
   }
 
index 2ce70333a569612199435e4aa556edb42ed9dbe6..ff03c5a099e4fd4d7759d959d6b26f05e3ded226 100644 (file)
@@ -1,5 +1,6 @@
 pub mod comment;
 pub mod post;
+pub mod private_message;
 
 #[cfg(test)]
 mod tests {
@@ -7,7 +8,11 @@ mod tests {
     context::WithContext,
     objects::tests::file_to_json_object,
     protocol::{
-      activities::create_or_update::{comment::CreateOrUpdateComment, post::CreateOrUpdatePost},
+      activities::create_or_update::{
+        comment::CreateOrUpdateComment,
+        post::CreateOrUpdatePost,
+        private_message::CreateOrUpdatePrivateMessage,
+      },
       tests::test_parse_lemmy_item,
     },
   };
@@ -26,6 +31,10 @@ mod tests {
       "assets/lemmy/activities/create_or_update/create_note.json",
     )
     .unwrap();
+    test_parse_lemmy_item::<CreateOrUpdatePrivateMessage>(
+      "assets/lemmy/activities/create_or_update/create_private_message.json",
+    )
+    .unwrap();
 
     file_to_json_object::<WithContext<CreateOrUpdateComment>>(
       "assets/pleroma/activities/create_note.json",
index a999e58ec6f0a1ac55fdb1a82cc78c51a4395c9b..70b38af6c96fc69d962114ad75e8930f8a6f8779 100644 (file)
@@ -1,7 +1,4 @@
-use crate::{
-  objects::person::ApubPerson,
-  protocol::{objects::tombstone::Tombstone, Unparsed},
-};
+use crate::{objects::person::ApubPerson, protocol::Unparsed};
 use activitystreams_kinds::activity::DeleteType;
 use lemmy_apub_lib::object_id::ObjectId;
 use serde::{Deserialize, Serialize};
@@ -15,7 +12,11 @@ pub struct Delete {
   pub(crate) actor: ObjectId<ApubPerson>,
   #[serde(deserialize_with = "crate::deserialize_one_or_many")]
   pub(crate) to: Vec<Url>,
-  pub(crate) object: Tombstone,
+  pub(crate) object: IdOrNestedObject,
+  #[serde(deserialize_with = "crate::deserialize_one_or_many")]
+  #[serde(default)]
+  #[serde(skip_serializing_if = "Vec::is_empty")]
+  pub(crate) cc: Vec<Url>,
   #[serde(rename = "type")]
   pub(crate) kind: DeleteType,
   /// If summary is present, this is a mod action (Remove in Lemmy terms). Otherwise, its a user
@@ -25,3 +26,26 @@ pub struct Delete {
   #[serde(flatten)]
   pub(crate) unparsed: Unparsed,
 }
+
+/// Instead of a simple ID string as object, Mastodon sends a nested tombstone for some reason,
+/// so we need to handle that as well.
+#[derive(Clone, Debug, Deserialize, Serialize)]
+#[serde(untagged)]
+pub(crate) enum IdOrNestedObject {
+  Id(Url),
+  NestedObject(NestedObject),
+}
+
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub(crate) struct NestedObject {
+  id: Url,
+}
+
+impl IdOrNestedObject {
+  pub(crate) fn id(&self) -> &Url {
+    match self {
+      IdOrNestedObject::Id(i) => i,
+      IdOrNestedObject::NestedObject(n) => &n.id,
+    }
+  }
+}
index 802548348d4129c4faa57e27f062bb2916404836..9ecb65c4ce1103773b3aecec7fcb4a3e0b3588f3 100644 (file)
@@ -3,13 +3,17 @@ pub mod undo_delete;
 
 #[cfg(test)]
 mod tests {
-  use crate::protocol::{
-    activities::deletion::{delete::Delete, undo_delete::UndoDelete},
-    tests::test_parse_lemmy_item,
+  use crate::{
+    context::WithContext,
+    objects::tests::file_to_json_object,
+    protocol::{
+      activities::deletion::{delete::Delete, undo_delete::UndoDelete},
+      tests::test_parse_lemmy_item,
+    },
   };
 
   #[actix_rt::test]
-  async fn test_parse_lemmy_deletion() {
+  async fn test_parse_deletion() {
     test_parse_lemmy_item::<Delete>("assets/lemmy/activities/deletion/remove_note.json").unwrap();
     test_parse_lemmy_item::<Delete>("assets/lemmy/activities/deletion/delete_page.json").unwrap();
 
@@ -17,5 +21,14 @@ mod tests {
       .unwrap();
     test_parse_lemmy_item::<UndoDelete>("assets/lemmy/activities/deletion/undo_delete_page.json")
       .unwrap();
+    test_parse_lemmy_item::<Delete>("assets/lemmy/activities/deletion/delete_private_message.json")
+      .unwrap();
+    test_parse_lemmy_item::<UndoDelete>(
+      "assets/lemmy/activities/deletion/undo_delete_private_message.json",
+    )
+    .unwrap();
+
+    file_to_json_object::<WithContext<Delete>>("assets/pleroma/activities/delete.json").unwrap();
+    file_to_json_object::<WithContext<Delete>>("assets/mastodon/activities/delete.json").unwrap();
   }
 }
index ebd51f9640328dd15e5fdf5480d9b92ab6f70fdc..f2f2d764494d84c76204e92171b6222b4611b1f4 100644 (file)
@@ -15,6 +15,8 @@ pub struct UndoDelete {
   pub(crate) to: Vec<Url>,
   pub(crate) object: Delete,
   #[serde(deserialize_with = "crate::deserialize_one_or_many")]
+  #[serde(default)]
+  #[serde(skip_serializing_if = "Vec::is_empty")]
   pub(crate) cc: Vec<Url>,
   #[serde(rename = "type")]
   pub(crate) kind: UndoType,
index 47b01b241d99611d713e5118c276c207b8f2d4d8..9279cab12cbf2b0369ff831616b30a4dab120e71 100644 (file)
@@ -6,7 +6,6 @@ pub mod community;
 pub mod create_or_update;
 pub mod deletion;
 pub mod following;
-pub mod private_message;
 pub mod voting;
 
 #[derive(Clone, Debug, Display, Deserialize, Serialize, PartialEq)]
diff --git a/crates/apub/src/protocol/activities/private_message/delete.rs b/crates/apub/src/protocol/activities/private_message/delete.rs
deleted file mode 100644 (file)
index 7d28e1c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-use crate::{
-  objects::{person::ApubPerson, private_message::ApubPrivateMessage},
-  protocol::Unparsed,
-};
-use activitystreams_kinds::activity::DeleteType;
-use lemmy_apub_lib::object_id::ObjectId;
-use serde::{Deserialize, Serialize};
-use url::Url;
-
-#[derive(Clone, Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct DeletePrivateMessage {
-  pub(crate) actor: ObjectId<ApubPerson>,
-  #[serde(deserialize_with = "crate::deserialize_one")]
-  pub(crate) to: [ObjectId<ApubPerson>; 1],
-  pub(crate) object: ObjectId<ApubPrivateMessage>,
-  #[serde(rename = "type")]
-  pub(crate) kind: DeleteType,
-  pub(crate) id: Url,
-  #[serde(flatten)]
-  pub(crate) unparsed: Unparsed,
-}
diff --git a/crates/apub/src/protocol/activities/private_message/mod.rs b/crates/apub/src/protocol/activities/private_message/mod.rs
deleted file mode 100644 (file)
index 04be31b..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-pub mod create_or_update;
-pub mod delete;
-pub mod undo_delete;
-
-#[cfg(test)]
-mod tests {
-  use crate::protocol::{
-    activities::private_message::{
-      create_or_update::CreateOrUpdatePrivateMessage,
-      delete::DeletePrivateMessage,
-      undo_delete::UndoDeletePrivateMessage,
-    },
-    tests::test_parse_lemmy_item,
-  };
-
-  #[actix_rt::test]
-  async fn test_parse_lemmy_private_message() {
-    test_parse_lemmy_item::<CreateOrUpdatePrivateMessage>(
-      "assets/lemmy/activities/private_message/create.json",
-    )
-    .unwrap();
-    test_parse_lemmy_item::<DeletePrivateMessage>(
-      "assets/lemmy/activities/private_message/delete.json",
-    )
-    .unwrap();
-    test_parse_lemmy_item::<UndoDeletePrivateMessage>(
-      "assets/lemmy/activities/private_message/undo_delete.json",
-    )
-    .unwrap();
-  }
-}
diff --git a/crates/apub/src/protocol/activities/private_message/undo_delete.rs b/crates/apub/src/protocol/activities/private_message/undo_delete.rs
deleted file mode 100644 (file)
index 605938c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-use crate::{
-  objects::person::ApubPerson,
-  protocol::{activities::private_message::delete::DeletePrivateMessage, Unparsed},
-};
-use activitystreams_kinds::activity::UndoType;
-use lemmy_apub_lib::object_id::ObjectId;
-use serde::{Deserialize, Serialize};
-use url::Url;
-
-#[derive(Clone, Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct UndoDeletePrivateMessage {
-  pub(crate) actor: ObjectId<ApubPerson>,
-  #[serde(deserialize_with = "crate::deserialize_one")]
-  pub(crate) to: [ObjectId<ApubPerson>; 1],
-  pub(crate) object: DeletePrivateMessage,
-  #[serde(rename = "type")]
-  pub(crate) kind: UndoType,
-  pub(crate) id: Url,
-  #[serde(flatten)]
-  pub(crate) unparsed: Unparsed,
-}