From 518af878024c082585bf489102e57d8620ffe792 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Mon, 8 Jan 2024 12:36:21 +0100 Subject: [PATCH] use enum for image proxy setting --- config/defaults.hjson | 41 ++++++++++++++----------- crates/api_common/src/request.rs | 4 +-- crates/api_common/src/utils.rs | 31 +++++++++++-------- crates/utils/src/settings/structs.rs | 45 +++++++++++++++------------- 4 files changed, 70 insertions(+), 51 deletions(-) diff --git a/config/defaults.hjson b/config/defaults.hjson index 6c8bd2bb3..94c185a1d 100644 --- a/config/defaults.hjson +++ b/config/defaults.hjson @@ -36,29 +36,36 @@ # Maximum number of active sql connections pool_size: 95 } - # Settings related to activitypub federation # Pictrs image server configuration. pictrs: { # Address where pictrs is available (for image hosting) url: "http://localhost:8080/" # Set a custom pictrs API key. ( Required for deleting images ) api_key: "string" - # If enabled, all images from remote domains are rewritten to pass through `/api/v3/image_proxy`. - # This improves privacy as users don't expose their IP to untrusted servers, and decreases load - # on other servers. However it causes more load for the local server. - # - # Requires pict-rs 0.5 - image_proxy: false - # By default the thumbnails for external links are stored in pict-rs. This ensures that they - # can be reliably retrieved and can be resized using pict-rs APIs. However it also increases - # storage usage. In case this is disabled, the Opengraph image is directly returned as - # thumbnail.Note that it still gets proxied through the local instance if `image_proxy` is - # enabled. - # - # In some countries it is forbidden to copy preview images from newspaper articles and only - # hotlinking is allowed. If that is the case for your instance, make sure that `image_proxy` and - # `cache_external_link_previews` are both disabled. - cache_external_link_previews: true + # Specifies how to handle remote images, so that users don't have to connect directly to remote servers. + image_mode: + # Leave images unchanged, don't generate any local thumbnails for post urls. Instead the the + # Opengraph image is directly returned as thumbnail + "None" + + # or + + # Generate thumbnails for external post urls and store them persistently in pict-rs. This + # ensures that they can be reliably retrieved and can be resized using pict-rs APIs. However + # it also increases storage usage. + # + # This is the default behaviour, and also matches Lemmy 0.18. + "StoreLinkPreviews" + + # or + + # If enabled, all images from remote domains are rewritten to pass through `/api/v3/image_proxy`, + # including embedded images in markdown. Images are stored temporarily in pict-rs for caching. + # This improves privacy as users don't expose their IP to untrusted servers, and decreases load + # on other servers. However it increases bandwidth use for the local server. + # + # Requires pict-rs 0.5 + "ProxyAllImages" # Timeout for uploading images to pictrs (in seconds) upload_timeout: 30 } diff --git a/crates/api_common/src/request.rs b/crates/api_common/src/request.rs index 10a339f42..bf6e71596 100644 --- a/crates/api_common/src/request.rs +++ b/crates/api_common/src/request.rs @@ -7,7 +7,7 @@ use encoding::{all::encodings, DecoderTrap}; use lemmy_db_schema::newtypes::DbUrl; use lemmy_utils::{ error::{LemmyError, LemmyErrorType}, - settings::structs::Settings, + settings::structs::{ImageProxyMode, Settings}, version::VERSION, REQWEST_TIMEOUT, }; @@ -258,7 +258,7 @@ async fn generate_pictrs_thumbnail( ) -> Result { let pictrs_config = context.settings().pictrs_config()?; - if !pictrs_config.cache_external_link_previews { + if pictrs_config.image_mode == ImageProxyMode::ProxyAllImages { return Ok(proxy_image_link(image_url.clone(), context).await?.into()); } diff --git a/crates/api_common/src/utils.rs b/crates/api_common/src/utils.rs index c377f1838..b5e52f433 100644 --- a/crates/api_common/src/utils.rs +++ b/crates/api_common/src/utils.rs @@ -35,7 +35,7 @@ use lemmy_utils::{ email::{send_email, translations::Lang}, error::{LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult}, rate_limit::{ActionType, BucketConfig}, - settings::structs::Settings, + settings::structs::{ImageProxyMode, Settings}, utils::{ markdown::markdown_rewrite_image_links, slurs::{build_slur_regex, remove_slurs}, @@ -846,7 +846,7 @@ pub async fn process_markdown( context: &LemmyContext, ) -> LemmyResult { let text = remove_slurs(text, slur_regex); - if context.settings().pictrs_config()?.image_proxy { + if context.settings().pictrs_config()?.image_mode == ImageProxyMode::ProxyAllImages { let (text, links) = markdown_rewrite_image_links(text); RemoteImage::create(&mut context.pool(), links).await?; Ok(text) @@ -872,13 +872,13 @@ pub async fn process_markdown_opt( /// as separate parameter so it can be changed in tests. async fn proxy_image_link_internal( link: Url, - force_image_proxy: bool, + image_proxy_mode: ImageProxyMode, context: &LemmyContext, ) -> LemmyResult { // Dont rewrite links pointing to local domain. - if link.domain() == Some(&context.settings().hostname) || !force_image_proxy { + if link.domain() == Some(&context.settings().hostname) { Ok(link.into()) - } else { + } else if image_proxy_mode == ImageProxyMode::ProxyAllImages { let proxied = format!( "{}/api/v3/image_proxy?url={}", context.settings().get_protocol_and_hostname(), @@ -886,6 +886,8 @@ async fn proxy_image_link_internal( ); RemoteImage::create(&mut context.pool(), vec![link]).await?; Ok(Url::parse(&proxied)?.into()) + } else { + Ok(link.into()) } } @@ -894,7 +896,7 @@ async fn proxy_image_link_internal( pub(crate) async fn proxy_image_link(link: Url, context: &LemmyContext) -> LemmyResult { proxy_image_link_internal( link, - context.settings().pictrs_config()?.image_proxy, + context.settings().pictrs_config()?.image_mode, context, ) .await @@ -993,16 +995,21 @@ mod tests { // image from local domain is unchanged let local_url = Url::parse("http://lemmy-alpha/image.png").unwrap(); - let proxied = proxy_image_link_internal(local_url.clone(), true, &context) - .await - .unwrap(); + let proxied = + proxy_image_link_internal(local_url.clone(), ImageProxyMode::ProxyAllImages, &context) + .await + .unwrap(); assert_eq!(&local_url, proxied.inner()); // image from remote domain is proxied let remote_image = Url::parse("http://lemmy-beta/image.png").unwrap(); - let proxied = proxy_image_link_internal(remote_image.clone(), true, &context) - .await - .unwrap(); + let proxied = proxy_image_link_internal( + remote_image.clone(), + ImageProxyMode::ProxyAllImages, + &context, + ) + .await + .unwrap(); assert_eq!( "https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Flemmy-beta%2Fimage.png", proxied.as_str() diff --git a/crates/utils/src/settings/structs.rs b/crates/utils/src/settings/structs.rs index 222391bf5..fd8e73506 100644 --- a/crates/utils/src/settings/structs.rs +++ b/crates/utils/src/settings/structs.rs @@ -12,7 +12,6 @@ pub struct Settings { /// settings related to the postgresql database #[default(Default::default())] pub database: DatabaseConfig, - /// Settings related to activitypub federation /// Pictrs image server configuration. #[default(Some(Default::default()))] pub(crate) pictrs: Option, @@ -79,31 +78,37 @@ pub struct PictrsConfig { #[default(None)] pub api_key: Option, - /// If enabled, all images from remote domains are rewritten to pass through `/api/v3/image_proxy`. - /// This improves privacy as users don't expose their IP to untrusted servers, and decreases load - /// on other servers. However it causes more load for the local server. - /// - /// Requires pict-rs 0.5 - #[default(false)] - pub image_proxy: bool, - - /// By default the thumbnails for external links are stored in pict-rs. This ensures that they - /// can be reliably retrieved and can be resized using pict-rs APIs. However it also increases - /// storage usage. In case this is disabled, the Opengraph image is directly returned as - /// thumbnail.Note that it still gets proxied through the local instance if `image_proxy` is - /// enabled. - /// - /// In some countries it is forbidden to copy preview images from newspaper articles and only - /// hotlinking is allowed. If that is the case for your instance, make sure that `image_proxy` and - /// `cache_external_link_previews` are both disabled. - #[default(true)] - pub cache_external_link_previews: bool, + /// Specifies how to handle remote images, so that users don't have to connect directly to remote servers. + #[default(ImageProxyMode::StoreLinkPreviews)] + pub image_mode: ImageProxyMode, /// Timeout for uploading images to pictrs (in seconds) #[default(30)] pub upload_timeout: u64, } +#[derive(Debug, Deserialize, Serialize, Clone, SmartDefault, Document, PartialEq)] +#[serde(deny_unknown_fields)] +pub enum ImageProxyMode { + /// Leave images unchanged, don't generate any local thumbnails for post urls. Instead the the + /// Opengraph image is directly returned as thumbnail + None, + /// Generate thumbnails for external post urls and store them persistently in pict-rs. This + /// ensures that they can be reliably retrieved and can be resized using pict-rs APIs. However + /// it also increases storage usage. + /// + /// This is the default behaviour, and also matches Lemmy 0.18. + #[default] + StoreLinkPreviews, + /// If enabled, all images from remote domains are rewritten to pass through `/api/v3/image_proxy`, + /// including embedded images in markdown. Images are stored temporarily in pict-rs for caching. + /// This improves privacy as users don't expose their IP to untrusted servers, and decreases load + /// on other servers. However it increases bandwidth use for the local server. + /// + /// Requires pict-rs 0.5 + ProxyAllImages, +} + #[derive(Debug, Deserialize, Serialize, Clone, SmartDefault, Document)] #[serde(default)] pub struct DatabaseConfig {