3 community::send_activity_in_community,
7 verify_person_in_community,
9 activity_lists::AnnouncableActivities,
11 objects::{community::ApubCommunity, person::ApubPerson, post::ApubPost},
12 protocol::{activities::community::collection_remove::CollectionRemove, InCommunity},
15 use activitypub_federation::{
16 core::object_id::ObjectId,
18 traits::{ActivityHandler, Actor},
20 use activitystreams_kinds::{activity::RemoveType, public};
21 use lemmy_api_common::{
22 context::LemmyContext,
23 utils::{generate_featured_url, generate_moderators_url},
25 use lemmy_db_schema::{
26 impls::community::CollectionType,
28 community::{Community, CommunityModerator, CommunityModeratorForm},
29 moderator::{ModAddCommunity, ModAddCommunityForm},
30 post::{Post, PostUpdateForm},
32 traits::{Crud, Joinable},
34 use lemmy_utils::error::LemmyError;
37 impl CollectionRemove {
38 #[tracing::instrument(skip_all)]
39 pub async fn send_remove_mod(
40 community: &ApubCommunity,
41 removed_mod: &ApubPerson,
43 context: &LemmyContext,
44 ) -> Result<(), LemmyError> {
45 let id = generate_activity_id(
47 &context.settings().get_protocol_and_hostname(),
49 let remove = CollectionRemove {
50 actor: ObjectId::new(actor.actor_id()),
52 object: ObjectId::new(removed_mod.actor_id()),
53 target: generate_moderators_url(&community.actor_id)?.into(),
55 cc: vec![community.actor_id()],
56 kind: RemoveType::Remove,
57 audience: Some(ObjectId::new(community.actor_id())),
60 let activity = AnnouncableActivities::CollectionRemove(remove);
61 let inboxes = vec![removed_mod.shared_inbox_or_inbox()];
62 send_activity_in_community(activity, actor, community, inboxes, true, context).await
65 pub async fn send_remove_featured_post(
66 community: &ApubCommunity,
67 featured_post: &ApubPost,
69 context: &LemmyContext,
70 ) -> Result<(), LemmyError> {
71 let id = generate_activity_id(
73 &context.settings().get_protocol_and_hostname(),
75 let remove = CollectionRemove {
76 actor: ObjectId::new(actor.actor_id()),
78 object: featured_post.ap_id.clone().into(),
79 target: generate_featured_url(&community.actor_id)?.into(),
80 cc: vec![community.actor_id()],
81 kind: RemoveType::Remove,
83 audience: Some(ObjectId::new(community.actor_id())),
85 let activity = AnnouncableActivities::CollectionRemove(remove);
86 send_activity_in_community(activity, actor, community, vec![], true, context).await
90 #[async_trait::async_trait(?Send)]
91 impl ActivityHandler for CollectionRemove {
92 type DataType = LemmyContext;
93 type Error = LemmyError;
95 fn id(&self) -> &Url {
99 fn actor(&self) -> &Url {
103 #[tracing::instrument(skip_all)]
106 context: &Data<LemmyContext>,
107 request_counter: &mut i32,
108 ) -> Result<(), LemmyError> {
109 verify_is_public(&self.to, &self.cc)?;
110 let community = self.community(context, request_counter).await?;
111 verify_person_in_community(&self.actor, &community, context, request_counter).await?;
123 #[tracing::instrument(skip_all)]
126 context: &Data<LemmyContext>,
127 request_counter: &mut i32,
128 ) -> Result<(), LemmyError> {
129 let (community, collection_type) =
130 Community::get_by_collection_url(context.pool(), &self.target.into()).await?;
131 match collection_type {
132 CollectionType::Moderators => {
133 let remove_mod = self
135 .dereference(context, local_instance(context).await, request_counter)
138 let form = CommunityModeratorForm {
139 community_id: community.id,
140 person_id: remove_mod.id,
142 CommunityModerator::leave(context.pool(), &form).await?;
147 .dereference(context, local_instance(context).await, request_counter)
149 let form = ModAddCommunityForm {
150 mod_person_id: actor.id,
151 other_person_id: remove_mod.id,
152 community_id: community.id,
155 ModAddCommunity::create(context.pool(), &form).await?;
157 // TODO: send websocket notification about removed mod
159 CollectionType::Featured => {
160 let post = ObjectId::<ApubPost>::new(self.object)
161 .dereference(context, local_instance(context).await, request_counter)
163 let form = PostUpdateForm::builder()
164 .featured_community(Some(false))
166 Post::update(context.pool(), post.id, &form).await?;