v6/src/activitypub/mod.rs

85 lines
2.3 KiB
Rust

mod actor;
pub mod articles;
mod comments;
mod db;
pub mod digester;
pub mod federate;
mod inbox;
pub mod keys;
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!(debug_assertions);
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)
}