From 80aef61aed29d25099835ee4769bb8e1e363eb47 Mon Sep 17 00:00:00 2001 From: nutomic Date: Fri, 10 Jul 2020 18:15:41 +0000 Subject: Split code into cargo workspaces (#67) More fixes - fixed docker builds - fixed mentions regex test - fixed DATABASE_URL stuff - change schema path in diesel.toml Address review comments - add jsonb column back into activity table - remove authors field from cargo.toml - adjust LEMMY_DATABASE_URL env var usage - rename all occurences of LEMMY_DATABASE_URL to DATABASE_URL Decouple utils and db Split code into cargo workspaces Co-authored-by: Felix Ableitner Reviewed-on: https://yerbamate.dev/LemmyNet/lemmy/pulls/67 --- server/lemmy_utils/src/settings.rs | 135 +++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 server/lemmy_utils/src/settings.rs (limited to 'server/lemmy_utils/src/settings.rs') diff --git a/server/lemmy_utils/src/settings.rs b/server/lemmy_utils/src/settings.rs new file mode 100644 index 00000000..2ce33f58 --- /dev/null +++ b/server/lemmy_utils/src/settings.rs @@ -0,0 +1,135 @@ +use config::{Config, ConfigError, Environment, File}; +use serde::Deserialize; +use std::{fs, io::Error, net::IpAddr, sync::RwLock}; + +static CONFIG_FILE_DEFAULTS: &str = "config/defaults.hjson"; +static CONFIG_FILE: &str = "config/config.hjson"; + +#[derive(Debug, Deserialize, Clone)] +pub struct Settings { + pub setup: Option, + pub database: Database, + pub hostname: String, + pub bind: IpAddr, + pub port: u16, + pub jwt_secret: String, + pub front_end_dir: String, + pub rate_limit: RateLimitConfig, + pub email: Option, + pub federation: Federation, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct Setup { + pub admin_username: String, + pub admin_password: String, + pub admin_email: Option, + pub site_name: String, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct RateLimitConfig { + pub message: i32, + pub message_per_second: i32, + pub post: i32, + pub post_per_second: i32, + pub register: i32, + pub register_per_second: i32, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct EmailConfig { + pub smtp_server: String, + pub smtp_login: Option, + pub smtp_password: Option, + pub smtp_from_address: String, + pub use_tls: bool, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct Database { + pub user: String, + pub password: String, + pub host: String, + pub port: i32, + pub database: String, + pub pool_size: u32, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct Federation { + pub enabled: bool, + pub tls_enabled: bool, + pub allowed_instances: String, +} + +lazy_static! { + static ref SETTINGS: RwLock = RwLock::new(match Settings::init() { + Ok(c) => c, + Err(e) => panic!("{}", e), + }); +} + +impl Settings { + /// Reads config from the files and environment. + /// First, defaults are loaded from CONFIG_FILE_DEFAULTS, then these values can be overwritten + /// from CONFIG_FILE (optional). Finally, values from the environment (with prefix LEMMY) are + /// added to the config. + /// + /// Note: The env var `LEMMY_DATABASE_URL` is parsed in + /// `server/lemmy_db/src/lib.rs::get_database_url_from_env()` + fn init() -> Result { + let mut s = Config::new(); + + s.merge(File::with_name(CONFIG_FILE_DEFAULTS))?; + + s.merge(File::with_name(CONFIG_FILE).required(false))?; + + // Add in settings from the environment (with a prefix of LEMMY) + // Eg.. `LEMMY_DEBUG=1 ./target/app` would set the `debug` key + // Note: we need to use double underscore here, because otherwise variables containing + // underscore cant be set from environmnet. + // https://github.com/mehcode/config-rs/issues/73 + s.merge(Environment::with_prefix("LEMMY").separator("__"))?; + + s.try_into() + } + + /// Returns the config as a struct. + pub fn get() -> Self { + SETTINGS.read().unwrap().to_owned() + } + + pub fn get_database_url(&self) -> String { + format!( + "postgres://{}:{}@{}:{}/{}", + self.database.user, + self.database.password, + self.database.host, + self.database.port, + self.database.database + ) + } + + pub fn api_endpoint(&self) -> String { + format!("{}/api/v1", self.hostname) + } + + pub fn read_config_file() -> Result { + fs::read_to_string(CONFIG_FILE) + } + + pub fn save_config_file(data: &str) -> Result { + fs::write(CONFIG_FILE, data)?; + + // Reload the new settings + // From https://stackoverflow.com/questions/29654927/how-do-i-assign-a-string-to-a-mutable-static-variable/47181804#47181804 + let mut new_settings = SETTINGS.write().unwrap(); + *new_settings = match Settings::init() { + Ok(c) => c, + Err(e) => panic!("{}", e), + }; + + Self::read_config_file() + } +} -- cgit v1.2.3