]> Untitled Git - lemmy.git/blob - crates/apub/src/fetcher/user_or_community.rs
Federate with Peertube (#2244)
[lemmy.git] / crates / apub / src / fetcher / user_or_community.rs
1 use crate::{
2   objects::{community::ApubCommunity, person::ApubPerson},
3   protocol::objects::{group::Group, person::Person},
4 };
5 use chrono::NaiveDateTime;
6 use lemmy_apub_lib::traits::{ActorType, ApubObject};
7 use lemmy_utils::LemmyError;
8 use lemmy_websocket::LemmyContext;
9 use serde::{Deserialize, Serialize};
10 use url::Url;
11
12 #[derive(Clone, Debug)]
13 pub enum UserOrCommunity {
14   User(ApubPerson),
15   Community(ApubCommunity),
16 }
17
18 #[derive(Serialize, Deserialize, Clone, Debug)]
19 #[serde(untagged)]
20 pub enum PersonOrGroup {
21   Person(Person),
22   Group(Group),
23 }
24
25 #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
26 pub enum PersonOrGroupType {
27   Person,
28   Group,
29 }
30
31 #[async_trait::async_trait(?Send)]
32 impl ApubObject for UserOrCommunity {
33   type DataType = LemmyContext;
34   type ApubType = PersonOrGroup;
35   type DbType = ();
36   type TombstoneType = ();
37
38   fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
39     Some(match self {
40       UserOrCommunity::User(p) => p.last_refreshed_at,
41       UserOrCommunity::Community(p) => p.last_refreshed_at,
42     })
43   }
44
45   #[tracing::instrument(skip_all)]
46   async fn read_from_apub_id(
47     object_id: Url,
48     data: &Self::DataType,
49   ) -> Result<Option<Self>, LemmyError> {
50     let person = ApubPerson::read_from_apub_id(object_id.clone(), data).await?;
51     Ok(match person {
52       Some(o) => Some(UserOrCommunity::User(o)),
53       None => ApubCommunity::read_from_apub_id(object_id, data)
54         .await?
55         .map(UserOrCommunity::Community),
56     })
57   }
58
59   #[tracing::instrument(skip_all)]
60   async fn delete(self, data: &Self::DataType) -> Result<(), LemmyError> {
61     match self {
62       UserOrCommunity::User(p) => p.delete(data).await,
63       UserOrCommunity::Community(p) => p.delete(data).await,
64     }
65   }
66
67   async fn into_apub(self, _data: &Self::DataType) -> Result<Self::ApubType, LemmyError> {
68     unimplemented!()
69   }
70
71   fn to_tombstone(&self) -> Result<Self::TombstoneType, LemmyError> {
72     unimplemented!()
73   }
74
75   #[tracing::instrument(skip_all)]
76   async fn verify(
77     apub: &Self::ApubType,
78     expected_domain: &Url,
79     data: &Self::DataType,
80     request_counter: &mut i32,
81   ) -> Result<(), LemmyError> {
82     match apub {
83       PersonOrGroup::Person(a) => {
84         ApubPerson::verify(a, expected_domain, data, request_counter).await
85       }
86       PersonOrGroup::Group(a) => {
87         ApubCommunity::verify(a, expected_domain, data, request_counter).await
88       }
89     }
90   }
91
92   #[tracing::instrument(skip_all)]
93   async fn from_apub(
94     apub: Self::ApubType,
95     data: &Self::DataType,
96     request_counter: &mut i32,
97   ) -> Result<Self, LemmyError> {
98     Ok(match apub {
99       PersonOrGroup::Person(p) => {
100         UserOrCommunity::User(ApubPerson::from_apub(p, data, request_counter).await?)
101       }
102       PersonOrGroup::Group(p) => {
103         UserOrCommunity::Community(ApubCommunity::from_apub(p, data, request_counter).await?)
104       }
105     })
106   }
107 }
108
109 impl ActorType for UserOrCommunity {
110   fn actor_id(&self) -> Url {
111     match self {
112       UserOrCommunity::User(p) => p.actor_id(),
113       UserOrCommunity::Community(p) => p.actor_id(),
114     }
115   }
116
117   fn public_key(&self) -> String {
118     match self {
119       UserOrCommunity::User(p) => p.public_key(),
120       UserOrCommunity::Community(p) => p.public_key(),
121     }
122   }
123
124   fn private_key(&self) -> Option<String> {
125     todo!()
126   }
127
128   fn inbox_url(&self) -> Url {
129     todo!()
130   }
131
132   fn shared_inbox_url(&self) -> Option<Url> {
133     todo!()
134   }
135 }