]> Untitled Git - lemmy.git/blob - crates/apub/src/activity_lists.rs
Federation tests replication round1 - demonstrate absent replication of comment delet...
[lemmy.git] / crates / apub / src / activity_lists.rs
1 use crate::{
2   objects::community::ApubCommunity,
3   protocol::{
4     activities::{
5       block::{block_user::BlockUser, undo_block_user::UndoBlockUser},
6       community::{
7         announce::{AnnounceActivity, RawAnnouncableActivities},
8         collection_add::CollectionAdd,
9         collection_remove::CollectionRemove,
10         lock_page::{LockPage, UndoLockPage},
11         report::Report,
12         update::UpdateCommunity,
13       },
14       create_or_update::{
15         chat_message::CreateOrUpdateChatMessage,
16         note::CreateOrUpdateNote,
17         page::CreateOrUpdatePage,
18       },
19       deletion::{delete::Delete, delete_user::DeleteUser, undo_delete::UndoDelete},
20       following::{accept::AcceptFollow, follow::Follow, undo_follow::UndoFollow},
21       voting::{undo_vote::UndoVote, vote::Vote},
22     },
23     objects::page::Page,
24     InCommunity,
25   },
26 };
27 use activitypub_federation::{config::Data, traits::ActivityHandler};
28 use lemmy_api_common::context::LemmyContext;
29 use lemmy_utils::error::LemmyError;
30 use serde::{Deserialize, Serialize};
31 use url::Url;
32
33 /// List of activities which the shared inbox can handle.
34 ///
35 /// This could theoretically be defined as an enum with variants `GroupInboxActivities` and
36 /// `PersonInboxActivities`. In practice we need to write it out manually so that priorities
37 /// are handled correctly.
38 #[derive(Debug, Deserialize, Serialize)]
39 #[serde(untagged)]
40 #[enum_delegate::implement(ActivityHandler)]
41 pub enum SharedInboxActivities {
42   Follow(Follow),
43   AcceptFollow(AcceptFollow),
44   UndoFollow(UndoFollow),
45   CreateOrUpdatePrivateMessage(CreateOrUpdateChatMessage),
46   Report(Report),
47   AnnounceActivity(AnnounceActivity),
48   /// This is a catch-all and needs to be last
49   RawAnnouncableActivities(RawAnnouncableActivities),
50 }
51
52 /// List of activities which the group inbox can handle.
53 #[derive(Debug, Deserialize, Serialize)]
54 #[serde(untagged)]
55 #[enum_delegate::implement(ActivityHandler)]
56 pub enum GroupInboxActivities {
57   Follow(Follow),
58   UndoFollow(UndoFollow),
59   Report(Report),
60   /// This is a catch-all and needs to be last
61   AnnouncableActivities(RawAnnouncableActivities),
62 }
63
64 /// List of activities which the person inbox can handle.
65 #[derive(Clone, Debug, Deserialize, Serialize)]
66 #[serde(untagged)]
67 #[enum_delegate::implement(ActivityHandler)]
68 pub enum PersonInboxActivities {
69   Follow(Follow),
70   AcceptFollow(AcceptFollow),
71   UndoFollow(UndoFollow),
72   CreateOrUpdatePrivateMessage(CreateOrUpdateChatMessage),
73   Delete(Delete),
74   UndoDelete(UndoDelete),
75   AnnounceActivity(AnnounceActivity),
76   /// User can also receive some "announcable" activities, eg a comment mention.
77   AnnouncableActivities(AnnouncableActivities),
78 }
79
80 #[derive(Clone, Debug, Deserialize, Serialize)]
81 #[serde(untagged)]
82 #[enum_delegate::implement(ActivityHandler)]
83 pub enum AnnouncableActivities {
84   CreateOrUpdateComment(CreateOrUpdateNote),
85   CreateOrUpdatePost(CreateOrUpdatePage),
86   Vote(Vote),
87   UndoVote(UndoVote),
88   Delete(Delete),
89   UndoDelete(UndoDelete),
90   UpdateCommunity(UpdateCommunity),
91   BlockUser(BlockUser),
92   UndoBlockUser(UndoBlockUser),
93   CollectionAdd(CollectionAdd),
94   CollectionRemove(CollectionRemove),
95   LockPost(LockPage),
96   UndoLockPost(UndoLockPage),
97   // For compatibility with Pleroma/Mastodon (send only)
98   Page(Page),
99 }
100
101 #[derive(Clone, Debug, Deserialize, Serialize)]
102 #[serde(untagged)]
103 #[enum_delegate::implement(ActivityHandler)]
104 #[allow(clippy::enum_variant_names)]
105 pub enum SiteInboxActivities {
106   BlockUser(BlockUser),
107   UndoBlockUser(UndoBlockUser),
108   DeleteUser(DeleteUser),
109 }
110
111 #[async_trait::async_trait]
112 impl InCommunity for AnnouncableActivities {
113   #[tracing::instrument(skip(self, context))]
114   async fn community(&self, context: &Data<LemmyContext>) -> Result<ApubCommunity, LemmyError> {
115     use AnnouncableActivities::*;
116     match self {
117       CreateOrUpdateComment(a) => a.community(context).await,
118       CreateOrUpdatePost(a) => a.community(context).await,
119       Vote(a) => a.community(context).await,
120       UndoVote(a) => a.community(context).await,
121       Delete(a) => a.community(context).await,
122       UndoDelete(a) => a.community(context).await,
123       UpdateCommunity(a) => a.community(context).await,
124       BlockUser(a) => a.community(context).await,
125       UndoBlockUser(a) => a.community(context).await,
126       CollectionAdd(a) => a.community(context).await,
127       CollectionRemove(a) => a.community(context).await,
128       LockPost(a) => a.community(context).await,
129       UndoLockPost(a) => a.community(context).await,
130       Page(_) => unimplemented!(),
131     }
132   }
133 }
134
135 #[cfg(test)]
136 mod tests {
137   #![allow(clippy::unwrap_used)]
138   #![allow(clippy::indexing_slicing)]
139
140   use crate::{
141     activity_lists::{GroupInboxActivities, PersonInboxActivities, SiteInboxActivities},
142     protocol::tests::{test_json, 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::<PersonInboxActivities>(
160       "assets/lemmy/activities/create_or_update/create_note.json",
161     )
162     .unwrap();
163     test_parse_lemmy_item::<PersonInboxActivities>(
164       "assets/lemmy/activities/create_or_update/create_private_message.json",
165     )
166     .unwrap();
167     test_json::<PersonInboxActivities>("assets/mastodon/activities/follow.json").unwrap();
168   }
169
170   #[test]
171   fn test_site_inbox() {
172     test_parse_lemmy_item::<SiteInboxActivities>(
173       "assets/lemmy/activities/deletion/delete_user.json",
174     )
175     .unwrap();
176   }
177 }