]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/update.rs
add enable_federated_downvotes site option
[lemmy.git] / crates / apub / src / activities / community / update.rs
1 use crate::{
2   activities::{
3     community::send_activity_in_community,
4     generate_activity_id,
5     verify_is_public,
6     verify_mod_action,
7     verify_person_in_community,
8   },
9   activity_lists::AnnouncableActivities,
10   insert_received_activity,
11   objects::{community::ApubCommunity, person::ApubPerson},
12   protocol::{activities::community::update::UpdateCommunity, InCommunity},
13 };
14 use activitypub_federation::{
15   config::Data,
16   kinds::{activity::UpdateType, public},
17   traits::{ActivityHandler, Actor, Object},
18 };
19 use lemmy_api_common::context::LemmyContext;
20 use lemmy_db_schema::{
21   source::{community::Community, person::Person},
22   traits::Crud,
23 };
24 use lemmy_utils::error::LemmyError;
25 use url::Url;
26
27 pub(crate) async fn send_update_community(
28   community: Community,
29   actor: Person,
30   context: Data<LemmyContext>,
31 ) -> Result<(), LemmyError> {
32   let community: ApubCommunity = community.into();
33   let actor: ApubPerson = actor.into();
34   let id = generate_activity_id(
35     UpdateType::Update,
36     &context.settings().get_protocol_and_hostname(),
37   )?;
38   let update = UpdateCommunity {
39     actor: actor.id().into(),
40     to: vec![public()],
41     object: Box::new(community.clone().into_json(&context).await?),
42     cc: vec![community.id()],
43     kind: UpdateType::Update,
44     id: id.clone(),
45     audience: Some(community.id().into()),
46   };
47
48   let activity = AnnouncableActivities::UpdateCommunity(update);
49   send_activity_in_community(activity, &actor, &community, vec![], true, &context).await
50 }
51
52 #[async_trait::async_trait]
53 impl ActivityHandler for UpdateCommunity {
54   type DataType = LemmyContext;
55   type Error = LemmyError;
56
57   fn id(&self) -> &Url {
58     &self.id
59   }
60
61   fn actor(&self) -> &Url {
62     self.actor.inner()
63   }
64
65   #[tracing::instrument(skip_all)]
66   async fn verify(&self, context: &Data<Self::DataType>) -> Result<(), LemmyError> {
67     insert_received_activity(&self.id, context).await?;
68     verify_is_public(&self.to, &self.cc)?;
69     let community = self.community(context).await?;
70     verify_person_in_community(&self.actor, &community, context).await?;
71     verify_mod_action(&self.actor, self.object.id.inner(), community.id, context).await?;
72     ApubCommunity::verify(&self.object, &community.actor_id.clone().into(), context).await?;
73     Ok(())
74   }
75
76   #[tracing::instrument(skip_all)]
77   async fn receive(self, context: &Data<Self::DataType>) -> Result<(), LemmyError> {
78     let community = self.community(context).await?;
79
80     let community_update_form = self.object.into_update_form();
81
82     Community::update(&mut context.pool(), community.id, &community_update_form).await?;
83     Ok(())
84   }
85 }