]> Untitled Git - lemmy.git/blob - crates/api_crud/src/community/delete.rs
Support mastodon deletes
[lemmy.git] / crates / api_crud / src / community / delete.rs
1 use crate::PerformCrud;
2 use actix_web::web::Data;
3 use lemmy_api_common::{blocking, community::*, get_local_user_view_from_jwt, is_admin};
4 use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove, DeletableObjects};
5 use lemmy_db_schema::{
6   source::{
7     community::Community,
8     moderator::{ModRemoveCommunity, ModRemoveCommunityForm},
9   },
10   traits::Crud,
11 };
12 use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
13 use lemmy_utils::{utils::naive_from_unix, ApiError, ConnectionId, LemmyError};
14 use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud};
15
16 #[async_trait::async_trait(?Send)]
17 impl PerformCrud for DeleteCommunity {
18   type Response = CommunityResponse;
19
20   async fn perform(
21     &self,
22     context: &Data<LemmyContext>,
23     websocket_id: Option<ConnectionId>,
24   ) -> Result<CommunityResponse, LemmyError> {
25     let data: &DeleteCommunity = self;
26     let local_user_view =
27       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
28
29     // Fetch the community mods
30     let community_id = data.community_id;
31     let community_mods = blocking(context.pool(), move |conn| {
32       CommunityModeratorView::for_community(conn, community_id)
33     })
34     .await??;
35
36     // Make sure deleter is the top mod
37     if local_user_view.person.id != community_mods[0].moderator.id {
38       return Err(ApiError::err_plain("no_community_edit_allowed").into());
39     }
40
41     // Do the delete
42     let community_id = data.community_id;
43     let deleted = data.deleted;
44     let updated_community = blocking(context.pool(), move |conn| {
45       Community::update_deleted(conn, community_id, deleted)
46     })
47     .await?
48     .map_err(|e| ApiError::err("couldnt_update_community", e))?;
49
50     // Send apub messages
51     send_apub_delete(
52       &local_user_view.person.clone().into(),
53       &updated_community.clone().into(),
54       DeletableObjects::Community(Box::new(updated_community.into())),
55       deleted,
56       context,
57     )
58     .await?;
59
60     send_community_ws_message(
61       data.community_id,
62       UserOperationCrud::DeleteCommunity,
63       websocket_id,
64       Some(local_user_view.person.id),
65       context,
66     )
67     .await
68   }
69 }
70
71 #[async_trait::async_trait(?Send)]
72 impl PerformCrud for RemoveCommunity {
73   type Response = CommunityResponse;
74
75   async fn perform(
76     &self,
77     context: &Data<LemmyContext>,
78     websocket_id: Option<ConnectionId>,
79   ) -> Result<CommunityResponse, LemmyError> {
80     let data: &RemoveCommunity = self;
81     let local_user_view =
82       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
83
84     // Verify its an admin (only an admin can remove a community)
85     is_admin(&local_user_view)?;
86
87     // Do the remove
88     let community_id = data.community_id;
89     let removed = data.removed;
90     let updated_community = blocking(context.pool(), move |conn| {
91       Community::update_removed(conn, community_id, removed)
92     })
93     .await?
94     .map_err(|e| ApiError::err("couldnt_update_community", e))?;
95
96     // Mod tables
97     let expires = data.expires.map(naive_from_unix);
98     let form = ModRemoveCommunityForm {
99       mod_person_id: local_user_view.person.id,
100       community_id: data.community_id,
101       removed: Some(removed),
102       reason: data.reason.to_owned(),
103       expires,
104     };
105     blocking(context.pool(), move |conn| {
106       ModRemoveCommunity::create(conn, &form)
107     })
108     .await??;
109
110     // Apub messages
111     send_apub_remove(
112       &local_user_view.person.clone().into(),
113       &updated_community.clone().into(),
114       DeletableObjects::Community(Box::new(updated_community.into())),
115       data.reason.clone().unwrap_or_else(|| "".to_string()),
116       removed,
117       context,
118     )
119     .await?;
120
121     send_community_ws_message(
122       data.community_id,
123       UserOperationCrud::RemoveCommunity,
124       websocket_id,
125       Some(local_user_view.person.id),
126       context,
127     )
128     .await
129   }
130 }