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