From d80888c9db55cd1d948889532019b2ae4ed1a977 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sat, 16 Nov 2024 02:58:45 +0100 Subject: [PATCH] `webfinger`: Add link properties and titles --- acrate-webfinger/src/route.rs | 80 ++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 16 deletions(-) diff --git a/acrate-webfinger/src/route.rs b/acrate-webfinger/src/route.rs index 4018ae0..b59780a 100644 --- a/acrate-webfinger/src/route.rs +++ b/acrate-webfinger/src/route.rs @@ -1,9 +1,11 @@ use axum::http::{HeaderMap, Response, StatusCode}; use axum_extra::extract::Query; use serde::Deserialize; +use acrate_core::diesel::GroupedBy; use acrate_core::diesel_async::{AsyncConnection, AsyncPgConnection}; +use acrate_core::meta::{MetaAlias, MetaLink, MetaLinkProperty, MetaLinkTitle, MetaProperty}; use acrate_hostmeta::jrd::ResourceDescriptorLinkJRD; -use acrate_hostmeta::xrd::{ResourceDescriptorLinkXRD, ResourceDescriptorPropertyXRD}; +use acrate_hostmeta::xrd::{ResourceDescriptorLinkXRD, ResourceDescriptorPropertyXRD, ResourceDescriptorTitleXRD}; use crate::config; #[derive(Debug, Clone, Deserialize)] @@ -42,22 +44,50 @@ pub async fn webfinger_handler( .await .map_err(|_| StatusCode::BAD_GATEWAY)?; - let aliases = acrate_core::meta::MetaAlias::query_matching(&mut conn, WEBFINGER_DOC, &resource) + let aliases = MetaAlias::query_matching(&mut conn, WEBFINGER_DOC, &resource) .await .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - let properties = acrate_core::meta::MetaProperty::query_matching(&mut conn, WEBFINGER_DOC, &resource) + let properties = MetaProperty::query_matching(&mut conn, WEBFINGER_DOC, &resource) .await .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - let links = acrate_core::meta::MetaLink::query_matching(&mut conn, WEBFINGER_DOC, &resource) + let links = MetaLink::query_matching(&mut conn, WEBFINGER_DOC, &resource) .await .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + let link_properties = MetaLinkProperty::query_by_link(&mut conn, &links) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? + .grouped_by(&links); + + let link_titles = MetaLinkTitle::query_by_link(&mut conn, &links) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? + .grouped_by(&links); + + let links_full: Vec<(MetaLink, Vec, Vec)> = links + .into_iter() + .zip(link_properties) + .zip(link_titles) + .map(|((link, properties), titles)| (link, properties, titles)) + .collect(); + + { + let headers = response.headers_mut(); + headers.insert( + "Access-Control-Allow-Origin", + "*".parse().unwrap() + ); + } + for mime in accept.split(",") { { let headers = response.headers_mut(); - headers.insert("Content-Type", mime.parse().unwrap()); + headers.insert( + "Content-Type", + mime.parse().map_err(|_| StatusCode::BAD_REQUEST)? + ); } let (mime, _params) = match mime.trim().split_once(";") { @@ -79,15 +109,21 @@ pub async fn webfinger_handler( .map(|prop| (prop.rel, prop.value)) .collect(); - let links = links + let links = links_full .into_iter() - .map(|link| ResourceDescriptorLinkJRD { + .map(|(link, properties, titles)| ResourceDescriptorLinkJRD { rel: link.rel, r#type: link.type_, href: link.href, - titles: Default::default(), // TODO: Titles - properties: Default::default(), // TODO: Link properties - template: None, // TODO: Template + template: link.template, + properties: properties + .into_iter() + .map(|property| (property.rel, property.value)) + .collect(), + titles: titles + .into_iter() + .map(|title| (title.language, title.value)) + .collect(), }) .collect::>(); @@ -116,7 +152,7 @@ pub async fn webfinger_handler( .map(|alias| alias.alias) .collect(); - let properties = properties + let properties: Vec = properties .into_iter() .map(|prop| ResourceDescriptorPropertyXRD { rel: prop.rel, @@ -124,15 +160,27 @@ pub async fn webfinger_handler( }) .collect(); - let links = links + let links = links_full .into_iter() - .map(|link| ResourceDescriptorLinkXRD { + .map(|(link, properties, titles)| ResourceDescriptorLinkXRD { rel: link.rel, r#type: link.type_, href: link.href, - titles: Default::default(), // TODO: Titles - properties: Default::default(), // TODO: Link properties - template: None, // TODO: Template + template: link.template, + properties: properties + .into_iter() + .map(|property| ResourceDescriptorPropertyXRD { + rel: property.rel, + value: property.value, + }) + .collect(), + titles: titles + .into_iter() + .map(|title| ResourceDescriptorTitleXRD { + language: title.language, + value: title.value, + }) + .collect(), }) .collect::>();