Allow fetching from local domain in case it redirects to remote

This commit is contained in:
Felix Ableitner 2024-04-08 14:49:01 +02:00
parent 1b46dd6f80
commit 2cd31014b3
4 changed files with 9 additions and 13 deletions

View file

@ -19,7 +19,6 @@ use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
use reqwest_middleware::ClientWithMiddleware;
use serde::Serialize;
use std::{
self,
fmt::{Debug, Display},
time::{Duration, SystemTime},
};
@ -214,7 +213,6 @@ pub(crate) fn generate_request_headers(inbox_url: &Url) -> HeaderMap {
mod tests {
use super::*;
use crate::{config::FederationConfig, http_signatures::generate_actor_keypair};
use bytes::Bytes;
use http::StatusCode;
use std::{
sync::{atomic::AtomicUsize, Arc},

View file

@ -69,10 +69,11 @@ pub async fn fetch_object_http<T: Clone, Kind: DeserializeOwned>(
return Err(Error::FetchInvalidContentType(res.url));
}
// Ensure id field matches final url
// Ensure id field matches final url after redirect
if res.object_id.as_ref() != Some(&res.url) {
return Err(Error::FetchWrongId(res.url));
}
Ok(res)
}
@ -84,8 +85,6 @@ async fn fetch_object_http_with_accept<T: Clone, Kind: DeserializeOwned>(
content_type: &HeaderValue,
) -> Result<FetchObjectResponse<Kind>, Error> {
let config = &data.config;
// dont fetch local objects this way
debug_assert!(url.domain() != Some(&config.domain));
config.verify_url_valid(url).await?;
info!("Fetching remote object {}", url.to_string());
@ -125,6 +124,12 @@ async fn fetch_object_http_with_accept<T: Clone, Kind: DeserializeOwned>(
let text = res.bytes_limited().await?;
let object_id = extract_id(&text).ok();
// Dont allow fetching local object. Only check this after the request as a local url
// may redirect to a remote object.
if data.config.is_local_url(&url) {
return Err(Error::NotFound.into());
}
match serde_json::from_slice(&text) {
Ok(object) => Ok(FetchObjectResponse {
object,

View file

@ -88,13 +88,6 @@ where
<Kind as Object>::Error: From<Error>,
{
let db_object = self.dereference_from_db(data).await?;
// if its a local object, only fetch it from the database and not over http
if data.config.is_local_url(&self.0) {
return match db_object {
None => Err(Error::NotFound.into()),
Some(o) => Ok(o),
};
}
// object found in database
if let Some(object) = db_object {

View file

@ -343,7 +343,7 @@ pub mod tests {
error::Error,
fetch::object_id::ObjectId,
http_signatures::{generate_actor_keypair, Keypair},
protocol::{public_key::PublicKey, verification::verify_domains_match},
protocol::verification::verify_domains_match,
};
use activitystreams_kinds::{activity::FollowType, actor::PersonType};
use once_cell::sync::Lazy;