]> Untitled Git - lemmy.git/blob - crates/api_crud/src/comment/delete.rs
Fix API and clippy warnings
[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::ApubObjectType;
12 use lemmy_db_queries::{source::comment::Comment_, Crud};
13 use lemmy_db_schema::source::{comment::*, moderator::*};
14 use lemmy_db_views::comment_view::CommentView;
15 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
16 use lemmy_websocket::{messages::SendComment, 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 = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
29
30     let comment_id = data.comment_id;
31     let orig_comment = blocking(context.pool(), move |conn| {
32       CommentView::read(&conn, comment_id, None)
33     })
34     .await??;
35
36     check_community_ban(
37       local_user_view.person.id,
38       orig_comment.community.id,
39       context.pool(),
40     )
41     .await?;
42
43     // Verify that only the creator can delete
44     if local_user_view.person.id != orig_comment.creator.id {
45       return Err(ApiError::err("no_comment_edit_allowed").into());
46     }
47
48     // Do the delete
49     let deleted = data.deleted;
50     let updated_comment = match blocking(context.pool(), move |conn| {
51       Comment::update_deleted(conn, comment_id, deleted)
52     })
53     .await?
54     {
55       Ok(comment) => comment,
56       Err(_e) => return Err(ApiError::err("couldnt_update_comment").into()),
57     };
58
59     // Send the apub message
60     if deleted {
61       updated_comment
62         .send_delete(&local_user_view.person, context)
63         .await?;
64     } else {
65       updated_comment
66         .send_undo_delete(&local_user_view.person, context)
67         .await?;
68     }
69
70     // Refetch it
71     let comment_id = data.comment_id;
72     let person_id = local_user_view.person.id;
73     let comment_view = blocking(context.pool(), move |conn| {
74       CommentView::read(conn, comment_id, Some(person_id))
75     })
76     .await??;
77
78     // Build the recipients
79     let comment_view_2 = comment_view.clone();
80     let mentions = vec![];
81     let recipient_ids = send_local_notifs(
82       mentions,
83       updated_comment,
84       local_user_view.person.clone(),
85       comment_view_2.post,
86       context.pool(),
87       false,
88     )
89     .await?;
90
91     let res = CommentResponse {
92       comment_view,
93       recipient_ids,
94       form_id: None, // TODO a comment delete might clear forms?
95     };
96
97     context.chat_server().do_send(SendComment {
98       op: UserOperationCrud::DeleteComment,
99       comment: res.clone(),
100       websocket_id,
101     });
102
103     Ok(res)
104   }
105 }
106
107 #[async_trait::async_trait(?Send)]
108 impl PerformCrud for RemoveComment {
109   type Response = CommentResponse;
110
111   async fn perform(
112     &self,
113     context: &Data<LemmyContext>,
114     websocket_id: Option<ConnectionId>,
115   ) -> Result<CommentResponse, LemmyError> {
116     let data: &RemoveComment = &self;
117     let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
118
119     let comment_id = data.comment_id;
120     let orig_comment = blocking(context.pool(), move |conn| {
121       CommentView::read(&conn, comment_id, None)
122     })
123     .await??;
124
125     check_community_ban(
126       local_user_view.person.id,
127       orig_comment.community.id,
128       context.pool(),
129     )
130     .await?;
131
132     // Verify that only a mod or admin can remove
133     is_mod_or_admin(
134       context.pool(),
135       local_user_view.person.id,
136       orig_comment.community.id,
137     )
138     .await?;
139
140     // Do the remove
141     let removed = data.removed;
142     let updated_comment = match blocking(context.pool(), move |conn| {
143       Comment::update_removed(conn, comment_id, removed)
144     })
145     .await?
146     {
147       Ok(comment) => comment,
148       Err(_e) => return Err(ApiError::err("couldnt_update_comment").into()),
149     };
150
151     // Mod tables
152     let form = ModRemoveCommentForm {
153       mod_person_id: local_user_view.person.id,
154       comment_id: data.comment_id,
155       removed: Some(removed),
156       reason: data.reason.to_owned(),
157     };
158     blocking(context.pool(), move |conn| {
159       ModRemoveComment::create(conn, &form)
160     })
161     .await??;
162
163     // Send the apub message
164     if removed {
165       updated_comment
166         .send_remove(&local_user_view.person, context)
167         .await?;
168     } else {
169       updated_comment
170         .send_undo_remove(&local_user_view.person, context)
171         .await?;
172     }
173
174     // Refetch it
175     let comment_id = data.comment_id;
176     let person_id = local_user_view.person.id;
177     let comment_view = blocking(context.pool(), move |conn| {
178       CommentView::read(conn, comment_id, Some(person_id))
179     })
180     .await??;
181
182     // Build the recipients
183     let comment_view_2 = comment_view.clone();
184
185     let mentions = vec![];
186     let recipient_ids = send_local_notifs(
187       mentions,
188       updated_comment,
189       local_user_view.person.clone(),
190       comment_view_2.post,
191       context.pool(),
192       false,
193     )
194     .await?;
195
196     let res = CommentResponse {
197       comment_view,
198       recipient_ids,
199       form_id: None, // TODO maybe this might clear other forms
200     };
201
202     context.chat_server().do_send(SendComment {
203       op: UserOperationCrud::RemoveComment,
204       comment: res.clone(),
205       websocket_id,
206     });
207
208     Ok(res)
209   }
210 }