]> Untitled Git - lemmy.git/blob - crates/api_crud/src/comment/delete.rs
Merge websocket crate into api_common
[lemmy.git] / crates / api_crud / src / comment / delete.rs
1 use crate::PerformCrud;
2 use actix_web::web::Data;
3 use lemmy_api_common::{
4   comment::{CommentResponse, DeleteComment},
5   utils::{check_community_ban, get_local_user_view_from_jwt},
6   websocket::{
7     send::{send_comment_ws_message, send_local_notifs},
8     UserOperationCrud,
9   },
10   LemmyContext,
11 };
12 use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects};
13 use lemmy_db_schema::{
14   source::{
15     comment::{Comment, CommentUpdateForm},
16     community::Community,
17     post::Post,
18   },
19   traits::Crud,
20 };
21 use lemmy_db_views::structs::CommentView;
22 use lemmy_utils::{error::LemmyError, ConnectionId};
23
24 #[async_trait::async_trait(?Send)]
25 impl PerformCrud for DeleteComment {
26   type Response = CommentResponse;
27
28   #[tracing::instrument(skip(context, websocket_id))]
29   async fn perform(
30     &self,
31     context: &Data<LemmyContext>,
32     websocket_id: Option<ConnectionId>,
33   ) -> Result<CommentResponse, LemmyError> {
34     let data: &DeleteComment = self;
35     let local_user_view =
36       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
37
38     let comment_id = data.comment_id;
39     let orig_comment = CommentView::read(context.pool(), comment_id, None).await?;
40
41     // Dont delete it if its already been deleted.
42     if orig_comment.comment.deleted == data.deleted {
43       return Err(LemmyError::from_message("couldnt_update_comment"));
44     }
45
46     check_community_ban(
47       local_user_view.person.id,
48       orig_comment.community.id,
49       context.pool(),
50     )
51     .await?;
52
53     // Verify that only the creator can delete
54     if local_user_view.person.id != orig_comment.creator.id {
55       return Err(LemmyError::from_message("no_comment_edit_allowed"));
56     }
57
58     // Do the delete
59     let deleted = data.deleted;
60     let updated_comment = Comment::update(
61       context.pool(),
62       comment_id,
63       &CommentUpdateForm::builder().deleted(Some(deleted)).build(),
64     )
65     .await
66     .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?;
67
68     let post_id = updated_comment.post_id;
69     let post = Post::read(context.pool(), post_id).await?;
70     let recipient_ids = send_local_notifs(
71       vec![],
72       &updated_comment,
73       &local_user_view.person,
74       &post,
75       false,
76       context,
77     )
78     .await?;
79
80     let res = send_comment_ws_message(
81       data.comment_id,
82       UserOperationCrud::DeleteComment,
83       websocket_id,
84       None, // TODO a comment delete might clear forms?
85       Some(local_user_view.person.id),
86       recipient_ids,
87       context,
88     )
89     .await?;
90
91     // Send the apub message
92     let community = Community::read(context.pool(), orig_comment.post.community_id).await?;
93     let deletable = DeletableObjects::Comment(Box::new(updated_comment.clone().into()));
94     send_apub_delete_in_community(
95       local_user_view.person,
96       community,
97       deletable,
98       None,
99       deleted,
100       context,
101     )
102     .await?;
103
104     Ok(res)
105   }
106 }