diff options
author | Vika <vika@fireburn.ru> | 2024-08-18 00:17:54 +0300 |
---|---|---|
committer | Vika <vika@fireburn.ru> | 2024-08-18 00:27:53 +0300 |
commit | 90d2e2d20928d06ab971090dc22ddff267e80d39 (patch) | |
tree | c21a11d6d1b4285628ac6534e3f613888c4ab743 /src/indieauth | |
parent | 1bf23d1c2dd6e85c677392a83a67a581c218cc11 (diff) | |
download | kittybox-90d2e2d20928d06ab971090dc22ddff267e80d39.tar.zst |
indieauth: fix profile fetching if some properties are undeclared
Diffstat (limited to 'src/indieauth')
-rw-r--r-- | src/indieauth/mod.rs | 42 |
1 files changed, 23 insertions, 19 deletions
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<A: AuthBackend>( } } +#[tracing::instrument(skip(db))] async fn get_profile<D: Storage + 'static>( db: D, url: &str, email: bool ) -> crate::database::Result<Option<Profile>> { + fn get_first(v: serde_json::Value) -> Option<String> { + 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 } })) |