2022-12-10 18:15:32 +00:00
|
|
|
mod actor;
|
|
|
|
pub mod articles;
|
|
|
|
mod comments;
|
|
|
|
mod db;
|
|
|
|
pub mod digester;
|
|
|
|
pub mod federate;
|
|
|
|
mod inbox;
|
2023-01-03 19:25:26 +00:00
|
|
|
pub mod keys;
|
2022-12-10 18:15:32 +00:00
|
|
|
mod types;
|
|
|
|
mod util;
|
|
|
|
mod webfinger;
|
|
|
|
|
|
|
|
use self::types::ActorExt;
|
|
|
|
use activitystreams::{base::AnyBase, prelude::BaseExt};
|
|
|
|
use anyhow::anyhow;
|
|
|
|
use axum::{
|
|
|
|
routing::{get, post, Router},
|
|
|
|
Extension,
|
|
|
|
};
|
|
|
|
use log::warn;
|
|
|
|
use once_cell::sync::Lazy;
|
|
|
|
use reqwest::{Client, ClientBuilder};
|
|
|
|
use sqlx::SqlitePool;
|
|
|
|
use uuid::Uuid;
|
|
|
|
|
|
|
|
pub static DOMAIN: Lazy<String> =
|
|
|
|
Lazy::new(|| std::env::var("DOMAIN").unwrap_or("shadowfacts.net".to_owned()));
|
|
|
|
|
|
|
|
pub fn router(pool: SqlitePool) -> Router {
|
|
|
|
Router::new()
|
|
|
|
.route("/.well-known/webfinger", get(webfinger::handle))
|
|
|
|
.route("/ap/actor", get(actor::handle))
|
|
|
|
.route("/ap/actor/followers", get(actor::handle_followers))
|
|
|
|
.layer(Extension(pool))
|
|
|
|
.route("/ap/inbox", post(inbox::handle))
|
|
|
|
.route("/comments", get(comments::handle))
|
|
|
|
.route("/interact", post(webfinger::handle_interact))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn gen_ap_id() -> String {
|
|
|
|
format!("https://{}/ap/{}", *DOMAIN, Uuid::new_v4())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn gen_converation_id() -> String {
|
|
|
|
format!("https://{}/ap/conversation/{}", *DOMAIN, Uuid::new_v4())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn conversation_context() -> AnyBase {
|
|
|
|
AnyBase::from_arbitrary_json(serde_json::json!({
|
|
|
|
"ostatus": "http://ostatus.org#",
|
|
|
|
"conversation": "ostatus:conversation"
|
|
|
|
}))
|
|
|
|
.unwrap()
|
|
|
|
}
|
|
|
|
|
|
|
|
const ACCEPT_INVALID_CERTS: bool = !cfg!(release);
|
|
|
|
pub static CLIENT: Lazy<Client> = Lazy::new(|| {
|
|
|
|
if ACCEPT_INVALID_CERTS {
|
|
|
|
warn!("Accepting invalid certs for ActivityPub request");
|
|
|
|
}
|
|
|
|
|
|
|
|
ClientBuilder::new()
|
|
|
|
.danger_accept_invalid_certs(ACCEPT_INVALID_CERTS)
|
|
|
|
.build()
|
|
|
|
.expect("couldn't build reqwest client")
|
|
|
|
});
|
|
|
|
|
|
|
|
pub async fn get_actor(id: &str, pool: &SqlitePool) -> anyhow::Result<ActorExt> {
|
|
|
|
if let Some(actor) = db::fetch_cached_actor(id, pool).await {
|
|
|
|
let actor = serde_json::from_str::<ActorExt>(&actor.actor_object)?;
|
|
|
|
Ok(actor)
|
|
|
|
} else {
|
|
|
|
fetch_actor(id, pool).await
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn fetch_actor(id: &str, pool: &SqlitePool) -> anyhow::Result<ActorExt> {
|
|
|
|
let actor = federate::fetch_actor(id).await?;
|
|
|
|
if actor.id_unchecked().unwrap().as_str() != id {
|
|
|
|
return Err(anyhow!("got mismatched id for actor at {}", id));
|
|
|
|
}
|
|
|
|
db::add_cached_actor(&actor, pool).await?;
|
|
|
|
Ok(actor)
|
|
|
|
}
|