From 90d2e2d20928d06ab971090dc22ddff267e80d39 Mon Sep 17 00:00:00 2001 From: Vika Date: Sun, 18 Aug 2024 00:17:54 +0300 Subject: indieauth: fix profile fetching if some properties are undeclared --- src/indieauth/mod.rs | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'src/indieauth') diff --git a/src/indieauth/mod.rs b/src/indieauth/mod.rs index 9f35ed0..808b9b7 100644 --- a/src/indieauth/mod.rs +++ b/src/indieauth/mod.rs @@ -719,33 +719,37 @@ async fn revocation_endpoint_post( } } +#[tracing::instrument(skip(db))] async fn get_profile( db: D, url: &str, email: bool ) -> crate::database::Result> { + fn get_first(v: serde_json::Value) -> Option { + match v { + serde_json::Value::Array(mut a) => { + a.truncate(1); + match a.pop() { + Some(serde_json::Value::String(s)) => Some(s), + Some(serde_json::Value::Object(mut o)) => o.remove("value").and_then(get_first), + _ => None + } + }, + _ => None + } + } + Ok(db.get_post(url).await?.map(|mut mf2| { // Ruthlessly manually destructure the MF2 document to save memory - let name = match mf2["properties"]["name"][0].take() { - serde_json::Value::String(s) => Some(s), - _ => None - }; - let url = match mf2["properties"]["uid"][0].take() { - serde_json::Value::String(s) => s.parse().ok(), - _ => None - }; - let photo = match mf2["properties"]["photo"][0].take() { - serde_json::Value::String(s) => s.parse().ok(), - _ => None - }; - let email = if email { - match mf2["properties"]["email"][0].take() { - serde_json::Value::String(s) => Some(s), - _ => None - } - } else { - None + let mut properties = match mf2.as_object_mut().unwrap().remove("properties") { + Some(serde_json::Value::Object(props)) => props, + _ => unreachable!() }; + drop(mf2); + let name = properties.remove("name").and_then(get_first); + let url = properties.remove("uid").and_then(get_first).and_then(|u| u.parse().ok()); + let photo = properties.remove("photo").and_then(get_first).and_then(|u| u.parse().ok()); + let email = properties.remove("name").and_then(get_first); Profile { name, url, photo, email } })) -- cgit 1.4.1