]> Untitled Git - lemmy.git/blob - crates/api_crud/src/post/delete.rs
cf48757d3f6105c8747728760ec5f584c184a130
[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::ApubObjectType;
11 use lemmy_db_queries::{source::post::Post_, Crud, DeleteableOrRemoveable};
12 use lemmy_db_schema::source::{moderator::*, post::*};
13 use lemmy_db_views::post_view::PostView;
14 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
15 use lemmy_websocket::{messages::SendPost, 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 = get_local_user_view_from_jwt(&data.auth, context.pool()).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("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     if deleted {
54       updated_post
55         .blank_out_deleted_or_removed_info()
56         .send_delete(&local_user_view.person, context)
57         .await?;
58     } else {
59       updated_post
60         .send_undo_delete(&local_user_view.person, context)
61         .await?;
62     }
63
64     // Refetch the post
65     let post_id = data.post_id;
66     let mut post_view = blocking(context.pool(), move |conn| {
67       PostView::read(conn, post_id, Some(local_user_view.person.id))
68     })
69     .await??;
70
71     if deleted {
72       post_view.post = post_view.post.blank_out_deleted_or_removed_info();
73     }
74
75     let res = PostResponse { post_view };
76
77     context.chat_server().do_send(SendPost {
78       op: UserOperationCrud::DeletePost,
79       post: res.clone(),
80       websocket_id,
81     });
82
83     Ok(res)
84   }
85 }
86
87 #[async_trait::async_trait(?Send)]
88 impl PerformCrud for RemovePost {
89   type Response = PostResponse;
90
91   async fn perform(
92     &self,
93     context: &Data<LemmyContext>,
94     websocket_id: Option<ConnectionId>,
95   ) -> Result<PostResponse, LemmyError> {
96     let data: &RemovePost = self;
97     let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
98
99     let post_id = data.post_id;
100     let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
101
102     check_community_ban(
103       local_user_view.person.id,
104       orig_post.community_id,
105       context.pool(),
106     )
107     .await?;
108
109     // Verify that only the mods can remove
110     is_mod_or_admin(
111       context.pool(),
112       local_user_view.person.id,
113       orig_post.community_id,
114     )
115     .await?;
116
117     // Update the post
118     let post_id = data.post_id;
119     let removed = data.removed;
120     let updated_post = blocking(context.pool(), move |conn| {
121       Post::update_removed(conn, post_id, removed)
122     })
123     .await??;
124
125     // Mod tables
126     let form = ModRemovePostForm {
127       mod_person_id: local_user_view.person.id,
128       post_id: data.post_id,
129       removed: Some(removed),
130       reason: data.reason.to_owned(),
131     };
132     blocking(context.pool(), move |conn| {
133       ModRemovePost::create(conn, &form)
134     })
135     .await??;
136
137     // apub updates
138     if removed {
139       updated_post
140         .blank_out_deleted_or_removed_info()
141         .send_remove(&local_user_view.person, context)
142         .await?;
143     } else {
144       updated_post
145         .send_undo_remove(&local_user_view.person, context)
146         .await?;
147     }
148
149     // Refetch the post
150     let post_id = data.post_id;
151     let person_id = local_user_view.person.id;
152     let mut post_view = blocking(context.pool(), move |conn| {
153       PostView::read(conn, post_id, Some(person_id))
154     })
155     .await??;
156
157     // Blank out deleted or removed info
158     if removed {
159       post_view.post = post_view.post.blank_out_deleted_or_removed_info();
160     }
161
162     let res = PostResponse { post_view };
163
164     context.chat_server().do_send(SendPost {
165       op: UserOperationCrud::RemovePost,
166       post: res.clone(),
167       websocket_id,
168     });
169
170     Ok(res)
171   }
172 }