]> Untitled Git - lemmy.git/blob - crates/api_crud/src/community/delete.rs
Merge pull request #1572 from LemmyNet/feature/federated-mod-community-updates
[lemmy.git] / crates / api_crud / src / community / delete.rs
1 use crate::{community::send_community_websocket, 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::CommunityType;
5 use lemmy_db_queries::{source::community::Community_, Crud};
6 use lemmy_db_schema::source::{
7   community::*,
8   moderator::{ModRemoveCommunity, ModRemoveCommunityForm},
9 };
10 use lemmy_db_views_actor::{
11   community_moderator_view::CommunityModeratorView,
12   community_view::CommunityView,
13 };
14 use lemmy_utils::{utils::naive_from_unix, ApiError, ConnectionId, LemmyError};
15 use lemmy_websocket::{LemmyContext, UserOperationCrud};
16
17 #[async_trait::async_trait(?Send)]
18 impl PerformCrud for DeleteCommunity {
19   type Response = CommunityResponse;
20
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 = get_local_user_view_from_jwt(&data.auth, context.pool()).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("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 = match blocking(context.pool(), move |conn| {
45       Community::update_deleted(conn, community_id, deleted)
46     })
47     .await?
48     {
49       Ok(community) => community,
50       Err(_e) => return Err(ApiError::err("couldnt_update_community").into()),
51     };
52
53     // Send apub messages
54     if deleted {
55       updated_community
56         .send_delete(local_user_view.person.to_owned(), context)
57         .await?;
58     } else {
59       updated_community
60         .send_undo_delete(local_user_view.person.to_owned(), context)
61         .await?;
62     }
63
64     let community_id = data.community_id;
65     let person_id = local_user_view.person.id;
66     let community_view = blocking(context.pool(), move |conn| {
67       CommunityView::read(conn, community_id, Some(person_id))
68     })
69     .await??;
70
71     let res = CommunityResponse { community_view };
72
73     send_community_websocket(
74       &res,
75       context,
76       websocket_id,
77       UserOperationCrud::DeleteCommunity,
78     );
79
80     Ok(res)
81   }
82 }
83
84 #[async_trait::async_trait(?Send)]
85 impl PerformCrud for RemoveCommunity {
86   type Response = CommunityResponse;
87
88   async fn perform(
89     &self,
90     context: &Data<LemmyContext>,
91     websocket_id: Option<ConnectionId>,
92   ) -> Result<CommunityResponse, LemmyError> {
93     let data: &RemoveCommunity = &self;
94     let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
95
96     // Verify its an admin (only an admin can remove a community)
97     is_admin(&local_user_view)?;
98
99     // Do the remove
100     let community_id = data.community_id;
101     let removed = data.removed;
102     let updated_community = match blocking(context.pool(), move |conn| {
103       Community::update_removed(conn, community_id, removed)
104     })
105     .await?
106     {
107       Ok(community) => community,
108       Err(_e) => return Err(ApiError::err("couldnt_update_community").into()),
109     };
110
111     // Mod tables
112     let expires = data.expires.map(naive_from_unix);
113     let form = ModRemoveCommunityForm {
114       mod_person_id: local_user_view.person.id,
115       community_id: data.community_id,
116       removed: Some(removed),
117       reason: data.reason.to_owned(),
118       expires,
119     };
120     blocking(context.pool(), move |conn| {
121       ModRemoveCommunity::create(conn, &form)
122     })
123     .await??;
124
125     // Apub messages
126     if removed {
127       updated_community.send_remove(context).await?;
128     } else {
129       updated_community.send_undo_remove(context).await?;
130     }
131
132     let community_id = data.community_id;
133     let person_id = local_user_view.person.id;
134     let community_view = blocking(context.pool(), move |conn| {
135       CommunityView::read(conn, community_id, Some(person_id))
136     })
137     .await??;
138
139     let res = CommunityResponse { community_view };
140
141     send_community_websocket(
142       &res,
143       context,
144       websocket_id,
145       UserOperationCrud::RemoveCommunity,
146     );
147
148     Ok(res)
149   }
150 }