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