From 66a14ac8027e1a00cc23473b178b7e0ba43067ee Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Sun, 23 Mar 2025 15:57:17 +0000 Subject: [PATCH] feat: freeze unauthenticated media --- src/api/client_server/media.rs | 31 ++++++++++++++++++++++++++----- src/api/server_server.rs | 3 ++- src/service/media/mod.rs | 34 +++++++++++++++++++++++++++++----- 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/src/api/client_server/media.rs b/src/api/client_server/media.rs index 29e4592f..70e35668 100644 --- a/src/api/client_server/media.rs +++ b/src/api/client_server/media.rs @@ -166,7 +166,13 @@ pub async fn get_content_route( file, content_disposition, content_type, - } = get_content(&body.server_name, body.media_id.clone(), body.allow_remote).await?; + } = get_content( + &body.server_name, + body.media_id.clone(), + body.allow_remote, + false, + ) + .await?; Ok(media::get_content::v3::Response { file, @@ -182,19 +188,23 @@ pub async fn get_content_route( pub async fn get_content_auth_route( body: Ruma, ) -> Result { - get_content(&body.server_name, body.media_id.clone(), true).await + get_content(&body.server_name, body.media_id.clone(), true, true).await } async fn get_content( server_name: &ServerName, media_id: String, allow_remote: bool, + authenticated: bool, ) -> Result { if let Ok(Some(FileMeta { content_disposition, content_type, file, - })) = services().media.get(server_name, &media_id).await + })) = services() + .media + .get(server_name, &media_id, authenticated) + .await { Ok(get_content::v1::Response { file, @@ -231,6 +241,7 @@ pub async fn get_content_as_filename_route( body.media_id.clone(), body.filename.clone(), body.allow_remote, + false, ) .await?; @@ -253,6 +264,7 @@ pub async fn get_content_as_filename_auth_route( body.media_id.clone(), body.filename.clone(), true, + true, ) .await } @@ -262,10 +274,14 @@ async fn get_content_as_filename( media_id: String, filename: String, allow_remote: bool, + authenticated: bool, ) -> Result { if let Ok(Some(FileMeta { file, content_type, .. - })) = services().media.get(server_name, &media_id).await + })) = services() + .media + .get(server_name, &media_id, authenticated) + .await { Ok(get_content_as_filename::v1::Response { file, @@ -311,6 +327,7 @@ pub async fn get_content_thumbnail_route( body.method.clone(), body.animated, body.allow_remote, + false, ) .await?; @@ -336,10 +353,12 @@ pub async fn get_content_thumbnail_auth_route( body.method.clone(), body.animated, true, + true, ) .await } +#[allow(clippy::too_many_arguments)] async fn get_content_thumbnail( server_name: &ServerName, media_id: String, @@ -348,6 +367,7 @@ async fn get_content_thumbnail( method: Option, animated: Option, allow_remote: bool, + authenticated: bool, ) -> Result { if let Some(FileMeta { file, @@ -364,6 +384,7 @@ async fn get_content_thumbnail( height .try_into() .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Height is invalid."))?, + authenticated, ) .await? { @@ -372,7 +393,7 @@ async fn get_content_thumbnail( content_type, content_disposition: Some(content_disposition), }) - } else if server_name != services().globals.server_name() && allow_remote { + } else if server_name != services().globals.server_name() && allow_remote && authenticated { let thumbnail_response = match services() .sending .send_federation_request( diff --git a/src/api/server_server.rs b/src/api/server_server.rs index 01ec47d3..3f780ebd 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -2227,7 +2227,7 @@ pub async fn get_content_route( file, }) = services() .media - .get(services().globals.server_name(), &body.media_id) + .get(services().globals.server_name(), &body.media_id, true) .await? { Ok(get_content::v1::Response::new( @@ -2264,6 +2264,7 @@ pub async fn get_content_thumbnail_route( body.height .try_into() .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Width is invalid."))?, + true, ) .await? else { diff --git a/src/service/media/mod.rs b/src/service/media/mod.rs index 7fe21cc3..81d66210 100644 --- a/src/service/media/mod.rs +++ b/src/service/media/mod.rs @@ -87,14 +87,23 @@ impl Service { } /// Fetches a local file and it's metadata - pub async fn get(&self, servername: &ServerName, media_id: &str) -> Result> { + pub async fn get( + &self, + servername: &ServerName, + media_id: &str, + authenticated: bool, + ) -> Result> { let DbFileMeta { sha256_digest, filename, content_type, - unauthenticated_access_permitted: _, + unauthenticated_access_permitted, } = self.db.search_file_metadata(servername, media_id)?; + if !(authenticated || unauthenticated_access_permitted) { + return Ok(None); + } + let file = get_file(&hex::encode(sha256_digest)).await?; Ok(Some(FileMeta { @@ -133,17 +142,22 @@ impl Service { media_id: &str, width: u32, height: u32, + authenticated: bool, ) -> Result> { if let Some((width, height, crop)) = self.thumbnail_properties(width, height) { if let Ok(DbFileMeta { sha256_digest, filename, content_type, - unauthenticated_access_permitted: _, + unauthenticated_access_permitted, }) = self .db .search_thumbnail_metadata(servername, media_id, width, height) { + if !(authenticated || unauthenticated_access_permitted) { + return Ok(None); + } + // Using saved thumbnail let file = get_file(&hex::encode(sha256_digest)).await?; @@ -152,13 +166,19 @@ impl Service { content_type, file, })) + } else if !authenticated { + return Ok(None); } else if let Ok(DbFileMeta { sha256_digest, filename, content_type, - unauthenticated_access_permitted: _, + unauthenticated_access_permitted, }) = self.db.search_file_metadata(servername, media_id) { + if !(authenticated || unauthenticated_access_permitted) { + return Ok(None); + } + let content_disposition = content_disposition(filename.clone(), &content_type); // Generate a thumbnail let file = get_file(&hex::encode(sha256_digest)).await?; @@ -252,12 +272,16 @@ impl Service { sha256_digest, filename, content_type, - unauthenticated_access_permitted: _, + unauthenticated_access_permitted, }) = self.db.search_file_metadata(servername, media_id) else { return Ok(None); }; + if !(authenticated || unauthenticated_access_permitted) { + return Ok(None); + } + let file = get_file(&hex::encode(sha256_digest)).await?; Ok(Some(FileMeta {