diff --git a/Cargo.lock b/Cargo.lock index d6cbfbddd..4950d7ce6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1119,18 +1119,18 @@ dependencies = [ [[package]] name = "doku" version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7669ad18bd53786107832ce23c4cd1d859d3fe2ed6393ebcc0def93f15e5fa3" +source = "git+https://github.com/anixe/doku#10a0339a82be92b5f160aac325d11c9c2ef875e1" dependencies = [ "doku-derive", "serde", + "serde_json", + "url", ] [[package]] name = "doku-derive" version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "603fe9f91b4d0e11036df029aeaeffa90b8f97e700104d5d24abb053bf9ba858" +source = "git+https://github.com/anixe/doku#10a0339a82be92b5f160aac325d11c9c2ef875e1" dependencies = [ "darling 0.13.1", "proc-macro2 1.0.39", @@ -2075,6 +2075,7 @@ dependencies = [ "lemmy_websocket", "opentelemetry 0.17.0", "opentelemetry-otlp", + "parking_lot 0.12.0", "reqwest", "reqwest-middleware", "reqwest-retry", diff --git a/Cargo.toml b/Cargo.toml index 407a19ee7..f95ad8e1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,8 @@ reqwest = { version = "0.11.10", features = ["json"] } reqwest-middleware = "0.1.5" reqwest-tracing = "0.2.1" clokwerk = "0.3.5" -doku = "0.11.0" +doku = { git = "https://github.com/anixe/doku", features = ["url-2"] } +parking_lot = "0.12.0" reqwest-retry = "0.1.5" console-subscriber = { version = "0.1.3", optional = true } opentelemetry = { version = "0.17.0", features = ["rt-tokio"], optional = true } diff --git a/config/defaults.hjson b/config/defaults.hjson index 69fc34755..c85658567 100644 --- a/config/defaults.hjson +++ b/config/defaults.hjson @@ -75,7 +75,7 @@ # Pictrs image server configuration. pictrs_config: { # Address where pictrs is available (for image hosting) - url: "string" + url: "http://pictrs:8080/" # Set a custom pictrs API key. ( Required for deleting images ) api_key: "string" } diff --git a/crates/api_common/src/request.rs b/crates/api_common/src/request.rs index 1bc81861e..84789b17e 100644 --- a/crates/api_common/src/request.rs +++ b/crates/api_common/src/request.rs @@ -166,10 +166,13 @@ pub async fn purge_image_from_pictrs( let purge_url = format!("{}/internal/purge?alias={}", pictrs_config.url, alias); + let pictrs_api_key = pictrs_config + .api_key + .ok_or_else(|| LemmyError::from_message("pictrs_api_key_not_provided"))?; let response = client .post(&purge_url) .timeout(REQWEST_TIMEOUT) - .header("x-api-token", pictrs_config.api_key) + .header("x-api-token", pictrs_api_key) .send() .await?; diff --git a/crates/routes/src/images.rs b/crates/routes/src/images.rs index edd8fc8d4..a3d8115cf 100644 --- a/crates/routes/src/images.rs +++ b/crates/routes/src/images.rs @@ -27,8 +27,7 @@ pub fn config(cfg: &mut web::ServiceConfig, client: ClientWithMiddleware, rate_l ) // This has optional query params: /image/{filename}?format=jpg&thumbnail=256 .service(web::resource("/pictrs/image/{filename}").route(web::get().to(full_res))) - .service(web::resource("/pictrs/image/delete/{token}/{filename}").route(web::get().to(delete))) - .service(web::resource("/pictrs/internal/purge").route(web::post().to(purge))); + .service(web::resource("/pictrs/image/delete/{token}/{filename}").route(web::get().to(delete))); } #[derive(Debug, Serialize, Deserialize)] @@ -200,34 +199,6 @@ async fn delete( Ok(HttpResponse::build(res.status()).body(BodyStream::new(res.bytes_stream()))) } -async fn purge( - web::Query(params): web::Query, - req: HttpRequest, - client: web::Data, - context: web::Data, -) -> Result { - let purge_string = match params { - PictrsPurgeParams::File(f) => format!("file={}", f), - PictrsPurgeParams::Alias(a) => format!("alias={}", a), - }; - - let pictrs_config = context.settings().pictrs_config()?; - let url = format!("{}/internal/purge?{}", pictrs_config.url, &purge_string); - - let mut client_req = adapt_request(&req, &client, url); - - if let Some(addr) = req.head().peer_addr { - client_req = client_req.header("X-Forwarded-For", addr.to_string()) - } - - // Add the API token, X-Api-Token header - client_req = client_req.header("x-api-token", pictrs_config.api_key); - - let res = client_req.send().await.map_err(error::ErrorBadRequest)?; - - Ok(HttpResponse::build(res.status()).body(BodyStream::new(res.bytes_stream()))) -} - fn make_send(mut stream: S) -> impl Stream + Send + Unpin + 'static where S: Stream + Unpin + 'static, diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml index 0ceac0906..61a2564d5 100644 --- a/crates/utils/Cargo.toml +++ b/crates/utils/Cargo.toml @@ -38,7 +38,7 @@ http = "0.2.6" deser-hjson = "1.0.2" smart-default = "0.6.0" jsonwebtoken = "8.0.1" -doku = "0.11.0" +doku = { git = "https://github.com/anixe/doku", features = ["url-2"] } uuid = { version = "0.8.2", features = ["serde", "v4"] } html2text = "0.3.1" rosetta-i18n = "0.1.2" diff --git a/crates/utils/src/settings/structs.rs b/crates/utils/src/settings/structs.rs index 70d91bde3..7ee8cf18b 100644 --- a/crates/utils/src/settings/structs.rs +++ b/crates/utils/src/settings/structs.rs @@ -1,29 +1,32 @@ use doku::Document; use serde::{Deserialize, Serialize}; use std::net::{IpAddr, Ipv4Addr}; +use url::Url; #[derive(Debug, Deserialize, Serialize, Clone, SmartDefault, Document)] #[serde(default)] pub struct Settings { /// settings related to the postgresql database - #[serde(default)] + #[default(Default::default())] pub database: DatabaseConfig, - #[default(Some(RateLimitConfig::default()))] /// rate limits for various user actions, by user ip + #[default(Some(Default::default()))] pub rate_limit: Option, /// Settings related to activitypub federation - #[default(FederationConfig::default())] + #[default(Default::default())] pub federation: FederationConfig, /// Pictrs image server configuration. - #[default(None)] + #[default(Some(Default::default()))] pub(crate) pictrs_config: Option, - #[default(CaptchaConfig::default())] + #[default(Default::default())] pub captcha: CaptchaConfig, /// Email sending configuration. All options except login/password are mandatory #[default(None)] + #[doku(example = "Some(Default::default())")] pub email: Option, /// Parameters for automatic configuration of new instance (only used at first start) #[default(None)] + #[doku(example = "Some(Default::default())")] pub setup: Option, /// the domain name of your instance (mandatory) #[default("unset")] @@ -50,19 +53,20 @@ pub struct Settings { /// Set the URL for opentelemetry exports. If you do not have an opentelemetry collector, do not set this option #[default(None)] #[doku(skip)] - pub opentelemetry_url: Option, + pub opentelemetry_url: Option, } #[derive(Debug, Deserialize, Serialize, Clone, SmartDefault, Document)] #[serde(default)] pub struct PictrsConfig { /// Address where pictrs is available (for image hosting) - #[default("http://pictrs:8080")] - pub url: String, + #[default(Url::parse("http://pictrs:8080").expect("parse pictrs url"))] + #[doku(example = "Url::parse(\"http://pictrs:8080\").unwrap()")] + pub url: Url, /// Set a custom pictrs API key. ( Required for deleting images ) - #[default("API_KEY")] - pub api_key: String, + #[default(None)] + pub api_key: Option, } #[derive(Debug, Deserialize, Serialize, Clone, SmartDefault, Document)] diff --git a/src/lib.rs b/src/lib.rs index b0bbd4bb0..3dcc41e58 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,8 +11,9 @@ use tracing::subscriber::set_global_default; use tracing_error::ErrorLayer; use tracing_log::LogTracer; use tracing_subscriber::{filter::Targets, layer::SubscriberExt, Layer, Registry}; +use url::Url; -pub fn init_logging(opentelemetry_url: Option<&str>) -> Result<(), LemmyError> { +pub fn init_logging(opentelemetry_url: &Option) -> Result<(), LemmyError> { LogTracer::init()?; let log_description = std::env::var("RUST_LOG").unwrap_or_else(|_| "info".into()); @@ -30,7 +31,7 @@ pub fn init_logging(opentelemetry_url: Option<&str>) -> Result<(), LemmyError> { if let Some(_url) = opentelemetry_url { #[cfg(feature = "console")] - crate::telemetry::init_tracing(_url, subscriber, targets)?; + telemetry::init_tracing(_url.as_ref(), subscriber, targets)?; #[cfg(not(feature = "console"))] tracing::error!("Feature `console` must be enabled for opentelemetry tracing"); } else { diff --git a/src/main.rs b/src/main.rs index fa771c3de..81a108b89 100644 --- a/src/main.rs +++ b/src/main.rs @@ -60,7 +60,7 @@ async fn main() -> Result<(), LemmyError> { let settings = SETTINGS.to_owned(); - init_logging(settings.opentelemetry_url.as_deref())?; + init_logging(&settings.opentelemetry_url)?; // Set up the r2d2 connection pool let db_url = match get_database_url_from_env() {