]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/update.rs
Moving settings to Database. (#2492)
[lemmy.git] / crates / apub / src / activities / community / update.rs
1 use crate::{
2   activities::{
3     community::{announce::GetCommunity, 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   check_apub_id_valid,
11   fetch_local_site_data,
12   local_instance,
13   objects::{community::ApubCommunity, person::ApubPerson},
14   protocol::activities::community::update::UpdateCommunity,
15   ActorType,
16 };
17 use activitypub_federation::{
18   core::object_id::ObjectId,
19   data::Data,
20   traits::{ActivityHandler, ApubObject},
21 };
22 use activitystreams_kinds::{activity::UpdateType, public};
23 use lemmy_api_common::utils::blocking;
24 use lemmy_db_schema::{source::community::Community, traits::Crud};
25 use lemmy_utils::error::LemmyError;
26 use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud};
27 use url::Url;
28
29 impl UpdateCommunity {
30   #[tracing::instrument(skip_all)]
31   pub async fn send(
32     community: ApubCommunity,
33     actor: &ApubPerson,
34     context: &LemmyContext,
35   ) -> Result<(), LemmyError> {
36     let id = generate_activity_id(
37       UpdateType::Update,
38       &context.settings().get_protocol_and_hostname(),
39     )?;
40     let update = UpdateCommunity {
41       actor: ObjectId::new(actor.actor_id()),
42       to: vec![public()],
43       object: Box::new(community.clone().into_apub(context).await?),
44       cc: vec![community.actor_id()],
45       kind: UpdateType::Update,
46       id: id.clone(),
47       unparsed: Default::default(),
48     };
49
50     let activity = AnnouncableActivities::UpdateCommunity(update);
51     send_activity_in_community(activity, actor, &community, vec![], context).await
52   }
53 }
54
55 #[async_trait::async_trait(?Send)]
56 impl ActivityHandler for UpdateCommunity {
57   type DataType = LemmyContext;
58   type Error = LemmyError;
59
60   fn id(&self) -> &Url {
61     &self.id
62   }
63
64   fn actor(&self) -> &Url {
65     self.actor.inner()
66   }
67
68   #[tracing::instrument(skip_all)]
69   async fn verify(
70     &self,
71     context: &Data<LemmyContext>,
72     request_counter: &mut i32,
73   ) -> Result<(), LemmyError> {
74     let local_site_data = blocking(context.pool(), fetch_local_site_data).await??;
75     check_apub_id_valid(self.id(), &local_site_data, context.settings())
76       .map_err(LemmyError::from_message)?;
77     verify_is_public(&self.to, &self.cc)?;
78     let community = self.get_community(context, request_counter).await?;
79     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
80     verify_mod_action(
81       &self.actor,
82       self.object.id.inner(),
83       community.id,
84       context,
85       request_counter,
86     )
87     .await?;
88     ApubCommunity::verify(
89       &self.object,
90       &community.actor_id.clone().into(),
91       context,
92       request_counter,
93     )
94     .await?;
95     Ok(())
96   }
97
98   #[tracing::instrument(skip_all)]
99   async fn receive(
100     self,
101     context: &Data<LemmyContext>,
102     request_counter: &mut i32,
103   ) -> Result<(), LemmyError> {
104     let community = self.get_community(context, request_counter).await?;
105
106     let community_update_form = self.object.into_update_form();
107
108     let updated_community = blocking(context.pool(), move |conn| {
109       Community::update(conn, community.id, &community_update_form)
110     })
111     .await??;
112
113     send_community_ws_message(
114       updated_community.id,
115       UserOperationCrud::EditCommunity,
116       None,
117       None,
118       context,
119     )
120     .await?;
121     Ok(())
122   }
123 }
124
125 #[async_trait::async_trait(?Send)]
126 impl GetCommunity for UpdateCommunity {
127   #[tracing::instrument(skip_all)]
128   async fn get_community(
129     &self,
130     context: &LemmyContext,
131     request_counter: &mut i32,
132   ) -> Result<ApubCommunity, LemmyError> {
133     let cid = ObjectId::new(self.object.id.clone());
134     cid
135       .dereference(context, local_instance(context), request_counter)
136       .await
137   }
138 }