1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
use activitypub_federation::{
config::Data,
fetch::object_id::ObjectId,
http_signatures::generate_actor_keypair,
kinds::actor::PersonType,
protocol::public_key::PublicKey,
traits::{Actor, Object},
};
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use tracing::trace;
use url::Url;
use crate::{error::AppError, state::AppHandle};
#[derive(PartialEq, Clone, Debug)]
pub(crate) struct User {
pub username: String,
pub ap_id: ObjectId<User>,
pub private_key: Option<String>,
pub public_key: String,
pub inbox: Url,
}
impl User {
pub fn new(username: &str) -> Result<Self, AppError> {
trace!("creating a new user");
let keys = generate_actor_keypair()?;
let stub = &format!("http://localhost/users/{username}");
Ok(Self {
username: username.to_owned(),
ap_id: Url::parse(stub)?.into(),
private_key: Some(keys.private_key),
public_key: keys.public_key,
inbox: Url::parse(&format!("{stub}/inbox"))?,
})
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Person {
#[serde(rename = "type")]
kind: PersonType,
preferred_username: String,
id: ObjectId<User>,
inbox: Url,
public_key: PublicKey,
}
#[async_trait]
impl Object for User {
#[doc = " App data type passed to handlers. Must be identical to"]
#[doc = " [crate::config::FederationConfigBuilder::app_data] type."]
type DataType = AppHandle;
#[doc = " The type of protocol struct which gets sent over network to federate this database struct."]
type Kind = Person;
#[doc = " Error type returned by handler methods"]
type Error = AppError;
#[doc = " `id` field of the object"]
fn id(&self) -> &Url {
self.ap_id.inner()
}
#[doc = " Try to read the object with given `id` from local database."]
#[doc = " Should return `Ok(None)` if not found."]
async fn read_from_id(
object_id: Url,
data: &Data<Self::DataType>,
) -> Result<Option<Self>, Self::Error> {
todo!()
}
#[doc = " Convert database type to Activitypub type."]
#[doc = " Called when a local object gets fetched by another instance over HTTP, or when an object"]
#[doc = " gets sent in an activity."]
async fn into_json(self, data: &Data<Self::DataType>) -> Result<Self::Kind, Self::Error> {
Ok(Person {
preferred_username: self.username.clone(),
kind: Default::default(),
id: self.ap_id.clone(),
inbox: self.inbox.clone(),
public_key: self.public_key(),
})
}
#[doc = " Verifies that the received object is valid."]
#[doc = " You should check here that the domain of id matches `expected_domain`. Additionally you"]
#[doc = " should perform any application specific checks."]
#[doc = " It is necessary to use a separate method for this, because it might be used for activities"]
#[doc = " like `Delete/Note`, which shouldn\'t perform any database write for the inner `Note`."]
async fn verify(
json: &Self::Kind,
expected_domain: &Url,
data: &Data<Self::DataType>,
) -> Result<(), Self::Error> {
todo!()
}
#[doc = " Convert object from ActivityPub type to database type."]
#[doc = " Called when an object is received from HTTP fetch or as part of an activity. This method"]
#[doc = " should write the received object to database. Note that there is no distinction between"]
#[doc = " create and update, so an `upsert` operation should be used."]
async fn from_json(json: Self::Kind, data: &Data<Self::DataType>) -> Result<Self, Self::Error> {
todo!()
}
}
impl Actor for User {
fn public_key_pem(&self) -> &str {
&self.public_key
}
fn private_key_pem(&self) -> Option<String> {
self.private_key.clone()
}
fn inbox(&self) -> Url {
self.inbox.clone()
}
}
|