From da89ea22fb79bd457a5bdb76b159a4749f6d9df3 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Thu, 18 Nov 2021 19:28:53 +0100 Subject: [PATCH] Fix Smithereen webfinger, remove duplicate webfinger impl (fixes #1916) --- crates/apub/src/fetcher/webfinger.rs | 14 ++++++--- crates/apub/src/mentions.rs | 45 ++++------------------------ crates/apub/src/objects/comment.rs | 3 +- crates/routes/src/webfinger.rs | 4 +-- 4 files changed, 20 insertions(+), 46 deletions(-) diff --git a/crates/apub/src/fetcher/webfinger.rs b/crates/apub/src/fetcher/webfinger.rs index e36fbb58c..d1878d287 100644 --- a/crates/apub/src/fetcher/webfinger.rs +++ b/crates/apub/src/fetcher/webfinger.rs @@ -18,8 +18,8 @@ use url::Url; #[derive(Serialize, Deserialize, Debug)] pub struct WebfingerLink { pub rel: Option, - #[serde(rename(serialize = "type", deserialize = "type"))] - pub type_: Option, + #[serde(rename = "type")] + pub kind: Option, pub href: Option, } @@ -61,7 +61,7 @@ where /// Turns a person id like `@name@example.com` into an apub ID, like `https://example.com/user/name`, /// using webfinger. -async fn webfinger_resolve_actor( +pub(crate) async fn webfinger_resolve_actor( identifier: &str, context: &LemmyContext, request_counter: &mut i32, @@ -91,7 +91,13 @@ where let links: Vec = res .links .iter() - .filter(|l| l.type_.eq(&Some("application/activity+json".to_string()))) + .filter(|link| { + if let Some(type_) = &link.kind { + type_.starts_with("application/") + } else { + false + } + }) .map(|l| l.href.clone()) .flatten() .collect(); diff --git a/crates/apub/src/mentions.rs b/crates/apub/src/mentions.rs index 268a1693b..2cf0e757a 100644 --- a/crates/apub/src/mentions.rs +++ b/crates/apub/src/mentions.rs @@ -1,12 +1,11 @@ use crate::{ - fetcher::webfinger::WebfingerResponse, + fetcher::webfinger::webfinger_resolve_actor, objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson}, }; use activitystreams::{ base::BaseExt, link::{LinkExt, Mention}, }; -use anyhow::anyhow; use lemmy_api_common::blocking; use lemmy_apub_lib::{object_id::ObjectId, traits::ActorType}; use lemmy_db_schema::{ @@ -15,12 +14,10 @@ use lemmy_db_schema::{ DbPool, }; use lemmy_utils::{ - request::{retry, RecvError}, utils::{scrape_text_for_mentions, MentionData}, LemmyError, }; use lemmy_websocket::LemmyContext; -use log::debug; use url::Url; pub struct MentionsAndAddresses { @@ -35,6 +32,7 @@ pub async fn collect_non_local_mentions( comment: &ApubComment, community_id: ObjectId, context: &LemmyContext, + request_counter: &mut i32, ) -> Result { let parent_creator = get_comment_parent_creator(context.pool(), comment).await?; let mut addressed_ccs: Vec = vec![community_id.into(), parent_creator.actor_id()]; @@ -59,9 +57,11 @@ pub async fn collect_non_local_mentions( for mention in &mentions { // TODO should it be fetching it every time? - if let Ok(actor_id) = fetch_webfinger_url(mention, context).await { + let identifier = format!("{}@{}", mention.name, mention.domain); + let actor_id = + webfinger_resolve_actor::(&identifier, context, request_counter).await; + if let Ok(actor_id) = actor_id { let actor_id: ObjectId = ObjectId::new(actor_id); - debug!("mention actor_id: {}", actor_id); addressed_ccs.push(actor_id.to_string().parse()?); let mut mention_tag = Mention::new(); @@ -99,36 +99,3 @@ async fn get_comment_parent_creator( .into(), ) } - -/// Turns a person id like `@name@example.com` into an apub ID, like `https://example.com/user/name`, -/// using webfinger. -async fn fetch_webfinger_url( - mention: &MentionData, - context: &LemmyContext, -) -> Result { - let fetch_url = format!( - "{}://{}/.well-known/webfinger?resource=acct:{}@{}", - context.settings().get_protocol_string(), - mention.domain, - mention.name, - mention.domain - ); - debug!("Fetching webfinger url: {}", &fetch_url); - - let response = retry(|| context.client().get(&fetch_url).send()).await?; - - let res: WebfingerResponse = response - .json() - .await - .map_err(|e| RecvError(e.to_string()))?; - - let link = res - .links - .iter() - .find(|l| l.type_.eq(&Some("application/activity+json".to_string()))) - .ok_or_else(|| anyhow!("No application/activity+json link found."))?; - link - .href - .to_owned() - .ok_or_else(|| anyhow!("No href found.").into()) -} diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs index a3840e10a..f15084cc4 100644 --- a/crates/apub/src/objects/comment.rs +++ b/crates/apub/src/objects/comment.rs @@ -107,7 +107,8 @@ impl ApubObject for ApubComment { } else { ObjectId::::new(post.ap_id) }; - let maa = collect_non_local_mentions(&self, ObjectId::new(community.actor_id), context).await?; + let maa = + collect_non_local_mentions(&self, ObjectId::new(community.actor_id), context, &mut 0).await?; let note = Note { r#type: NoteType::Note, diff --git a/crates/routes/src/webfinger.rs b/crates/routes/src/webfinger.rs index 1cf54bac4..db5e662c0 100644 --- a/crates/routes/src/webfinger.rs +++ b/crates/routes/src/webfinger.rs @@ -76,12 +76,12 @@ fn webfinger_link_for_actor(url: Option) -> Vec { vec![ WebfingerLink { rel: Some("http://webfinger.net/rel/profile-page".to_string()), - type_: Some("text/html".to_string()), + kind: Some("text/html".to_string()), href: Some(url.to_owned()), }, WebfingerLink { rel: Some("self".to_string()), - type_: Some("application/activity+json".to_string()), + kind: Some("application/activity+json".to_string()), href: Some(url), }, ]