feat(media): use authenticated endpoints when fetching remote media

This commit is contained in:
Matthias Ahouansou 2024-08-24 10:36:03 +01:00
parent 27d6d94355
commit cbd3b07ca7
No known key found for this signature in database

View file

@ -84,6 +84,31 @@ pub async fn get_remote_content(
server_name: &ServerName, server_name: &ServerName,
media_id: String, media_id: String,
) -> Result<get_content::v1::Response, Error> { ) -> Result<get_content::v1::Response, Error> {
let content_response = match services()
.sending
.send_federation_request(
server_name,
federation_media::get_content::v1::Request {
media_id: media_id.clone(),
timeout_ms: Duration::from_secs(20),
},
)
.await
{
Ok(federation_media::get_content::v1::Response {
metadata: _,
content: FileOrLocation::File(content),
}) => get_content::v1::Response {
file: content.file,
content_type: content.content_type,
content_disposition: content.content_disposition,
},
Ok(federation_media::get_content::v1::Response {
metadata: _,
content: FileOrLocation::Location(url),
}) => get_location_content(url).await?,
Err(Error::BadRequest(ErrorKind::Unrecognized, _)) => {
let media::get_content::v3::Response { let media::get_content::v3::Response {
file, file,
content_type, content_type,
@ -103,21 +128,26 @@ pub async fn get_remote_content(
) )
.await?; .await?;
get_content::v1::Response {
file,
content_type,
content_disposition,
}
}
Err(e) => return Err(e),
};
services() services()
.media .media
.create( .create(
mxc.to_owned(), mxc.to_owned(),
content_disposition.clone(), content_response.content_disposition.clone(),
content_type.as_deref(), content_response.content_type.as_deref(),
&file, &content_response.file,
) )
.await?; .await?;
Ok(get_content::v1::Response { Ok(content_response)
file,
content_type,
content_disposition,
})
} }
/// # `GET /_matrix/media/r0/download/{serverName}/{mediaId}` /// # `GET /_matrix/media/r0/download/{serverName}/{mediaId}`
@ -335,6 +365,40 @@ async fn get_content_thumbnail(
{ {
Ok(get_content_thumbnail::v1::Response { file, content_type }) Ok(get_content_thumbnail::v1::Response { file, content_type })
} else if server_name != services().globals.server_name() && allow_remote { } else if server_name != services().globals.server_name() && allow_remote {
let thumbnail_response = match services()
.sending
.send_federation_request(
server_name,
federation_media::get_content_thumbnail::v1::Request {
height,
width,
method: method.clone(),
media_id: media_id.clone(),
timeout_ms: Duration::from_secs(20),
animated,
},
)
.await
{
Ok(federation_media::get_content_thumbnail::v1::Response {
metadata: _,
content: FileOrLocation::File(content),
}) => get_content_thumbnail::v1::Response {
file: content.file,
content_type: content.content_type,
},
Ok(federation_media::get_content_thumbnail::v1::Response {
metadata: _,
content: FileOrLocation::Location(url),
}) => {
let get_content::v1::Response {
file, content_type, ..
} = get_location_content(url).await?;
get_content_thumbnail::v1::Response { file, content_type }
}
Err(Error::BadRequest(ErrorKind::Unrecognized, _)) => {
let media::get_content_thumbnail::v3::Response { let media::get_content_thumbnail::v3::Response {
file, content_type, .. file, content_type, ..
} = services() } = services()
@ -354,18 +418,24 @@ async fn get_content_thumbnail(
}, },
) )
.await?; .await?;
get_content_thumbnail::v1::Response { file, content_type }
}
Err(e) => return Err(e),
};
services() services()
.media .media
.upload_thumbnail( .upload_thumbnail(
mxc, mxc,
content_type.as_deref(), thumbnail_response.content_type.as_deref(),
width.try_into().expect("all UInts are valid u32s"), width.try_into().expect("all UInts are valid u32s"),
height.try_into().expect("all UInts are valid u32s"), height.try_into().expect("all UInts are valid u32s"),
&file, &thumbnail_response.file,
) )
.await?; .await?;
Ok(get_content_thumbnail::v1::Response { file, content_type }) Ok(thumbnail_response)
} else { } else {
Err(Error::BadRequest(ErrorKind::NotFound, "Media not found.")) Err(Error::BadRequest(ErrorKind::NotFound, "Media not found."))
} }