]> Untitled Git - lemmy.git/blob - crates/api_crud/src/post/delete.rs
Dont swallow API errors (fixes #1834) (#1837)
[lemmy.git] / crates / api_crud / src / post / delete.rs
1 use crate::PerformCrud;
2 use actix_web::web::Data;
3 use lemmy_api_common::{
4   blocking,
5   check_community_ban,
6   get_local_user_view_from_jwt,
7   is_mod_or_admin,
8   post::*,
9 };
10 use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove};
11 use lemmy_db_queries::{source::post::Post_, Crud};
12 use lemmy_db_schema::source::{community::Community, moderator::*, post::*};
13 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
14 use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud};
15
16 #[async_trait::async_trait(?Send)]
17 impl PerformCrud for DeletePost {
18   type Response = PostResponse;
19
20   async fn perform(
21     &self,
22     context: &Data<LemmyContext>,
23     websocket_id: Option<ConnectionId>,
24   ) -> Result<PostResponse, LemmyError> {
25     let data: &DeletePost = self;
26     let local_user_view =
27       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
28
29     let post_id = data.post_id;
30     let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
31
32     check_community_ban(
33       local_user_view.person.id,
34       orig_post.community_id,
35       context.pool(),
36     )
37     .await?;
38
39     // Verify that only the creator can delete
40     if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) {
41       return Err(ApiError::err_plain("no_post_edit_allowed").into());
42     }
43
44     // Update the post
45     let post_id = data.post_id;
46     let deleted = data.deleted;
47     let updated_post = blocking(context.pool(), move |conn| {
48       Post::update_deleted(conn, post_id, deleted)
49     })
50     .await??;
51
52     // apub updates
53     let community = blocking(context.pool(), move |conn| {
54       Community::read(conn, orig_post.community_id)
55     })
56     .await??;
57     send_apub_delete(
58       &local_user_view.person,
59       &community,
60       updated_post.ap_id.into(),
61       deleted,
62       context,
63     )
64     .await?;
65
66     send_post_ws_message(
67       data.post_id,
68       UserOperationCrud::DeletePost,
69       websocket_id,
70       Some(local_user_view.person.id),
71       context,
72     )
73     .await
74   }
75 }
76
77 #[async_trait::async_trait(?Send)]
78 impl PerformCrud for RemovePost {
79   type Response = PostResponse;
80
81   async fn perform(
82     &self,
83     context: &Data<LemmyContext>,
84     websocket_id: Option<ConnectionId>,
85   ) -> Result<PostResponse, LemmyError> {
86     let data: &RemovePost = self;
87     let local_user_view =
88       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
89
90     let post_id = data.post_id;
91     let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
92
93     check_community_ban(
94       local_user_view.person.id,
95       orig_post.community_id,
96       context.pool(),
97     )
98     .await?;
99
100     // Verify that only the mods can remove
101     is_mod_or_admin(
102       context.pool(),
103       local_user_view.person.id,
104       orig_post.community_id,
105     )
106     .await?;
107
108     // Update the post
109     let post_id = data.post_id;
110     let removed = data.removed;
111     let updated_post = blocking(context.pool(), move |conn| {
112       Post::update_removed(conn, post_id, removed)
113     })
114     .await??;
115
116     // Mod tables
117     let form = ModRemovePostForm {
118       mod_person_id: local_user_view.person.id,
119       post_id: data.post_id,
120       removed: Some(removed),
121       reason: data.reason.to_owned(),
122     };
123     blocking(context.pool(), move |conn| {
124       ModRemovePost::create(conn, &form)
125     })
126     .await??;
127
128     // apub updates
129     let community = blocking(context.pool(), move |conn| {
130       Community::read(conn, orig_post.community_id)
131     })
132     .await??;
133     send_apub_remove(
134       &local_user_view.person,
135       &community,
136       updated_post.ap_id.into(),
137       data.reason.clone().unwrap_or_else(|| "".to_string()),
138       removed,
139       context,
140     )
141     .await?;
142
143     send_post_ws_message(
144       data.post_id,
145       UserOperationCrud::RemovePost,
146       websocket_id,
147       Some(local_user_view.person.id),
148       context,
149     )
150     .await
151   }
152 }