Test implementation for webfinger and /users/{user} actor

main
Avery 7 days ago
commit 6d41858e92
Signed by: Avery
GPG Key ID: 4E53F4CB69B2CC8D

1
.gitignore vendored

@ -0,0 +1 @@
/target

1186
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,12 @@
[package]
name = "rust_fedi"
version = "0.1.0"
edition = "2024"
[dependencies]
axum = "0.8.3"
env_logger = "0.11.8"
rsa = "0.9.8"
serde = { version = "1.0.219", features = ["derive"] }
sha2 = "0.10.8"
tokio = { version = "1.44.2", features = ["full"] }

@ -0,0 +1,26 @@
mod users;
mod webfinger;
use axum::{Router, routing::get};
use users::users_get;
use webfinger::webfinger_get;
const HOST: &'static str = "testhost.com";
const USER: &'static str = "test";
#[tokio::main]
async fn main() {
env_logger::init();
let app = Router::new()
.route("/", get(root))
.route("/.well_know/webfinger", get(webfinger_get))
.route("/users/{users}", get(users_get));
let listener = tokio::net::TcpListener::bind("0.0.0.0:8000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
async fn root() -> &'static str {
"Hello World!"
}

@ -0,0 +1,31 @@
use axum::{Json, extract::Path};
use serde::{Deserialize, Serialize};
use crate::USER;
// {
// "@context": "https://www.w3.org/ns/activitystreams",
// "type": "Person",
// "name": "Sally Smith",
// "id": "https://testhost.com/users/test"
// }
#[derive(Serialize)]
pub struct UsersResponse {
#[serde(rename = "@context")]
context: String,
r#type: String,
name: String,
id: String,
}
pub async fn users_get(Path(user): Path<String>) -> Json<UsersResponse> {
assert_eq!(user, USER);
Json(UsersResponse {
context: "https://www.w3.org/ns/activitystreams".to_string(),
r#type: "Person".to_string(),
name: "Sally Smith".to_string(),
id: "https://testhost.com/users/test".to_string(),
})
}

@ -0,0 +1,46 @@
use axum::{Json, extract::Query};
use serde::{Deserialize, Serialize};
use crate::{HOST, USER};
#[derive(Deserialize)]
pub struct WebfingerQuery {
resource: String,
}
#[derive(Serialize)]
pub struct WebfingerResponse {
subject: String,
alias: Vec<String>,
links: Vec<WebfigerLink>,
}
#[derive(Serialize)]
pub struct WebfigerLink {
rel: String,
r#type: String,
href: String,
}
pub async fn webfinger_get(
Query(WebfingerQuery { resource }): Query<WebfingerQuery>,
) -> Json<WebfingerResponse> {
let Some((typ, val)) = resource.split_once(':') else {
panic!()
};
assert_eq!(typ, "acct");
let Some((usr, dom)) = val.split_once('@') else {
panic!()
};
assert_eq!(usr, USER);
assert_eq!(dom, HOST);
Json(WebfingerResponse {
subject: format!("acct:{USER}@{HOST}"),
alias: vec![format!("https://{HOST}/users/{USER}")],
links: vec![WebfigerLink {
rel: "self".to_string(),
r#type: "application/activity+json".to_string(),
href: format!("https://{HOST}/users/{USER}"),
}],
})
}
Loading…
Cancel
Save