From 2847040b3f06586e0dd84e376d3532376405d665 Mon Sep 17 00:00:00 2001 From: Nutomic Date: Wed, 29 Jan 2025 18:51:10 +0000 Subject: [PATCH] Deny unknown config fields (#5370) --- crates/utils/src/settings/mod.rs | 27 +++++++++++++++++---------- crates/utils/src/settings/structs.rs | 13 ++++++------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/crates/utils/src/settings/mod.rs b/crates/utils/src/settings/mod.rs index ecd0a9b55..240632f8d 100644 --- a/crates/utils/src/settings/mod.rs +++ b/crates/utils/src/settings/mod.rs @@ -2,7 +2,7 @@ use crate::{error::LemmyResult, location_info}; use anyhow::{anyhow, Context}; use deser_hjson::from_str; use regex::Regex; -use std::{env, fs, io::Error, sync::LazyLock}; +use std::{env, fs, sync::LazyLock}; use structs::{PictrsConfig, Settings}; use url::Url; @@ -39,7 +39,10 @@ impl Settings { /// `lemmy_db_schema/src/lib.rs::get_database_url_from_env()` /// Warning: Only call this once. pub(crate) fn init() -> LemmyResult { - let config = from_str::(&Self::read_config_file()?)?; + let path = + env::var("LEMMY_CONFIG_LOCATION").unwrap_or_else(|_| DEFAULT_CONFIG_FILE.to_string()); + let plain = fs::read_to_string(path)?; + let config = from_str::(&plain)?; if config.hostname == "unset" { Err(anyhow!("Hostname variable is not set!").into()) } else { @@ -55,14 +58,6 @@ impl Settings { } } - fn get_config_location() -> String { - env::var("LEMMY_CONFIG_LOCATION").unwrap_or_else(|_| DEFAULT_CONFIG_FILE.to_string()) - } - - fn read_config_file() -> Result { - fs::read_to_string(Self::get_config_location()) - } - /// Returns either "http" or "https", depending on tls_enabled setting pub fn get_protocol_string(&self) -> &'static str { if self.tls_enabled { @@ -109,3 +104,15 @@ impl Settings { fn pictrs_placeholder_url() -> Url { Url::parse("http://localhost:8080").expect("parse pictrs url") } + +#[cfg(test)] +mod tests { + + use super::*; + + #[test] + fn test_load_config() -> LemmyResult<()> { + Settings::init()?; + Ok(()) + } +} diff --git a/crates/utils/src/settings/structs.rs b/crates/utils/src/settings/structs.rs index 4577f4e60..01b73afd7 100644 --- a/crates/utils/src/settings/structs.rs +++ b/crates/utils/src/settings/structs.rs @@ -9,7 +9,7 @@ use std::{ use url::Url; #[derive(Debug, Deserialize, Serialize, Clone, SmartDefault, Document)] -#[serde(default)] +#[serde(default, deny_unknown_fields)] pub struct Settings { /// settings related to the postgresql database pub database: DatabaseConfig, @@ -109,7 +109,6 @@ pub struct PictrsConfig { } #[derive(Debug, Deserialize, Serialize, Clone, Default, Document, PartialEq)] -#[serde(deny_unknown_fields)] pub enum PictrsImageMode { /// Leave images unchanged, don't generate any local thumbnails for post urls. Instead the /// Opengraph image is directly returned as thumbnail @@ -132,7 +131,7 @@ pub enum PictrsImageMode { } #[derive(Debug, Deserialize, Serialize, Clone, SmartDefault, Document)] -#[serde(default)] +#[serde(default, deny_unknown_fields)] pub struct DatabaseConfig { /// Configure the database by specifying URI pointing to a postgres instance /// @@ -153,7 +152,7 @@ pub struct DatabaseConfig { } #[derive(Debug, Deserialize, Serialize, Clone, Document, SmartDefault)] -#[serde(deny_unknown_fields)] +#[serde(default, deny_unknown_fields)] pub struct EmailConfig { /// Hostname and port of the smtp server #[doku(example = "localhost:25")] @@ -180,7 +179,7 @@ impl EmailConfig { } #[derive(Debug, Deserialize, Serialize, Clone, Default, Document)] -#[serde(deny_unknown_fields)] +#[serde(default, deny_unknown_fields)] pub struct SetupConfig { /// Username for the admin user #[doku(example = "admin")] @@ -197,7 +196,7 @@ pub struct SetupConfig { } #[derive(Debug, Deserialize, Serialize, Clone, SmartDefault, Document)] -#[serde(deny_unknown_fields)] +#[serde(default, deny_unknown_fields)] pub struct PrometheusConfig { // Address that the Prometheus metrics will be served on. #[default(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)))] @@ -210,7 +209,7 @@ pub struct PrometheusConfig { } #[derive(Debug, Deserialize, Serialize, Clone, SmartDefault, Document)] -#[serde(default)] +#[serde(default, deny_unknown_fields)] // named federation"worker"config to disambiguate from the activitypub library configuration pub struct FederationWorkerConfig { /// Limit to the number of concurrent outgoing federation requests per target instance.