From a83113935d824d86d3e5000db50c10c44d84f8d0 Mon Sep 17 00:00:00 2001
From: Dessalines <dessalines@users.noreply.github.com>
Date: Wed, 3 Nov 2021 13:47:24 -0400
Subject: [PATCH] Check if post or comment are deleted first. Fixes #1864
 (#1867)

* Check if post or comment are deleted first. Fixes #1864

* Refactoring delete apub.

* Revert "Refactoring delete apub."

This reverts commit ba2c3d06cfb870efe792f4b2541036265b425156.
---
 crates/api_crud/src/comment/delete.rs         |  5 ++
 crates/api_crud/src/post/delete.rs            |  5 ++
 crates/apub/src/activities/deletion/delete.rs | 21 +-------
 crates/apub/src/activities/deletion/mod.rs    | 52 ++++++++++++-------
 .../src/activities/deletion/undo_delete.rs    | 12 +----
 crates/apub/src/objects/comment.rs            | 10 ++--
 crates/apub/src/objects/post.rs               | 10 ++--
 7 files changed, 59 insertions(+), 56 deletions(-)

diff --git a/crates/api_crud/src/comment/delete.rs b/crates/api_crud/src/comment/delete.rs
index 19851f0c..f55119f7 100644
--- a/crates/api_crud/src/comment/delete.rs
+++ b/crates/api_crud/src/comment/delete.rs
@@ -44,6 +44,11 @@ impl PerformCrud for DeleteComment {
     })
     .await??;
 
+    // Dont delete it if its already been deleted.
+    if orig_comment.comment.deleted == data.deleted {
+      return Err(ApiError::err_plain("couldnt_update_comment").into());
+    }
+
     check_community_ban(
       local_user_view.person.id,
       orig_comment.community.id,
diff --git a/crates/api_crud/src/post/delete.rs b/crates/api_crud/src/post/delete.rs
index a701e835..af699934 100644
--- a/crates/api_crud/src/post/delete.rs
+++ b/crates/api_crud/src/post/delete.rs
@@ -36,6 +36,11 @@ impl PerformCrud for DeletePost {
     let post_id = data.post_id;
     let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
 
+    // Dont delete it if its already been deleted.
+    if orig_post.deleted == data.deleted {
+      return Err(ApiError::err_plain("couldnt_update_post").into());
+    }
+
     check_community_ban(
       local_user_view.person.id,
       orig_post.community_id,
diff --git a/crates/apub/src/activities/deletion/delete.rs b/crates/apub/src/activities/deletion/delete.rs
index 672fca52..a4112a0a 100644
--- a/crates/apub/src/activities/deletion/delete.rs
+++ b/crates/apub/src/activities/deletion/delete.rs
@@ -33,12 +33,7 @@ use lemmy_websocket::{
 use crate::{
   activities::{
     community::{announce::GetCommunity, send_to_community},
-    deletion::{
-      receive_delete_action,
-      verify_delete_activity,
-      DeletableObjects,
-      WebsocketMessages,
-    },
+    deletion::{receive_delete_action, verify_delete_activity, DeletableObjects},
     generate_activity_id,
     verify_activity,
     verify_is_public,
@@ -87,19 +82,7 @@ impl ActivityHandler for Delete {
       };
       receive_remove_action(&self.actor, &self.object, reason, context, request_counter).await
     } else {
-      receive_delete_action(
-        &self.object,
-        &self.actor,
-        WebsocketMessages {
-          community: UserOperationCrud::DeleteCommunity,
-          post: UserOperationCrud::DeletePost,
-          comment: UserOperationCrud::DeleteComment,
-        },
-        true,
-        context,
-        request_counter,
-      )
-      .await
+      receive_delete_action(&self.object, &self.actor, true, context, request_counter).await
     }
   }
 }
diff --git a/crates/apub/src/activities/deletion/mod.rs b/crates/apub/src/activities/deletion/mod.rs
index b9c11291..3e9a7a3a 100644
--- a/crates/apub/src/activities/deletion/mod.rs
+++ b/crates/apub/src/activities/deletion/mod.rs
@@ -143,19 +143,12 @@ async fn verify_delete_activity_post_or_comment(
   Ok(())
 }
 
-struct WebsocketMessages {
-  community: UserOperationCrud,
-  post: UserOperationCrud,
-  comment: UserOperationCrud,
-}
-
 /// 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
 async fn receive_delete_action(
   object: &Url,
   actor: &ObjectId<ApubPerson>,
-  ws_messages: WebsocketMessages,
   deleted: bool,
   context: &LemmyContext,
   request_counter: &mut i32,
@@ -172,21 +165,44 @@ async fn receive_delete_action(
         Community::update_deleted(conn, community.id, deleted)
       })
       .await??;
-      send_community_ws_message(community.id, ws_messages.community, None, None, context).await?;
+      send_community_ws_message(
+        community.id,
+        UserOperationCrud::DeleteCommunity,
+        None,
+        None,
+        context,
+      )
+      .await?;
     }
     DeletableObjects::Post(post) => {
-      let deleted_post = blocking(context.pool(), move |conn| {
-        Post::update_deleted(conn, post.id, deleted)
-      })
-      .await??;
-      send_post_ws_message(deleted_post.id, ws_messages.post, None, None, context).await?;
+      if deleted != post.deleted {
+        let deleted_post = blocking(context.pool(), move |conn| {
+          Post::update_deleted(conn, post.id, deleted)
+        })
+        .await??;
+        send_post_ws_message(
+          deleted_post.id,
+          UserOperationCrud::DeletePost,
+          None,
+          None,
+          context,
+        )
+        .await?;
+      }
     }
     DeletableObjects::Comment(comment) => {
-      let deleted_comment = blocking(context.pool(), move |conn| {
-        Comment::update_deleted(conn, comment.id, deleted)
-      })
-      .await??;
-      send_comment_ws_message_simple(deleted_comment.id, ws_messages.comment, context).await?;
+      if deleted != comment.deleted {
+        let deleted_comment = blocking(context.pool(), move |conn| {
+          Comment::update_deleted(conn, comment.id, deleted)
+        })
+        .await??;
+        send_comment_ws_message_simple(
+          deleted_comment.id,
+          UserOperationCrud::DeleteComment,
+          context,
+        )
+        .await?;
+      }
     }
   }
   Ok(())
diff --git a/crates/apub/src/activities/deletion/undo_delete.rs b/crates/apub/src/activities/deletion/undo_delete.rs
index c1689119..2de4aefd 100644
--- a/crates/apub/src/activities/deletion/undo_delete.rs
+++ b/crates/apub/src/activities/deletion/undo_delete.rs
@@ -18,12 +18,7 @@ use lemmy_websocket::{
 use crate::{
   activities::{
     community::{announce::GetCommunity, send_to_community},
-    deletion::{
-      receive_delete_action,
-      verify_delete_activity,
-      DeletableObjects,
-      WebsocketMessages,
-    },
+    deletion::{receive_delete_action, verify_delete_activity, DeletableObjects},
     generate_activity_id,
     verify_activity,
     verify_is_public,
@@ -69,11 +64,6 @@ impl ActivityHandler for UndoDelete {
       receive_delete_action(
         &self.object.object,
         &self.actor,
-        WebsocketMessages {
-          community: UserOperationCrud::EditCommunity,
-          post: UserOperationCrud::EditPost,
-          comment: UserOperationCrud::EditComment,
-        },
         false,
         context,
         request_counter,
diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs
index e5ffb7ca..08a55bf9 100644
--- a/crates/apub/src/objects/comment.rs
+++ b/crates/apub/src/objects/comment.rs
@@ -81,10 +81,12 @@ impl ApubObject for ApubComment {
   }
 
   async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> {
-    blocking(context.pool(), move |conn| {
-      Comment::update_deleted(conn, self.id, true)
-    })
-    .await??;
+    if !self.deleted {
+      blocking(context.pool(), move |conn| {
+        Comment::update_deleted(conn, self.id, true)
+      })
+      .await??;
+    }
     Ok(())
   }
 
diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs
index c19c6277..b835f812 100644
--- a/crates/apub/src/objects/post.rs
+++ b/crates/apub/src/objects/post.rs
@@ -76,10 +76,12 @@ impl ApubObject for ApubPost {
   }
 
   async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> {
-    blocking(context.pool(), move |conn| {
-      Post::update_deleted(conn, self.id, true)
-    })
-    .await??;
+    if !self.deleted {
+      blocking(context.pool(), move |conn| {
+        Post::update_deleted(conn, self.id, true)
+      })
+      .await??;
+    }
     Ok(())
   }
 
-- 
2.44.1