use activitypub_federation::{ config::Data, fetch::webfinger::{build_webfinger_response, extract_webfinger_name}, }; use axum::{Json, extract::Query, http::StatusCode, response::IntoResponse}; use serde::Deserialize; use crate::{error::AppError, server::routes::users::get_user::read_user, state::AppHandle}; #[derive(Deserialize)] pub struct WebfingerQuery { resource: String, } pub async fn webfinger( Query(query): Query, data: Data, ) -> Result { let name = extract_webfinger_name(&query.resource, &data)?; if let Some(db_user) = read_user(name, &data).await { Ok(( StatusCode::OK, Json(build_webfinger_response( query.resource, db_user.ap_id.into_inner(), )), ) .into_response()) } else { Ok((StatusCode::NOT_FOUND, "").into_response()) } } #[cfg(test)] mod tests { use axum::{ body::Body, http::{Request, StatusCode}, }; use tower::ServiceExt; use crate::{server, state::AppState}; #[tokio::test] async fn webfinger_ok() { let state = AppState::new().await.unwrap(); let app = server::router(state); let response = app .oneshot( Request::builder() .uri("/.well-known/webfinger?resource=acct:sellershut@localhost") .body(Body::empty()) .unwrap(), ) .await .unwrap(); assert_eq!(response.status(), StatusCode::OK); } #[tokio::test] async fn webfinger_err() { let state = AppState::new().await.unwrap(); let app = server::router(state); let response = app .oneshot( Request::builder() .uri("/.well-known/webfinger?resource=acct:sst@localhost") .body(Body::empty()) .unwrap(), ) .await .unwrap(); assert_eq!(response.status(), StatusCode::NOT_FOUND); } }