]> Untitled Git - lemmy.git/blob - crates/api_crud/src/community/delete.rs
17ad70035030756e2b28058f9027ead7bf6d2180
[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_in_community, 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, 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   #[tracing::instrument(skip(context, websocket_id))]
21   async fn perform(
22     &self,
23     context: &Data<LemmyContext>,
24     websocket_id: Option<ConnectionId>,
25   ) -> Result<CommunityResponse, LemmyError> {
26     let data: &DeleteCommunity = self;
27     let local_user_view =
28       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
29
30     // Fetch the community mods
31     let community_id = data.community_id;
32     let community_mods = blocking(context.pool(), move |conn| {
33       CommunityModeratorView::for_community(conn, community_id)
34     })
35     .await??;
36
37     // Make sure deleter is the top mod
38     if local_user_view.person.id != community_mods[0].moderator.id {
39       return Err(LemmyError::from_message("no_community_edit_allowed"));
40     }
41
42     // Do the delete
43     let community_id = data.community_id;
44     let deleted = data.deleted;
45     let updated_community = blocking(context.pool(), move |conn| {
46       Community::update_deleted(conn, community_id, deleted)
47     })
48     .await?
49     .map_err(LemmyError::from)
50     .map_err(|e| e.with_message("couldnt_update_community"))?;
51
52     let res = send_community_ws_message(
53       data.community_id,
54       UserOperationCrud::DeleteCommunity,
55       websocket_id,
56       Some(local_user_view.person.id),
57       context,
58     )
59     .await?;
60
61     // Send apub messages
62     let deletable = DeletableObjects::Community(Box::new(updated_community.clone().into()));
63     send_apub_delete_in_community(
64       local_user_view.person,
65       updated_community,
66       deletable,
67       None,
68       deleted,
69       context,
70     )
71     .await?;
72
73     Ok(res)
74   }
75 }
76
77 #[async_trait::async_trait(?Send)]
78 impl PerformCrud for RemoveCommunity {
79   type Response = CommunityResponse;
80
81   #[tracing::instrument(skip(context, websocket_id))]
82   async fn perform(
83     &self,
84     context: &Data<LemmyContext>,
85     websocket_id: Option<ConnectionId>,
86   ) -> Result<CommunityResponse, LemmyError> {
87     let data: &RemoveCommunity = self;
88     let local_user_view =
89       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
90
91     // Verify its an admin (only an admin can remove a community)
92     is_admin(&local_user_view)?;
93
94     // Do the remove
95     let community_id = data.community_id;
96     let removed = data.removed;
97     let updated_community = blocking(context.pool(), move |conn| {
98       Community::update_removed(conn, community_id, removed)
99     })
100     .await?
101     .map_err(LemmyError::from)
102     .map_err(|e| e.with_message("couldnt_update_community"))?;
103
104     // Mod tables
105     let expires = data.expires.map(naive_from_unix);
106     let form = ModRemoveCommunityForm {
107       mod_person_id: local_user_view.person.id,
108       community_id: data.community_id,
109       removed: Some(removed),
110       reason: data.reason.to_owned(),
111       expires,
112     };
113     blocking(context.pool(), move |conn| {
114       ModRemoveCommunity::create(conn, &form)
115     })
116     .await??;
117
118     let res = send_community_ws_message(
119       data.community_id,
120       UserOperationCrud::RemoveCommunity,
121       websocket_id,
122       Some(local_user_view.person.id),
123       context,
124     )
125     .await?;
126
127     // Apub messages
128     let deletable = DeletableObjects::Community(Box::new(updated_community.clone().into()));
129     send_apub_delete_in_community(
130       local_user_view.person,
131       updated_community,
132       deletable,
133       data.reason.clone().or_else(|| Some("".to_string())),
134       removed,
135       context,
136     )
137     .await?;
138     Ok(res)
139   }
140 }