]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/announce.rs
Merge branch 'remove_settings_and_secret_singletons_squashed'
[lemmy.git] / crates / apub / src / activities / community / announce.rs
1 use crate::{
2   activities::{
3     comment::create_or_update::CreateOrUpdateComment,
4     community::{
5       add_mod::AddMod,
6       block_user::BlockUserFromCommunity,
7       list_community_follower_inboxes,
8       remove_mod::RemoveMod,
9       undo_block_user::UndoBlockUserFromCommunity,
10       update::UpdateCommunity,
11     },
12     deletion::{delete::Delete, undo_delete::UndoDelete},
13     generate_activity_id,
14     post::create_or_update::CreateOrUpdatePost,
15     undo_remove::UndoRemovePostCommentOrCommunity,
16     verify_activity,
17     verify_community,
18     voting::{undo_vote::UndoVote, vote::Vote},
19   },
20   activity_queue::send_activity_new,
21   extensions::context::lemmy_context,
22   fetcher::object_id::ObjectId,
23   http::is_activity_already_known,
24   insert_activity,
25   ActorType,
26   CommunityType,
27 };
28 use activitystreams::{
29   activity::kind::AnnounceType,
30   base::AnyBase,
31   primitives::OneOrMany,
32   unparsed::Unparsed,
33 };
34 use lemmy_apub_lib::{values::PublicUrl, ActivityFields, ActivityHandler};
35 use lemmy_db_schema::source::community::Community;
36 use lemmy_utils::LemmyError;
37 use lemmy_websocket::LemmyContext;
38 use serde::{Deserialize, Serialize};
39 use url::Url;
40
41 #[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)]
42 #[serde(untagged)]
43 pub enum AnnouncableActivities {
44   CreateOrUpdateComment(CreateOrUpdateComment),
45   CreateOrUpdatePost(Box<CreateOrUpdatePost>),
46   Vote(Vote),
47   UndoVote(UndoVote),
48   Delete(Delete),
49   UndoDelete(UndoDelete),
50   UndoRemovePostCommentOrCommunity(UndoRemovePostCommentOrCommunity),
51   UpdateCommunity(Box<UpdateCommunity>),
52   BlockUserFromCommunity(BlockUserFromCommunity),
53   UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
54   AddMod(AddMod),
55   RemoveMod(RemoveMod),
56 }
57
58 #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)]
59 #[serde(rename_all = "camelCase")]
60 pub struct AnnounceActivity {
61   actor: ObjectId<Community>,
62   to: [PublicUrl; 1],
63   object: AnnouncableActivities,
64   cc: Vec<Url>,
65   #[serde(rename = "type")]
66   kind: AnnounceType,
67   id: Url,
68   #[serde(rename = "@context")]
69   context: OneOrMany<AnyBase>,
70   #[serde(flatten)]
71   unparsed: Unparsed,
72 }
73
74 impl AnnounceActivity {
75   pub async fn send(
76     object: AnnouncableActivities,
77     community: &Community,
78     additional_inboxes: Vec<Url>,
79     context: &LemmyContext,
80   ) -> Result<(), LemmyError> {
81     let announce = AnnounceActivity {
82       actor: ObjectId::new(community.actor_id()),
83       to: [PublicUrl::Public],
84       object,
85       cc: vec![community.followers_url()],
86       kind: AnnounceType::Announce,
87       id: generate_activity_id(
88         &AnnounceType::Announce,
89         &context.settings().get_protocol_and_hostname(),
90       )?,
91       context: lemmy_context(),
92       unparsed: Default::default(),
93     };
94     let inboxes = list_community_follower_inboxes(community, additional_inboxes, context).await?;
95     send_activity_new(context, &announce, &announce.id, community, inboxes, false).await
96   }
97 }
98
99 #[async_trait::async_trait(?Send)]
100 impl ActivityHandler for AnnounceActivity {
101   async fn verify(
102     &self,
103     context: &LemmyContext,
104     request_counter: &mut i32,
105   ) -> Result<(), LemmyError> {
106     verify_activity(self, &context.settings())?;
107     verify_community(&self.actor, context, request_counter).await?;
108     self.object.verify(context, request_counter).await?;
109     Ok(())
110   }
111
112   async fn receive(
113     self,
114     context: &LemmyContext,
115     request_counter: &mut i32,
116   ) -> Result<(), LemmyError> {
117     if is_activity_already_known(context.pool(), self.object.id_unchecked()).await? {
118       return Ok(());
119     }
120     insert_activity(
121       self.object.id_unchecked(),
122       self.object.clone(),
123       false,
124       true,
125       context.pool(),
126     )
127     .await?;
128     self.object.receive(context, request_counter).await
129   }
130 }