diff --git a/acrate-webfinger/Cargo.toml b/acrate-webfinger/Cargo.toml index 5bb8042..cfd73d0 100644 --- a/acrate-webfinger/Cargo.toml +++ b/acrate-webfinger/Cargo.toml @@ -11,6 +11,7 @@ axum = { version = "0.7.7", features = ["macros"] } axum-extra = { version = "0.9.4", features = ["query"] } log = "0.4.22" micronfig = "0.3.0" +minijinja = "2.5.0" pretty_env_logger = "0.5.0" quick-xml = { version = "0.37.0", features = ["serialize"] } serde = { version = "1.0.215", features = ["derive"] } diff --git a/acrate-webfinger/src/main.rs b/acrate-webfinger/src/main.rs index de425ea..7b248b0 100644 --- a/acrate-webfinger/src/main.rs +++ b/acrate-webfinger/src/main.rs @@ -1,4 +1,6 @@ +use std::sync::Arc; use anyhow::Context; +use axum::Extension; mod config; mod route; @@ -8,10 +10,18 @@ mod route; async fn main() -> anyhow::Result { pretty_env_logger::init(); log::debug!("Logging initialized!"); + + log::trace!("Creating Minijinja environment..."); + let mut mj = minijinja::Environment::<'static>::new(); + + log::trace!("Adding webfinger page to the Minijinja environment..."); + mj.add_template("webfinger.html.j2", include_str!("webfinger.html.j2")) + .expect("webfinger.html.j2 to be a valid Minijinja template"); log::trace!("Creating Axum router..."); let app = axum::Router::new() - .route("/.well-known/webfinger", axum::routing::get(route::webfinger_handler)); + .route("/.well-known/webfinger", axum::routing::get(route::webfinger_handler)) + .layer(Extension(Arc::new(mj))); log::trace!("Axum router created successfully!"); log::trace!("Creating Tokio listener..."); diff --git a/acrate-webfinger/src/route.rs b/acrate-webfinger/src/route.rs index b59780a..1ae9cef 100644 --- a/acrate-webfinger/src/route.rs +++ b/acrate-webfinger/src/route.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; +use axum::Extension; use axum::http::{HeaderMap, Response, StatusCode}; use axum_extra::extract::Query; use serde::Deserialize; @@ -22,6 +24,7 @@ const WEBFINGER_DOC: &str = "/.well-known/webfinger"; pub async fn webfinger_handler( Query(WebfingerQuery {resource, rel}): Query, headers: HeaderMap, + Extension(mj): Extension>>, ) -> Result, StatusCode> { log::info!("Handling a WebFinger request!"); @@ -142,7 +145,7 @@ pub async fn webfinger_handler( body.push_str(&json); } - return Ok(response) + return Ok(response); }, "application/xml" | "application/xrd+xml" => { let subject = Some(resource); @@ -196,15 +199,63 @@ pub async fn webfinger_handler( { let body = response.body_mut(); - body.push_str(""); + body.push_str(r#""#); body.push_str(&xml); } - return Ok(response) + return Ok(response); + }, + "text/html" => { + let aliases: Vec = aliases.into_iter() + .map(|alias| alias.alias) + .collect(); + + let properties: Vec<(String, Option)> = properties.into_iter() + .map(|prop| { + (prop.rel, prop.value) + }) + .collect(); + + let links: Vec<(String, Option, Option, Option, Vec<(String, Option)>, Vec<(String, String)>)> = links_full + .into_iter() + .map(|(link, properties, titles)| { + ( + link.rel, + link.type_, + link.href, + link.template, + properties.into_iter() + .map(|prop| (prop.rel, prop.value)) + .collect::)>>(), + titles.into_iter() + .map(|title| (title.language, title.value)) + .collect::>() + ) + }) + .collect(); + + let html = mj.get_template("webfinger.html.j2") + .expect("webfinger.html.j2 to exist") + .render( + minijinja::context!( + subject => resource, + aliases => aliases, + properties => properties, + links => links, + ) + ) + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + { + let body = response.body_mut(); + body.push_str(&html); + } + + return Ok(response); }, _ => { continue; - } + }, } } diff --git a/acrate-webfinger/src/webfinger.html.j2 b/acrate-webfinger/src/webfinger.html.j2 new file mode 100644 index 0000000..1bb22ce --- /dev/null +++ b/acrate-webfinger/src/webfinger.html.j2 @@ -0,0 +1,98 @@ + + + + {{ subject }} ยท Acrate Webfinger + + +

+ Acrate Webfinger +

+

+ {{ subject }} +

+ {% if aliases %} +
+

+ Aliases +

+
    + {% for alias in aliases %} +
  • {{ alias }}
  • + {% endfor %} +
+
+ {% endif %} + {% if properties %} +
+

+ Properties +

+
+ {% for property in properties %} +
+ {{ property[0] }} +
+
+ {{ property[1] }} +
+ {% endfor %} +
+
+ {% endif %} + {% if links %} + + {% endif %} +