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