]> Untitled Git - lemmy.git/blob - crates/api_crud/src/comment/delete.rs
Moving settings and secrets to context.
[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   blocking,
5   check_community_ban,
6   comment::*,
7   get_local_user_view_from_jwt,
8   is_mod_or_admin,
9   send_local_notifs,
10 };
11 use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove};
12 use lemmy_db_queries::{source::comment::Comment_, Crud};
13 use lemmy_db_schema::source::{comment::*, community::Community, moderator::*, post::Post};
14 use lemmy_db_views::comment_view::CommentView;
15 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
16 use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperationCrud};
17
18 #[async_trait::async_trait(?Send)]
19 impl PerformCrud for DeleteComment {
20   type Response = CommentResponse;
21
22   async fn perform(
23     &self,
24     context: &Data<LemmyContext>,
25     websocket_id: Option<ConnectionId>,
26   ) -> Result<CommentResponse, LemmyError> {
27     let data: &DeleteComment = self;
28     let local_user_view =
29       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
30
31     let comment_id = data.comment_id;
32     let orig_comment = blocking(context.pool(), move |conn| {
33       CommentView::read(conn, comment_id, None)
34     })
35     .await??;
36
37     check_community_ban(
38       local_user_view.person.id,
39       orig_comment.community.id,
40       context.pool(),
41     )
42     .await?;
43
44     // Verify that only the creator can delete
45     if local_user_view.person.id != orig_comment.creator.id {
46       return Err(ApiError::err("no_comment_edit_allowed").into());
47     }
48
49     // Do the delete
50     let deleted = data.deleted;
51     let updated_comment = blocking(context.pool(), move |conn| {
52       Comment::update_deleted(conn, comment_id, deleted)
53     })
54     .await?
55     .map_err(|_| ApiError::err("couldnt_update_comment"))?;
56
57     // Send the apub message
58     let community = blocking(context.pool(), move |conn| {
59       Community::read(conn, orig_comment.post.community_id)
60     })
61     .await??;
62     send_apub_delete(
63       &local_user_view.person,
64       &community,
65       updated_comment.ap_id.clone().into(),
66       deleted,
67       context,
68     )
69     .await?;
70
71     let post_id = updated_comment.post_id;
72     let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
73     let recipient_ids = send_local_notifs(
74       vec![],
75       updated_comment,
76       local_user_view.person.clone(),
77       post,
78       context.pool(),
79       false,
80       &context.settings(),
81     )
82     .await?;
83
84     send_comment_ws_message(
85       data.comment_id,
86       UserOperationCrud::DeleteComment,
87       websocket_id,
88       None, // TODO a comment delete might clear forms?
89       Some(local_user_view.person.id),
90       recipient_ids,
91       context,
92     )
93     .await
94   }
95 }
96
97 #[async_trait::async_trait(?Send)]
98 impl PerformCrud for RemoveComment {
99   type Response = CommentResponse;
100
101   async fn perform(
102     &self,
103     context: &Data<LemmyContext>,
104     websocket_id: Option<ConnectionId>,
105   ) -> Result<CommentResponse, LemmyError> {
106     let data: &RemoveComment = self;
107     let local_user_view =
108       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
109
110     let comment_id = data.comment_id;
111     let orig_comment = blocking(context.pool(), move |conn| {
112       CommentView::read(conn, comment_id, None)
113     })
114     .await??;
115
116     check_community_ban(
117       local_user_view.person.id,
118       orig_comment.community.id,
119       context.pool(),
120     )
121     .await?;
122
123     // Verify that only a mod or admin can remove
124     is_mod_or_admin(
125       context.pool(),
126       local_user_view.person.id,
127       orig_comment.community.id,
128     )
129     .await?;
130
131     // Do the remove
132     let removed = data.removed;
133     let updated_comment = blocking(context.pool(), move |conn| {
134       Comment::update_removed(conn, comment_id, removed)
135     })
136     .await?
137     .map_err(|_| ApiError::err("couldnt_update_comment"))?;
138
139     // Mod tables
140     let form = ModRemoveCommentForm {
141       mod_person_id: local_user_view.person.id,
142       comment_id: data.comment_id,
143       removed: Some(removed),
144       reason: data.reason.to_owned(),
145     };
146     blocking(context.pool(), move |conn| {
147       ModRemoveComment::create(conn, &form)
148     })
149     .await??;
150
151     // Send the apub message
152     let community = blocking(context.pool(), move |conn| {
153       Community::read(conn, orig_comment.post.community_id)
154     })
155     .await??;
156     send_apub_remove(
157       &local_user_view.person,
158       &community,
159       updated_comment.ap_id.clone().into(),
160       data.reason.clone().unwrap_or_else(|| "".to_string()),
161       removed,
162       context,
163     )
164     .await?;
165
166     let post_id = updated_comment.post_id;
167     let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
168     let recipient_ids = send_local_notifs(
169       vec![],
170       updated_comment,
171       local_user_view.person.clone(),
172       post,
173       context.pool(),
174       false,
175       &context.settings(),
176     )
177     .await?;
178
179     send_comment_ws_message(
180       data.comment_id,
181       UserOperationCrud::RemoveComment,
182       websocket_id,
183       None, // TODO maybe this might clear other forms
184       Some(local_user_view.person.id),
185       recipient_ids,
186       context,
187     )
188     .await
189   }
190 }