4 announce::GetCommunity,
5 get_community_from_moderators_url,
6 send_activity_in_community,
9 verify_add_remove_moderator_target,
12 verify_person_in_community,
14 activity_lists::AnnouncableActivities,
16 fetch_local_site_data,
17 generate_moderators_url,
19 objects::{community::ApubCommunity, person::ApubPerson},
20 protocol::activities::community::remove_mod::RemoveMod,
23 use activitypub_federation::{
24 core::object_id::ObjectId,
26 traits::{ActivityHandler, Actor},
28 use activitystreams_kinds::{activity::RemoveType, public};
29 use lemmy_api_common::utils::blocking;
30 use lemmy_db_schema::{
32 community::{CommunityModerator, CommunityModeratorForm},
33 moderator::{ModAddCommunity, ModAddCommunityForm},
35 traits::{Crud, Joinable},
37 use lemmy_utils::error::LemmyError;
38 use lemmy_websocket::LemmyContext;
42 #[tracing::instrument(skip_all)]
44 community: &ApubCommunity,
45 removed_mod: &ApubPerson,
47 context: &LemmyContext,
48 ) -> Result<(), LemmyError> {
49 let id = generate_activity_id(
51 &context.settings().get_protocol_and_hostname(),
53 let remove = RemoveMod {
54 actor: ObjectId::new(actor.actor_id()),
56 object: ObjectId::new(removed_mod.actor_id()),
57 target: generate_moderators_url(&community.actor_id)?.into(),
59 cc: vec![community.actor_id()],
60 kind: RemoveType::Remove,
61 unparsed: Default::default(),
64 let activity = AnnouncableActivities::RemoveMod(remove);
65 let inboxes = vec![removed_mod.shared_inbox_or_inbox()];
66 send_activity_in_community(activity, actor, community, inboxes, context).await
70 #[async_trait::async_trait(?Send)]
71 impl ActivityHandler for RemoveMod {
72 type DataType = LemmyContext;
73 type Error = LemmyError;
75 fn id(&self) -> &Url {
79 fn actor(&self) -> &Url {
83 #[tracing::instrument(skip_all)]
86 context: &Data<LemmyContext>,
87 request_counter: &mut i32,
88 ) -> Result<(), LemmyError> {
89 let local_site_data = blocking(context.pool(), fetch_local_site_data).await??;
90 check_apub_id_valid(self.id(), &local_site_data, context.settings())
91 .map_err(LemmyError::from_message)?;
93 verify_is_public(&self.to, &self.cc)?;
94 let community = self.get_community(context, request_counter).await?;
95 verify_person_in_community(&self.actor, &community, context, request_counter).await?;
104 verify_add_remove_moderator_target(&self.target, &community)?;
108 #[tracing::instrument(skip_all)]
111 context: &Data<LemmyContext>,
112 request_counter: &mut i32,
113 ) -> Result<(), LemmyError> {
114 let community = self.get_community(context, request_counter).await?;
115 let remove_mod = self
117 .dereference(context, local_instance(context), request_counter)
120 let form = CommunityModeratorForm {
121 community_id: community.id,
122 person_id: remove_mod.id,
124 blocking(context.pool(), move |conn| {
125 CommunityModerator::leave(conn, &form)
132 .dereference(context, local_instance(context), request_counter)
134 let form = ModAddCommunityForm {
135 mod_person_id: actor.id,
136 other_person_id: remove_mod.id,
137 community_id: community.id,
140 blocking(context.pool(), move |conn| {
141 ModAddCommunity::create(conn, &form)
145 // TODO: send websocket notification about removed mod
150 #[async_trait::async_trait(?Send)]
151 impl GetCommunity for RemoveMod {
152 #[tracing::instrument(skip_all)]
153 async fn get_community(
155 context: &LemmyContext,
156 request_counter: &mut i32,
157 ) -> Result<ApubCommunity, LemmyError> {
158 get_community_from_moderators_url(&self.target, context, request_counter).await