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
use crate::database::Database;
use crate::snowflake;
use actix_web::http::Uri;
use actix_web::{web, HttpResponse};
use serde::{Deserialize, Serialize};
pub mod activity_json;
pub mod users;
pub mod webfinger;
#[derive(Clone)]
pub struct CanonicalServerUrl(pub String);
impl CanonicalServerUrl {
pub fn host(&self) -> &str {
self.0.split_once("://").unwrap().1
}
}
pub fn actor_id(base_url: &CanonicalServerUrl, username: &str) -> String {
format!("{}/u/{username}", base_url.0)
}
pub fn activity_id(actor_id: &str) -> String {
let id = snowflake::generate_snowflake();
format!("{actor_id}/activities/{id}")
}
pub fn note_id(actor_id: &str) -> String {
let id = snowflake::generate_snowflake();
format!("{actor_id}/notes/{id}")
}
pub fn collection_page_id(collection_id: &str, page: u32) -> String {
format!("{collection_id}?page={page}")
}
#[derive(Serialize, Deserialize)]
pub struct ApRetrievalParams {
page: Option<u32>,
}
pub async fn get_ap_object(
uri: Uri,
db: web::Data<&'static Database>,
server_url: web::Data<CanonicalServerUrl>,
query: web::Query<ApRetrievalParams>,
) -> HttpResponse {
if let Some(path_and_query) = uri.path_and_query() {
tracing::trace!("Looking up: {}{}", server_url.0, path_and_query);
}
let id = format!("{}{}", server_url.0, uri.path());
match db.get_object(&id, query.page).await {
Ok(Some(obj)) => activity_json::response(obj),
Ok(None) => HttpResponse::NotFound().finish(),
Err(err) => {
tracing::error!("Failed to get activitypub object from db: {err}");
HttpResponse::ServiceUnavailable().finish()
}
}
}