Fix webfinger fetching non-compliance (#69)

Allow webfinger to use "jrd+json" instead of "activity+json".
Fix #68.
This commit is contained in:
Samuel Tardieu 2023-07-18 22:17:21 +02:00 committed by GitHub
parent 988450c79f
commit 02ab897f4f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 3 deletions

View file

@ -33,9 +33,21 @@ pub mod webfinger;
/// If the value exceeds [FederationSettings.http_fetch_limit], the request is aborted with
/// [Error::RequestLimit]. This prevents denial of service attacks where an attack triggers
/// infinite, recursive fetching of data.
///
/// The `Accept` header will be set to the content of [`FEDERATION_CONTENT_TYPE`].
pub async fn fetch_object_http<T: Clone, Kind: DeserializeOwned>(
url: &Url,
data: &Data<T>,
) -> Result<Kind, Error> {
fetch_object_http_with_accept(url, data, FEDERATION_CONTENT_TYPE).await
}
/// Fetch a remote object over HTTP and convert to `Kind`. This function works exactly as
/// [`fetch_object_http`] except that the `Accept` header is specified in `content_type`.
async fn fetch_object_http_with_accept<T: Clone, Kind: DeserializeOwned>(
url: &Url,
data: &Data<T>,
content_type: &str,
) -> Result<Kind, Error> {
let config = &data.config;
// dont fetch local objects this way
@ -51,7 +63,7 @@ pub async fn fetch_object_http<T: Clone, Kind: DeserializeOwned>(
let req = config
.client
.get(url.as_str())
.header("Accept", FEDERATION_CONTENT_TYPE)
.header("Accept", content_type)
.timeout(config.request_timeout);
let res = if let Some((actor_id, private_key_pem)) = config.signed_fetch_actor.as_deref() {

View file

@ -1,7 +1,7 @@
use crate::{
config::Data,
error::{Error, Error::WebfingerResolveFailed},
fetch::{fetch_object_http, object_id::ObjectId},
fetch::{fetch_object_http_with_accept, object_id::ObjectId},
traits::{Actor, Object},
FEDERATION_CONTENT_TYPE,
};
@ -36,7 +36,9 @@ where
format!("{protocol}://{domain}/.well-known/webfinger?resource=acct:{identifier}");
debug!("Fetching webfinger url: {}", &fetch_url);
let res: Webfinger = fetch_object_http(&Url::parse(&fetch_url)?, data).await?;
let res: Webfinger =
fetch_object_http_with_accept(&Url::parse(&fetch_url)?, data, "application/jrd+json")
.await?;
debug_assert_eq!(res.subject, format!("acct:{identifier}"));
let links: Vec<Url> = res
@ -231,5 +233,8 @@ mod tests {
webfinger_resolve_actor::<DbConnection, DbUser>("LemmyDev@mastodon.social", &data)
.await;
assert!(res.is_ok());
// poa.st is as of 2023-07-14 the largest Pleroma instance
let res = webfinger_resolve_actor::<DbConnection, DbUser>("graf@poa.st", &data).await;
assert!(res.is_ok());
}
}