2 use actix_web::web::Data;
4 use lemmy_api_common::{
5 community::{GetCommunityResponse, TransferCommunity},
7 utils::{is_admin, is_top_mod, local_user_view_from_jwt},
11 community::{CommunityModerator, CommunityModeratorForm},
12 moderator::{ModTransferCommunity, ModTransferCommunityForm},
14 traits::{Crud, Joinable},
16 use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
18 error::{LemmyError, LemmyErrorExt, LemmyErrorType},
22 // TODO: we dont do anything for federation here, it should be updated the next time the community
23 // gets fetched. i hope we can get rid of the community creator role soon.
24 #[async_trait::async_trait(?Send)]
25 impl Perform for TransferCommunity {
26 type Response = GetCommunityResponse;
28 #[tracing::instrument(skip(context))]
31 context: &Data<LemmyContext>,
32 ) -> Result<GetCommunityResponse, LemmyError> {
33 let data: &TransferCommunity = self;
34 let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
36 // Fetch the community mods
37 let community_id = data.community_id;
38 let mut community_mods =
39 CommunityModeratorView::for_community(&mut context.pool(), community_id).await?;
41 // Make sure transferrer is either the top community mod, or an admin
42 if !(is_top_mod(&local_user_view, &community_mods).is_ok()
43 || is_admin(&local_user_view).is_ok())
45 return Err(LemmyErrorType::NotAnAdmin)?;
48 // You have to re-do the community_moderator table, reordering it.
49 // Add the transferee to the top
50 let creator_index = community_mods
52 .position(|r| r.moderator.id == data.person_id)
53 .context(location_info!())?;
54 let creator_person = community_mods.remove(creator_index);
55 community_mods.insert(0, creator_person);
57 // Delete all the mods
58 let community_id = data.community_id;
60 CommunityModerator::delete_for_community(&mut context.pool(), community_id).await?;
62 // TODO: this should probably be a bulk operation
63 // Re-add the mods, in the new order
64 for cmod in &community_mods {
65 let community_moderator_form = CommunityModeratorForm {
66 community_id: cmod.community.id,
67 person_id: cmod.moderator.id,
70 CommunityModerator::join(&mut context.pool(), &community_moderator_form)
72 .with_lemmy_type(LemmyErrorType::CommunityModeratorAlreadyExists)?;
76 let form = ModTransferCommunityForm {
77 mod_person_id: local_user_view.person.id,
78 other_person_id: data.person_id,
79 community_id: data.community_id,
82 ModTransferCommunity::create(&mut context.pool(), &form).await?;
84 let community_id = data.community_id;
85 let person_id = local_user_view.person.id;
87 CommunityView::read(&mut context.pool(), community_id, Some(person_id), false)
89 .with_lemmy_type(LemmyErrorType::CouldntFindCommunity)?;
91 let community_id = data.community_id;
92 let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id)
94 .with_lemmy_type(LemmyErrorType::CouldntFindCommunity)?;
97 Ok(GetCommunityResponse {
101 discussion_languages: vec![],