activitypub-federation-rust/examples/local_federation/axum/http.rs

87 lines
2.3 KiB
Rust
Raw Normal View History

use crate::{
error::Error,
instance::DatabaseHandle,
objects::person::{DbUser, Person, PersonAcceptedActivities},
};
use activitypub_federation::{
2023-03-06 06:47:34 +05:30
axum::{
inbox::{receive_activity, ActivityData},
json::ApubJson,
},
2023-03-02 04:49:10 +05:30
config::{ApubMiddleware, FederationConfig, RequestData},
2023-03-06 06:47:34 +05:30
fetch::webfinger::{build_webfinger_response, extract_webfinger_name, Webfinger},
protocol::context::WithContext,
traits::ApubObject,
};
use axum::{
2023-03-02 04:49:10 +05:30
extract::{Path, Query},
response::IntoResponse,
routing::{get, post},
2023-03-02 04:49:10 +05:30
Json,
Router,
};
2023-03-02 04:49:10 +05:30
use axum_macros::debug_handler;
use serde::Deserialize;
use std::net::ToSocketAddrs;
2023-03-02 19:48:06 +05:30
use tracing::info;
2023-03-02 04:49:10 +05:30
pub fn listen(config: &FederationConfig<DatabaseHandle>) -> Result<(), Error> {
2023-03-08 03:31:36 +05:30
let hostname = config.domain();
2023-03-02 19:48:06 +05:30
info!("Listening with axum on {hostname}");
2023-03-02 04:49:10 +05:30
let config = config.clone();
let app = Router::new()
.route("/:user/inbox", post(http_post_user_inbox))
.route("/:user", get(http_get_user))
2023-03-02 04:49:10 +05:30
.route("/.well-known/webfinger", get(webfinger))
.layer(ApubMiddleware::new(config));
let addr = hostname
.to_socket_addrs()?
.next()
.expect("Failed to lookup domain name");
let server = axum::Server::bind(&addr).serve(app.into_make_service());
actix_rt::spawn(server);
Ok(())
}
2023-03-02 04:49:10 +05:30
#[debug_handler]
async fn http_get_user(
2023-03-02 04:49:10 +05:30
Path(name): Path<String>,
data: RequestData<DatabaseHandle>,
) -> Result<ApubJson<WithContext<Person>>, Error> {
2023-03-02 04:49:10 +05:30
let db_user = data.read_user(&name)?;
let apub_user = db_user.into_apub(&data).await?;
Ok(ApubJson(WithContext::new_default(apub_user)))
}
2023-03-02 04:49:10 +05:30
#[debug_handler]
async fn http_post_user_inbox(
data: RequestData<DatabaseHandle>,
activity_data: ActivityData,
) -> impl IntoResponse {
receive_activity::<WithContext<PersonAcceptedActivities>, DbUser, DatabaseHandle>(
activity_data,
&data,
)
.await
}
2023-03-02 04:49:10 +05:30
#[derive(Deserialize)]
struct WebfingerQuery {
resource: String,
}
#[debug_handler]
async fn webfinger(
Query(query): Query<WebfingerQuery>,
data: RequestData<DatabaseHandle>,
) -> Result<Json<Webfinger>, Error> {
let name = extract_webfinger_name(&query.resource, &data)?;
let db_user = data.read_user(&name)?;
Ok(Json(build_webfinger_response(
query.resource,
db_user.ap_id.into_inner(),
)))
}