commit
6d41858e92
@ -0,0 +1 @@
|
|||||||
|
/target
|
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…
Reference in new issue