4 announce::{AnnouncableActivities, GetCommunity},
5 get_community_from_moderators_url,
10 verify_add_remove_moderator_target,
13 verify_person_in_community,
15 context::lemmy_context,
16 fetcher::object_id::ObjectId,
17 generate_moderators_url,
18 objects::{community::ApubCommunity, person::ApubPerson},
20 use activitystreams::{
21 activity::kind::RemoveType,
23 primitives::OneOrMany,
27 use lemmy_api_common::blocking;
30 traits::{ActivityFields, ActivityHandler, ActorType},
32 use lemmy_db_schema::{
33 source::community::{CommunityModerator, CommunityModeratorForm},
36 use lemmy_utils::LemmyError;
37 use lemmy_websocket::LemmyContext;
38 use serde::{Deserialize, Serialize};
41 #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)]
42 #[serde(rename_all = "camelCase")]
43 pub struct RemoveMod {
44 actor: ObjectId<ApubPerson>,
46 pub(in crate::activities) object: ObjectId<ApubPerson>,
48 #[serde(rename = "type")]
50 pub(in crate::activities) target: Url,
52 #[serde(rename = "@context")]
53 context: OneOrMany<AnyBase>,
60 community: &ApubCommunity,
61 removed_mod: &ApubPerson,
63 context: &LemmyContext,
64 ) -> Result<(), LemmyError> {
65 let id = generate_activity_id(
67 &context.settings().get_protocol_and_hostname(),
69 let remove = RemoveMod {
70 actor: ObjectId::new(actor.actor_id()),
72 object: ObjectId::new(removed_mod.actor_id()),
73 target: generate_moderators_url(&community.actor_id)?.into(),
75 context: lemmy_context(),
76 cc: vec![community.actor_id()],
77 kind: RemoveType::Remove,
78 unparsed: Default::default(),
81 let activity = AnnouncableActivities::RemoveMod(remove);
82 let inboxes = vec![removed_mod.shared_inbox_or_inbox_url()];
83 send_to_community(activity, &id, actor, community, inboxes, context).await
87 #[async_trait::async_trait(?Send)]
88 impl ActivityHandler for RemoveMod {
89 type DataType = LemmyContext;
92 context: &Data<LemmyContext>,
93 request_counter: &mut i32,
94 ) -> Result<(), LemmyError> {
95 verify_is_public(&self.to)?;
96 verify_activity(self, &context.settings())?;
97 let community = self.get_community(context, request_counter).await?;
98 verify_person_in_community(&self.actor, &community, context, request_counter).await?;
99 verify_mod_action(&self.actor, &community, context, request_counter).await?;
100 verify_add_remove_moderator_target(&self.target, &community)?;
106 context: &Data<LemmyContext>,
107 request_counter: &mut i32,
108 ) -> Result<(), LemmyError> {
109 let community = self.get_community(context, request_counter).await?;
110 let remove_mod = self.object.dereference(context, request_counter).await?;
112 let form = CommunityModeratorForm {
113 community_id: community.id,
114 person_id: remove_mod.id,
116 blocking(context.pool(), move |conn| {
117 CommunityModerator::leave(conn, &form)
120 // TODO: send websocket notification about removed mod
125 #[async_trait::async_trait(?Send)]
126 impl GetCommunity for RemoveMod {
127 async fn get_community(
129 context: &LemmyContext,
130 request_counter: &mut i32,
131 ) -> Result<ApubCommunity, LemmyError> {
132 get_community_from_moderators_url(&self.target, context, request_counter).await