]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/remove_mod.rs
Merge pull request #1877 from LemmyNet/refactor-apub-2
[lemmy.git] / crates / apub / src / activities / community / remove_mod.rs
1 use crate::{
2   activities::{
3     community::{announce::GetCommunity, get_community_from_moderators_url, send_to_community},
4     generate_activity_id,
5     verify_activity,
6     verify_add_remove_moderator_target,
7     verify_is_public,
8     verify_mod_action,
9     verify_person_in_community,
10   },
11   activity_lists::AnnouncableActivities,
12   generate_moderators_url,
13   objects::{community::ApubCommunity, person::ApubPerson},
14   protocol::activities::community::remove_mod::RemoveMod,
15 };
16 use activitystreams::{activity::kind::RemoveType, public};
17 use lemmy_api_common::blocking;
18 use lemmy_apub_lib::{
19   data::Data,
20   object_id::ObjectId,
21   traits::{ActivityHandler, ActorType},
22 };
23 use lemmy_db_schema::{
24   source::community::{CommunityModerator, CommunityModeratorForm},
25   traits::Joinable,
26 };
27 use lemmy_utils::LemmyError;
28 use lemmy_websocket::LemmyContext;
29
30 impl RemoveMod {
31   pub async fn send(
32     community: &ApubCommunity,
33     removed_mod: &ApubPerson,
34     actor: &ApubPerson,
35     context: &LemmyContext,
36   ) -> Result<(), LemmyError> {
37     let id = generate_activity_id(
38       RemoveType::Remove,
39       &context.settings().get_protocol_and_hostname(),
40     )?;
41     let remove = RemoveMod {
42       actor: ObjectId::new(actor.actor_id()),
43       to: vec![public()],
44       object: ObjectId::new(removed_mod.actor_id()),
45       target: generate_moderators_url(&community.actor_id)?.into(),
46       id: id.clone(),
47       cc: vec![community.actor_id()],
48       kind: RemoveType::Remove,
49       unparsed: Default::default(),
50     };
51
52     let activity = AnnouncableActivities::RemoveMod(remove);
53     let inboxes = vec![removed_mod.shared_inbox_or_inbox_url()];
54     send_to_community(activity, &id, actor, community, inboxes, context).await
55   }
56 }
57
58 #[async_trait::async_trait(?Send)]
59 impl ActivityHandler for RemoveMod {
60   type DataType = LemmyContext;
61   async fn verify(
62     &self,
63     context: &Data<LemmyContext>,
64     request_counter: &mut i32,
65   ) -> Result<(), LemmyError> {
66     verify_is_public(&self.to, &self.cc)?;
67     verify_activity(&self.id, self.actor.inner(), &context.settings())?;
68     let community = self.get_community(context, request_counter).await?;
69     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
70     verify_mod_action(&self.actor, &community, context, request_counter).await?;
71     verify_add_remove_moderator_target(&self.target, &community)?;
72     Ok(())
73   }
74
75   async fn receive(
76     self,
77     context: &Data<LemmyContext>,
78     request_counter: &mut i32,
79   ) -> Result<(), LemmyError> {
80     let community = self.get_community(context, request_counter).await?;
81     let remove_mod = self.object.dereference(context, request_counter).await?;
82
83     let form = CommunityModeratorForm {
84       community_id: community.id,
85       person_id: remove_mod.id,
86     };
87     blocking(context.pool(), move |conn| {
88       CommunityModerator::leave(conn, &form)
89     })
90     .await??;
91     // TODO: send websocket notification about removed mod
92     Ok(())
93   }
94 }
95
96 #[async_trait::async_trait(?Send)]
97 impl GetCommunity for RemoveMod {
98   async fn get_community(
99     &self,
100     context: &LemmyContext,
101     request_counter: &mut i32,
102   ) -> Result<ApubCommunity, LemmyError> {
103     get_community_from_moderators_url(&self.target, context, request_counter).await
104   }
105 }