]> Untitled Git - lemmy.git/blob - crates/apub/src/activity_lists.rs
c7fb51859d1cdeb0e262847a409ac5ddf900c4b2
[lemmy.git] / crates / apub / src / activity_lists.rs
1 use crate::{
2   activities::community::announce::GetCommunity,
3   objects::community::ApubCommunity,
4   protocol::{
5     activities::{
6       block::{block_user::BlockUser, undo_block_user::UndoBlockUser},
7       community::{
8         add_mod::AddMod,
9         announce::{AnnounceActivity, RawAnnouncableActivities},
10         remove_mod::RemoveMod,
11         report::Report,
12         update::UpdateCommunity,
13       },
14       create_or_update::{
15         comment::CreateOrUpdateComment,
16         post::CreateOrUpdatePost,
17         private_message::CreateOrUpdatePrivateMessage,
18       },
19       deletion::{delete::Delete, delete_user::DeleteUser, undo_delete::UndoDelete},
20       following::{
21         accept::AcceptFollowCommunity,
22         follow::FollowCommunity,
23         undo_follow::UndoFollowCommunity,
24       },
25       voting::{undo_vote::UndoVote, vote::Vote},
26     },
27     objects::page::Page,
28   },
29 };
30 use activitypub_federation::{deser::context::WithContext, traits::activity_handler};
31 use lemmy_utils::error::LemmyError;
32 use lemmy_websocket::LemmyContext;
33 use serde::{Deserialize, Serialize};
34 use url::Url;
35
36 #[derive(Debug, Deserialize, Serialize)]
37 #[serde(untagged)]
38 #[activity_handler(LemmyContext, LemmyError)]
39 pub enum SharedInboxActivities {
40   PersonInboxActivities(Box<WithContext<PersonInboxActivities>>),
41   GroupInboxActivities(Box<WithContext<GroupInboxActivities>>),
42 }
43
44 #[derive(Debug, Deserialize, Serialize)]
45 #[serde(untagged)]
46 #[activity_handler(LemmyContext, LemmyError)]
47 pub enum GroupInboxActivities {
48   FollowCommunity(FollowCommunity),
49   UndoFollowCommunity(UndoFollowCommunity),
50   Report(Report),
51   // This is a catch-all and needs to be last
52   AnnouncableActivities(RawAnnouncableActivities),
53 }
54
55 #[derive(Clone, Debug, Deserialize, Serialize)]
56 #[serde(untagged)]
57 #[activity_handler(LemmyContext, LemmyError)]
58 pub enum PersonInboxActivities {
59   AcceptFollowCommunity(AcceptFollowCommunity),
60   CreateOrUpdatePrivateMessage(CreateOrUpdatePrivateMessage),
61   Delete(Delete),
62   UndoDelete(UndoDelete),
63   AnnounceActivity(AnnounceActivity),
64 }
65
66 /// This is necessary for user inbox, which can also receive some "announcable" activities,
67 /// eg a comment mention. This needs to be a separate enum so that announcables received in shared
68 /// inbox can fall through to be parsed as GroupInboxActivities::AnnouncableActivities.
69 #[derive(Clone, Debug, Deserialize, Serialize)]
70 #[serde(untagged)]
71 #[activity_handler(LemmyContext, LemmyError)]
72 pub enum PersonInboxActivitiesWithAnnouncable {
73   PersonInboxActivities(PersonInboxActivities),
74   AnnouncableActivities(AnnouncableActivities),
75 }
76
77 #[derive(Clone, Debug, Deserialize, Serialize)]
78 #[serde(untagged)]
79 #[activity_handler(LemmyContext, LemmyError)]
80 pub enum AnnouncableActivities {
81   CreateOrUpdateComment(CreateOrUpdateComment),
82   CreateOrUpdatePost(Box<CreateOrUpdatePost>),
83   Vote(Vote),
84   UndoVote(UndoVote),
85   Delete(Delete),
86   UndoDelete(UndoDelete),
87   UpdateCommunity(UpdateCommunity),
88   BlockUser(BlockUser),
89   UndoBlockUser(UndoBlockUser),
90   AddMod(AddMod),
91   RemoveMod(RemoveMod),
92   // For compatibility with Pleroma/Mastodon (send only)
93   Page(Page),
94 }
95
96 #[derive(Clone, Debug, Deserialize, Serialize)]
97 #[serde(untagged)]
98 #[activity_handler(LemmyContext, LemmyError)]
99 #[allow(clippy::enum_variant_names)]
100 pub enum SiteInboxActivities {
101   BlockUser(BlockUser),
102   UndoBlockUser(UndoBlockUser),
103   DeleteUser(DeleteUser),
104 }
105
106 #[async_trait::async_trait(?Send)]
107 impl GetCommunity for AnnouncableActivities {
108   #[tracing::instrument(skip(self, context))]
109   async fn get_community(
110     &self,
111     context: &LemmyContext,
112     request_counter: &mut i32,
113   ) -> Result<ApubCommunity, LemmyError> {
114     use AnnouncableActivities::*;
115     let community = match self {
116       CreateOrUpdateComment(a) => a.get_community(context, request_counter).await?,
117       CreateOrUpdatePost(a) => a.get_community(context, request_counter).await?,
118       Vote(a) => a.get_community(context, request_counter).await?,
119       UndoVote(a) => a.get_community(context, request_counter).await?,
120       Delete(a) => a.get_community(context, request_counter).await?,
121       UndoDelete(a) => a.get_community(context, request_counter).await?,
122       UpdateCommunity(a) => a.get_community(context, request_counter).await?,
123       BlockUser(a) => a.get_community(context, request_counter).await?,
124       UndoBlockUser(a) => a.get_community(context, request_counter).await?,
125       AddMod(a) => a.get_community(context, request_counter).await?,
126       RemoveMod(a) => a.get_community(context, request_counter).await?,
127       Page(_) => unimplemented!(),
128     };
129     Ok(community)
130   }
131 }
132
133 #[cfg(test)]
134 mod tests {
135   use crate::{
136     activity_lists::{
137       GroupInboxActivities,
138       PersonInboxActivities,
139       PersonInboxActivitiesWithAnnouncable,
140       SiteInboxActivities,
141     },
142     protocol::tests::test_parse_lemmy_item,
143   };
144
145   #[test]
146   fn test_group_inbox() {
147     test_parse_lemmy_item::<GroupInboxActivities>("assets/lemmy/activities/following/follow.json")
148       .unwrap();
149     test_parse_lemmy_item::<GroupInboxActivities>(
150       "assets/lemmy/activities/create_or_update/create_note.json",
151     )
152     .unwrap();
153   }
154
155   #[test]
156   fn test_person_inbox() {
157     test_parse_lemmy_item::<PersonInboxActivities>("assets/lemmy/activities/following/accept.json")
158       .unwrap();
159     test_parse_lemmy_item::<PersonInboxActivitiesWithAnnouncable>(
160       "assets/lemmy/activities/create_or_update/create_note.json",
161     )
162     .unwrap();
163     test_parse_lemmy_item::<PersonInboxActivitiesWithAnnouncable>(
164       "assets/lemmy/activities/create_or_update/create_private_message.json",
165     )
166     .unwrap();
167   }
168
169   #[test]
170   fn test_site_inbox() {
171     test_parse_lemmy_item::<SiteInboxActivities>(
172       "assets/lemmy/activities/deletion/delete_user.json",
173     )
174     .unwrap();
175   }
176 }