]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/announce.rs
Rewrite voting (#1685)
[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       undo_block_user::UndoBlockUserFromCommunity,
9     },
10     deletion::{
11       delete::DeletePostCommentOrCommunity,
12       undo_delete::UndoDeletePostCommentOrCommunity,
13     },
14     generate_activity_id,
15     post::create_or_update::CreateOrUpdatePost,
16     removal::{
17       remove::RemovePostCommentCommunityOrMod,
18       undo_remove::UndoRemovePostCommentOrCommunity,
19     },
20     verify_activity,
21     verify_community,
22     voting::{undo_vote::UndoVote, vote::Vote},
23   },
24   activity_queue::send_activity_new,
25   extensions::context::lemmy_context,
26   http::is_activity_already_known,
27   insert_activity,
28   ActorType,
29   CommunityType,
30 };
31 use activitystreams::activity::kind::AnnounceType;
32 use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
33 use lemmy_db_schema::source::community::Community;
34 use lemmy_utils::LemmyError;
35 use lemmy_websocket::LemmyContext;
36 use serde::{Deserialize, Serialize};
37 use url::Url;
38
39 #[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler)]
40 #[serde(untagged)]
41 pub enum AnnouncableActivities {
42   CreateOrUpdateComment(CreateOrUpdateComment),
43   CreateOrUpdatePost(Box<CreateOrUpdatePost>),
44   Vote(Vote),
45   UndoVote(UndoVote),
46   DeletePostCommentOrCommunity(DeletePostCommentOrCommunity),
47   UndoDeletePostCommentOrCommunity(UndoDeletePostCommentOrCommunity),
48   RemovePostCommentCommunityOrMod(RemovePostCommentCommunityOrMod),
49   UndoRemovePostCommentOrCommunity(UndoRemovePostCommentOrCommunity),
50   BlockUserFromCommunity(BlockUserFromCommunity),
51   UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
52   AddMod(AddMod),
53 }
54
55 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
56 #[serde(rename_all = "camelCase")]
57 pub struct AnnounceActivity {
58   to: PublicUrl,
59   object: AnnouncableActivities,
60   cc: Vec<Url>,
61   #[serde(rename = "type")]
62   kind: AnnounceType,
63   #[serde(flatten)]
64   common: ActivityCommonFields,
65 }
66
67 impl AnnounceActivity {
68   pub async fn send(
69     object: AnnouncableActivities,
70     community: &Community,
71     additional_inboxes: Vec<Url>,
72     context: &LemmyContext,
73   ) -> Result<(), LemmyError> {
74     let announce = AnnounceActivity {
75       to: PublicUrl::Public,
76       object,
77       cc: vec![community.followers_url()],
78       kind: AnnounceType::Announce,
79       common: ActivityCommonFields {
80         context: lemmy_context(),
81         id: generate_activity_id(&AnnounceType::Announce)?,
82         actor: community.actor_id(),
83         unparsed: Default::default(),
84       },
85     };
86     let inboxes = list_community_follower_inboxes(community, additional_inboxes, context).await?;
87     send_activity_new(
88       context,
89       &announce,
90       &announce.common.id,
91       community,
92       inboxes,
93       false,
94     )
95     .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.common())?;
107     verify_community(&self.common.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.common().id_unchecked()).await? {
118       return Ok(());
119     }
120     insert_activity(
121       self.object.common().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
131   fn common(&self) -> &ActivityCommonFields {
132     &self.common
133   }
134 }