From 29804b0dceebb0203f27efc82439f3d26a088e45 Mon Sep 17 00:00:00 2001 From: notplants Date: Tue, 3 May 2022 15:50:26 +0200 Subject: [PATCH 1/8] Get CONFIG_PATH from env_variable --- Cargo.lock | 1 + peach-lib/Cargo.toml | 1 + peach-lib/src/config_manager.rs | 39 +++++++++++++++++++++++---------- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b56d9dc..989b105 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2430,6 +2430,7 @@ dependencies = [ "jsonrpc-client-core", "jsonrpc-client-http", "jsonrpc-core 8.0.1", + "lazy_static", "log 0.4.16", "nanorand", "regex", diff --git a/peach-lib/Cargo.toml b/peach-lib/Cargo.toml index 9d53e7f..58e5789 100644 --- a/peach-lib/Cargo.toml +++ b/peach-lib/Cargo.toml @@ -21,3 +21,4 @@ serde_json = "1.0" serde_yaml = "0.8" toml = "0.5" sha3 = "0.10" +lazy_static = "1.4.0" diff --git a/peach-lib/src/config_manager.rs b/peach-lib/src/config_manager.rs index e29f8d6..a11c23c 100644 --- a/peach-lib/src/config_manager.rs +++ b/peach-lib/src/config_manager.rs @@ -5,19 +5,34 @@ //! //! The configuration file is located at: "/var/lib/peachcloud/config.yml" -use std::fs; +use std::{env, fs}; +use lazy_static::lazy_static; use fslock::LockFile; use log::debug; use serde::{Deserialize, Serialize}; use crate::error::PeachError; -// main configuration file -pub const YAML_PATH: &str = "/var/lib/peachcloud/config.yml"; +// load path to main configuration file +// from PEACH_CONFIG_PATH if that environment variable is set +// or using the default value if not set +pub const DEFAULT_YAML_PATH: &str = "/var/lib/peachcloud/config.yml"; +lazy_static! { + static ref CONFIG_PATH: String = { + if let Ok(val) = env::var("PEACH_CONFIG_PATH") { + val + } + else { + DEFAULT_YAML_PATH.to_string() + } + }; + // the lock file path is the config file path + ".lock" + static ref LOCK_FILE_PATH: String = format!("{}.lock", *CONFIG_PATH); +} // lock file (used to avoid race conditions during config reading & writing) -pub const LOCK_FILE_PATH: &str = "/var/lib/peachcloud/config.lock"; + // default values pub const DEFAULT_DYN_SERVER_ADDRESS: &str = "http://dynserver.dyn.peachcloud.org"; @@ -53,14 +68,14 @@ pub struct PeachConfig { // helper functions for serializing and deserializing PeachConfig from disc pub fn save_peach_config(peach_config: PeachConfig) -> Result { // use a file lock to avoid race conditions while saving config - let mut lock = LockFile::open(LOCK_FILE_PATH)?; + let mut lock = LockFile::open(&*LOCK_FILE_PATH)?; lock.lock()?; let yaml_str = serde_yaml::to_string(&peach_config)?; - fs::write(YAML_PATH, yaml_str).map_err(|source| PeachError::Write { + fs::write((*CONFIG_PATH).to_string(), yaml_str).map_err(|source| PeachError::Write { source, - path: YAML_PATH.to_string(), + path: (*CONFIG_PATH).to_string(), })?; // unlock file lock @@ -71,10 +86,10 @@ pub fn save_peach_config(peach_config: PeachConfig) -> Result Result { - let peach_config_exists = std::path::Path::new(YAML_PATH).exists(); + let peach_config_exists = std::path::Path::new(&*CONFIG_PATH).exists(); let peach_config: PeachConfig = if !peach_config_exists { - debug!("Loading peach config: {} does not exist", YAML_PATH); + debug!("Loading peach config: {} does not exist", *CONFIG_PATH); PeachConfig { external_domain: "".to_string(), dyn_domain: "".to_string(), @@ -91,10 +106,10 @@ pub fn load_peach_config() -> Result { } // otherwise we load peach config from disk else { - debug!("Loading peach config: {} exists", YAML_PATH); - let contents = fs::read_to_string(YAML_PATH).map_err(|source| PeachError::Read { + debug!("Loading peach config: {} exists", *CONFIG_PATH); + let contents = fs::read_to_string((*CONFIG_PATH).to_string()).map_err(|source| PeachError::Read { source, - path: YAML_PATH.to_string(), + path: (*CONFIG_PATH).to_string(), })?; serde_yaml::from_str(&contents)? }; From 5b86f754f49995b2ff4affa2e51f8639acead91c Mon Sep 17 00:00:00 2001 From: notplants Date: Mon, 9 May 2022 15:53:03 +0200 Subject: [PATCH 2/8] Working on refactor to use hashmaps --- peach-lib/src/config_manager.rs | 259 +++++++++++++++++--------------- peach-lib/src/dyndns_client.rs | 34 +++-- peach-lib/src/error.rs | 9 ++ peach-lib/src/password_utils.rs | 8 +- peach-lib/src/sbot.rs | 1 + 5 files changed, 171 insertions(+), 140 deletions(-) diff --git a/peach-lib/src/config_manager.rs b/peach-lib/src/config_manager.rs index a11c23c..343c8b6 100644 --- a/peach-lib/src/config_manager.rs +++ b/peach-lib/src/config_manager.rs @@ -3,14 +3,19 @@ //! Different PeachCloud microservices import peach-lib, so that they can share //! this interface. //! +//! Config values are looked up from three locations in this order by key name: +//! 1. from environmental variables +//! 2. from a configuration file +//! 3. from default values +//! //! The configuration file is located at: "/var/lib/peachcloud/config.yml" +//! unless its path is configured by setting PEACH_CONFIG_PATH env variable. use std::{env, fs}; +use std::collections::HashMap; -use lazy_static::lazy_static; use fslock::LockFile; -use log::debug; -use serde::{Deserialize, Serialize}; +use lazy_static::lazy_static; use crate::error::PeachError; @@ -27,161 +32,168 @@ lazy_static! { DEFAULT_YAML_PATH.to_string() } }; + // lock file (used to avoid race conditions during config reading & writing) // the lock file path is the config file path + ".lock" static ref LOCK_FILE_PATH: String = format!("{}.lock", *CONFIG_PATH); } -// lock file (used to avoid race conditions during config reading & writing) - - -// default values -pub const DEFAULT_DYN_SERVER_ADDRESS: &str = "http://dynserver.dyn.peachcloud.org"; -pub const DEFAULT_DYN_NAMESERVER: &str = "ns.peachcloud.org"; - -// we make use of Serde default values in order to make PeachCloud -// robust and keep running even with a not fully complete config.yml -// main type which represents all peachcloud configurations -#[derive(Debug, PartialEq, Serialize, Deserialize)] -pub struct PeachConfig { - #[serde(default)] - pub external_domain: String, - #[serde(default)] - pub dyn_domain: String, - #[serde(default)] - pub dyn_dns_server_address: String, - #[serde(default)] - pub dyn_use_custom_server: bool, - #[serde(default)] - pub dyn_nameserver: String, - #[serde(default)] - pub dyn_tsig_key_path: String, - #[serde(default)] // default is false - pub dyn_enabled: bool, - #[serde(default)] // default is empty vector - pub ssb_admin_ids: Vec, - #[serde(default)] - pub admin_password_hash: String, - #[serde(default)] - pub temporary_password_hash: String, +// primary interface for getting config values +pub fn get_config_value(key: &str) -> Result { + // first check if it is an environmental variable + if let Ok(val) = env::var(key) { + Ok(val) + } else { + // then check disc + let peach_config_on_disc = load_peach_config_from_disc()?; + let val = peach_config_on_disc.get(key); + // then check defaults + match val { + Some(v) => Ok(v.to_string()), + None => { + match get_peach_config_defaults().get(key) { + Some(v) => Ok(v.to_string()), + None => { + Err(PeachError::InvalidKey { msg: format!("No default config value set for key: {}", key) }) + } + } + } + } + } } -// helper functions for serializing and deserializing PeachConfig from disc -pub fn save_peach_config(peach_config: PeachConfig) -> Result { + +// Default values for PeachCloud configs which are used for any key which is not set +// via an environment variable or in a saved configuration file. +pub fn get_peach_config_defaults() -> HashMap { + let peach_config_defaults: HashMap = HashMap::from([ + ("STANDALONE_MODE".to_string(), "true".to_string()), + ("DISABLE_AUTH".to_string(), "false".to_string()), + ("ADDR".to_string(), "127.0.0.1".to_string()), + ("PORT".to_string(), "8000".to_string()), + ("EXTERNAL_DOMAIN".to_string(), "".to_string()), + ("DYN_DOMAIN".to_string(), "".to_string()), + ("DYN_DNS_SERVER_ADDRESS".to_string(), "http://dynserver.dyn.peachcloud.org".to_string()), + ("DYN_USE_CUSTOM_SERVER".to_string(), "true".to_string()), + ("DYN_TSIG_KEY_PATH".to_string(), "".to_string()), + ("DYN_NAMESERVER".to_string(), "ns.peachcloud.org".to_string()), + ("DYN_ENABLED".to_string(), "false".to_string()), + ("SSB_ADMIN_IDS".to_string(), "[]".to_string()), + ("ADMIN_PASSWORD_HASH".to_string(), "146".to_string()), + ("TEMPORARY_PASSWORD_HASH".to_string(), "".to_string()), + ("GO_SBOT_DATADIR".to_string(), "".to_string()), + ("PEACH_CONFIGDIR".to_string(), "/var/lib/peachcloud".to_string()), + ]); + peach_config_defaults +} + + +// helper function to load PeachCloud configuration files saved to disc +pub fn load_peach_config_from_disc() -> Result, PeachError> { + let peach_config : HashMap = HashMap::new(); + // TODO: implement + Ok(peach_config) +} + +pub fn save_peach_config_to_disc(peach_config: HashMap) -> Result, PeachError> { + // use a file lock to avoid race conditions while saving config let mut lock = LockFile::open(&*LOCK_FILE_PATH)?; lock.lock()?; + // convert HashMap to yaml let yaml_str = serde_yaml::to_string(&peach_config)?; - fs::write((*CONFIG_PATH).to_string(), yaml_str).map_err(|source| PeachError::Write { + // write yaml to file + fs::write(CONFIG_PATH.as_str(), yaml_str).map_err(|source| PeachError::Write { source, - path: (*CONFIG_PATH).to_string(), + path: CONFIG_PATH.to_string(), })?; // unlock file lock lock.unlock()?; - // return peach_config + // return modified HashMap Ok(peach_config) } -pub fn load_peach_config() -> Result { - let peach_config_exists = std::path::Path::new(&*CONFIG_PATH).exists(); +// helper functions for serializing and deserializing PeachConfig from disc +pub fn save_peach_config_value(key: &str, value: String) -> Result, PeachError> { - let peach_config: PeachConfig = if !peach_config_exists { - debug!("Loading peach config: {} does not exist", *CONFIG_PATH); - PeachConfig { - external_domain: "".to_string(), - dyn_domain: "".to_string(), - dyn_dns_server_address: DEFAULT_DYN_SERVER_ADDRESS.to_string(), - dyn_use_custom_server: false, - dyn_nameserver: DEFAULT_DYN_NAMESERVER.to_string(), - dyn_tsig_key_path: "".to_string(), - dyn_enabled: false, - ssb_admin_ids: Vec::new(), - // default password is `peach` - admin_password_hash: "146".to_string(), - temporary_password_hash: "".to_string(), - } - } - // otherwise we load peach config from disk - else { - debug!("Loading peach config: {} exists", *CONFIG_PATH); - let contents = fs::read_to_string((*CONFIG_PATH).to_string()).map_err(|source| PeachError::Read { - source, - path: (*CONFIG_PATH).to_string(), - })?; - serde_yaml::from_str(&contents)? - }; + // get current config from disc + let mut peach_config = load_peach_config_from_disc()?; - Ok(peach_config) + // insert new key/value + peach_config.insert(key.to_string(), value); + + // save hte modified hashmap to disc + save_peach_config_to_disc(peach_config) } -// interfaces for setting specific config values + +// set all dyn configuration values at once pub fn set_peach_dyndns_config( dyn_domain: &str, dyn_dns_server_address: &str, dyn_tsig_key_path: &str, dyn_enabled: bool, -) -> Result { - let mut peach_config = load_peach_config()?; - peach_config.dyn_domain = dyn_domain.to_string(); - peach_config.dyn_dns_server_address = dyn_dns_server_address.to_string(); - peach_config.dyn_tsig_key_path = dyn_tsig_key_path.to_string(); - peach_config.dyn_enabled = dyn_enabled; - save_peach_config(peach_config) +) -> Result, PeachError> { + let mut peach_config = load_peach_config_from_disc()?; + let dyn_enabled_str = match dyn_enabled { + true => "true", + false => "false" + }; + peach_config.insert("DYN_DOMAIN".to_string(), dyn_domain.to_string()); + peach_config.insert("DYN_DNS_SERVER_ADDRESS".to_string(), dyn_dns_server_address.to_string()); + peach_config.insert("DYN_TSIG_KEY_PATH".to_string(), dyn_tsig_key_path.to_string()); + peach_config.insert("DYN_ENABLED".to_string(), dyn_enabled_str.to_string()); + save_peach_config_to_disc(peach_config) } -pub fn set_external_domain(new_external_domain: &str) -> Result { - let mut peach_config = load_peach_config()?; - peach_config.external_domain = new_external_domain.to_string(); - save_peach_config(peach_config) +pub fn set_external_domain(new_external_domain: &str) -> Result, PeachError> { + save_peach_config_value("EXTERNAL_DOMAIN", new_external_domain.to_string()) } pub fn get_peachcloud_domain() -> Result, PeachError> { - let peach_config = load_peach_config()?; - if !peach_config.external_domain.is_empty() { - Ok(Some(peach_config.external_domain)) - } else if !peach_config.dyn_domain.is_empty() { - Ok(Some(peach_config.dyn_domain)) + let external_domain = get_config_value("EXTERNAL_DOMAIN")?; + let dyn_domain = get_config_value("DYN_DOMAIN")?; + if !external_domain.is_empty() { + Ok(Some(external_domain.to_string())) + } else if !dyn_domain.is_empty() { + Ok(Some(dyn_domain.to_string())) } else { Ok(None) } } pub fn get_dyndns_server_address() -> Result { - let peach_config = load_peach_config()?; - // if the user is using a custom dyn server then load the address from the config - if peach_config.dyn_use_custom_server { - Ok(peach_config.dyn_dns_server_address) - } - // otherwise hardcode the address - else { - Ok(DEFAULT_DYN_SERVER_ADDRESS.to_string()) + get_config_value("DYN_DNS_SERVER_ADDRESS") +} + +pub fn set_dyndns_enabled_value(enabled_value: bool) -> Result, PeachError> { + match enabled_value { + true => save_peach_config_value("DYN_ENABLED", "true".to_string()), + false => save_peach_config_value("DYN_ENABLED", "false".to_string()) } } -pub fn set_dyndns_enabled_value(enabled_value: bool) -> Result { - let mut peach_config = load_peach_config()?; - peach_config.dyn_enabled = enabled_value; - save_peach_config(peach_config) +pub fn get_dyndns_enabled_value() -> Result { + let val = get_config_value("DYN_ENABLED")?; + return Ok(val == "true") } -pub fn add_ssb_admin_id(ssb_id: &str) -> Result { - let mut peach_config = load_peach_config()?; - peach_config.ssb_admin_ids.push(ssb_id.to_string()); - save_peach_config(peach_config) +pub fn add_ssb_admin_id(ssb_id: &str) -> Result, PeachError> { + let mut ssb_admin_ids = get_ssb_admin_ids()?; + ssb_admin_ids.push(ssb_id.to_string()); + save_ssb_admin_ids(ssb_admin_ids) } -pub fn delete_ssb_admin_id(ssb_id: &str) -> Result { - let mut peach_config = load_peach_config()?; - let mut ssb_admin_ids = peach_config.ssb_admin_ids; +pub fn delete_ssb_admin_id(ssb_id: &str) -> Result, PeachError> { + let mut ssb_admin_ids = get_ssb_admin_ids()?; let index_result = ssb_admin_ids.iter().position(|x| *x == ssb_id); match index_result { Some(index) => { ssb_admin_ids.remove(index); - peach_config.ssb_admin_ids = ssb_admin_ids; - save_peach_config(peach_config) + save_ssb_admin_ids(ssb_admin_ids) } None => Err(PeachError::SsbAdminIdNotFound { id: ssb_id.to_string(), @@ -189,32 +201,39 @@ pub fn delete_ssb_admin_id(ssb_id: &str) -> Result { } } -pub fn set_admin_password_hash(password_hash: &str) -> Result { - let mut peach_config = load_peach_config()?; - peach_config.admin_password_hash = password_hash.to_string(); - save_peach_config(peach_config) +pub fn save_ssb_admin_ids(ssb_admin_ids: Vec) -> Result, PeachError> { + // save_peach_config_value("SSB_ADMIN_IDS", ssb_admin_ids.to_string()) + // TODO: implement + Ok(ssb_admin_ids) +} + +pub fn set_admin_password_hash(password_hash: String) -> Result, PeachError> { + save_peach_config_value("ADMIN_PASSWORD_HASH", password_hash) } pub fn get_admin_password_hash() -> Result { - let peach_config = load_peach_config()?; - if !peach_config.admin_password_hash.is_empty() { - Ok(peach_config.admin_password_hash) + let admin_password_hash = get_config_value("ADMIN_PASSWORD_HASH")?; + if !admin_password_hash.is_empty() { + Ok(admin_password_hash.to_string()) } else { Err(PeachError::PasswordNotSet) } } -pub fn set_temporary_password_hash(password_hash: &str) -> Result { - let mut peach_config = load_peach_config()?; - peach_config.temporary_password_hash = password_hash.to_string(); - save_peach_config(peach_config) +pub fn set_temporary_password_hash(password_hash: String) -> Result, PeachError> { + save_peach_config_value("TEMPORARY_PASSWORD_HASH", password_hash) } pub fn get_temporary_password_hash() -> Result { - let peach_config = load_peach_config()?; - if !peach_config.temporary_password_hash.is_empty() { - Ok(peach_config.temporary_password_hash) + let admin_password_hash = get_config_value("TEMPORARY_PASSWORD_HASH")?; + if !admin_password_hash.is_empty() { + Ok(admin_password_hash.to_string()) } else { Err(PeachError::PasswordNotSet) } } + +pub fn get_ssb_admin_ids() -> Result, PeachError> { + let mut ssb_admin_ids = vec!["x".to_string(), "y".to_string(), "z".to_string()]; + Ok(ssb_admin_ids) +} diff --git a/peach-lib/src/dyndns_client.rs b/peach-lib/src/dyndns_client.rs index 2c94288..a169d25 100644 --- a/peach-lib/src/dyndns_client.rs +++ b/peach-lib/src/dyndns_client.rs @@ -18,7 +18,7 @@ use jsonrpc_client_http::HttpTransport; use log::{debug, info}; use regex::Regex; -use crate::config_manager::get_dyndns_server_address; +use crate::config_manager::{get_dyndns_server_address, get_config_value, get_dyndns_enabled_value}; use crate::{config_manager, error::PeachError}; /// constants for dyndns configuration @@ -107,7 +107,11 @@ fn get_public_ip_address() -> Result { /// Reads dyndns configurations from config.yml /// and then uses nsupdate to update the IP address for the configured domain pub fn dyndns_update_ip() -> Result { - let peach_config = config_manager::load_peach_config()?; + let dyn_tsig_key_path = get_config_value("DYN_TSIG_KEY_PATH")?; + let dyn_enabled = get_dyndns_enabled_value()?; + let dyn_domain = get_config_value("DYN_DOMAIN")?; + let dyn_dns_server_address = get_config_value("DYN_DNS_SERVER_ADDRESS")?; + let dyn_nameserver = get_config_value("DYN_NAMESERVER")?; info!( "Using config: dyn_tsig_key_path: {:?} @@ -116,13 +120,13 @@ pub fn dyndns_update_ip() -> Result { dyn_enabled: {:?} dyn_nameserver: {:?} ", - peach_config.dyn_tsig_key_path, - peach_config.dyn_domain, - peach_config.dyn_dns_server_address, - peach_config.dyn_enabled, - peach_config.dyn_nameserver, + dyn_tsig_key_path, + dyn_domain, + dyn_dns_server_address, + dyn_enabled, + dyn_nameserver, ); - if !peach_config.dyn_enabled { + if !dyn_enabled { info!("dyndns is not enabled, not updating"); Ok(false) } else { @@ -130,7 +134,7 @@ pub fn dyndns_update_ip() -> Result { let mut nsupdate_command = Command::new("nsupdate"); nsupdate_command .arg("-k") - .arg(&peach_config.dyn_tsig_key_path) + .arg(&dyn_tsig_key_path) .arg("-v"); // pass nsupdate commands via stdin let public_ip_address = get_public_ip_address()?; @@ -142,9 +146,9 @@ pub fn dyndns_update_ip() -> Result { update delete {DOMAIN} A update add {DOMAIN} 30 A {PUBLIC_IP_ADDRESS} send", - NAMESERVER = peach_config.dyn_nameserver, - ZONE = peach_config.dyn_domain, - DOMAIN = peach_config.dyn_domain, + NAMESERVER = dyn_nameserver, + ZONE = dyn_domain, + DOMAIN = dyn_domain, PUBLIC_IP_ADDRESS = public_ip_address, ); info!("ns_commands: {:?}", ns_commands); @@ -217,8 +221,7 @@ pub fn get_num_seconds_since_successful_dns_update() -> Result, Peac /// and has successfully run recently (in the last six minutes) pub fn is_dns_updater_online() -> Result { // first check if it is enabled in peach-config - let peach_config = config_manager::load_peach_config()?; - let is_enabled = peach_config.dyn_enabled; + let is_enabled = get_dyndns_enabled_value()?; // then check if it has successfully run within the last 6 minutes (60*6 seconds) let num_seconds_since_successful_update = get_num_seconds_since_successful_dns_update()?; let ran_recently: bool = match num_seconds_since_successful_update { @@ -248,8 +251,7 @@ pub fn get_dyndns_subdomain(dyndns_full_domain: &str) -> Option { // helper function which checks if a dyndns domain is new pub fn check_is_new_dyndns_domain(dyndns_full_domain: &str) -> Result { - let peach_config = config_manager::load_peach_config()?; - let previous_dyndns_domain = peach_config.dyn_domain; + let previous_dyndns_domain = get_config_value("DYN_DOMAIN")?; Ok(dyndns_full_domain != previous_dyndns_domain) } diff --git a/peach-lib/src/error.rs b/peach-lib/src/error.rs index ba396b1..7d49111 100644 --- a/peach-lib/src/error.rs +++ b/peach-lib/src/error.rs @@ -7,6 +7,11 @@ use std::{io, str, string}; /// This type represents all possible errors that can occur when interacting with the PeachCloud library. #[derive(Debug)] pub enum PeachError { + /// Represents looking up a Config value with a non-existent key + InvalidKey { + msg: String, + }, + /// Represents a failure to determine the path of the user's home directory. HomeDir, @@ -102,6 +107,7 @@ impl std::error::Error for PeachError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match *self { PeachError::HomeDir => None, + PeachError::InvalidKey{ .. } => None, PeachError::Io(_) => None, PeachError::JsonRpcClientCore(_) => None, PeachError::JsonRpcCore(_) => None, @@ -130,6 +136,9 @@ impl std::error::Error for PeachError { impl std::fmt::Display for PeachError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match *self { + PeachError::InvalidKey { ref msg} => { + write!(f, "Invalid key in config lookup: {}", msg) + } PeachError::HomeDir => { write!( f, diff --git a/peach-lib/src/password_utils.rs b/peach-lib/src/password_utils.rs index a806648..bb08cb2 100644 --- a/peach-lib/src/password_utils.rs +++ b/peach-lib/src/password_utils.rs @@ -33,7 +33,7 @@ pub fn validate_new_passwords(new_password1: &str, new_password2: &str) -> Resul /// Sets a new password for the admin user pub fn set_new_password(new_password: &str) -> Result<(), PeachError> { let new_password_hash = hash_password(new_password); - config_manager::set_admin_password_hash(&new_password_hash)?; + config_manager::set_admin_password_hash(new_password_hash)?; Ok(()) } @@ -53,7 +53,7 @@ pub fn hash_password(password: &str) -> String { /// which can be used to reset the permanent password pub fn set_new_temporary_password(new_password: &str) -> Result<(), PeachError> { let new_password_hash = hash_password(new_password); - config_manager::set_temporary_password_hash(&new_password_hash)?; + config_manager::set_temporary_password_hash(new_password_hash)?; Ok(()) } @@ -103,8 +103,8 @@ using this link: http://peach.local/auth/reset", }; msg += &remote_link; // finally send the message to the admins - let peach_config = config_manager::load_peach_config()?; - for ssb_admin_id in peach_config.ssb_admin_ids { + let ssb_admin_ids = config_manager::get_ssb_admin_ids()?; + for ssb_admin_id in ssb_admin_ids { // use golgi to send a private message on scuttlebutt match task::block_on(publish_private_msg(&msg, &ssb_admin_id)) { Ok(_) => (), diff --git a/peach-lib/src/sbot.rs b/peach-lib/src/sbot.rs index ee9434f..0c0d816 100644 --- a/peach-lib/src/sbot.rs +++ b/peach-lib/src/sbot.rs @@ -5,6 +5,7 @@ use std::{fs, fs::File, io, io::Write, path::PathBuf, process::Command, str}; use serde::{Deserialize, Serialize}; use crate::error::PeachError; +use crate::config_manager::get_config_value; /* HELPER FUNCTIONS */ From 2540a77af1f7421c86d640a239ea346f6dfd2bfa Mon Sep 17 00:00:00 2001 From: notplants Date: Tue, 10 May 2022 12:59:36 +0200 Subject: [PATCH 3/8] Working 3-way configuration --- peach-lib/debug/.cargo/config | 4 - peach-lib/debug/Cargo.toml | 12 -- peach-lib/debug/src/main.rs | 65 --------- peach-lib/examples/config.rs | 11 ++ peach-lib/src/config_manager.rs | 227 ++++++++++++++++++++------------ peach-lib/src/dyndns_client.rs | 15 +-- peach-lib/src/error.rs | 9 +- peach-lib/src/sbot.rs | 1 - 8 files changed, 161 insertions(+), 183 deletions(-) delete mode 100644 peach-lib/debug/.cargo/config delete mode 100644 peach-lib/debug/Cargo.toml delete mode 100644 peach-lib/debug/src/main.rs create mode 100644 peach-lib/examples/config.rs diff --git a/peach-lib/debug/.cargo/config b/peach-lib/debug/.cargo/config deleted file mode 100644 index 4b6f460..0000000 --- a/peach-lib/debug/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[target.aarch64-unknown-linux-gnu] -linker = "aarch64-linux-gnu-gcc" -objcopy = { path ="aarch64-linux-gnu-objcopy" } -strip = { path ="aarch64-linux-gnu-strip" } diff --git a/peach-lib/debug/Cargo.toml b/peach-lib/debug/Cargo.toml deleted file mode 100644 index 2c9f53e..0000000 --- a/peach-lib/debug/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "debug" -version = "0.1.0" -authors = ["notplants "] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -peach-lib = { path = "../" } -env_logger = "0.6" -chrono = "0.4.19" \ No newline at end of file diff --git a/peach-lib/debug/src/main.rs b/peach-lib/debug/src/main.rs deleted file mode 100644 index 19de0b3..0000000 --- a/peach-lib/debug/src/main.rs +++ /dev/null @@ -1,65 +0,0 @@ -use peach_lib::dyndns_client::{dyndns_update_ip, register_domain, is_dns_updater_online, log_successful_nsupdate, get_num_seconds_since_successful_dns_update }; -use peach_lib::password_utils::{verify_password, set_new_password, verify_temporary_password, set_new_temporary_password, send_password_reset}; -use peach_lib::config_manager::{add_ssb_admin_id, delete_ssb_admin_id}; -use peach_lib::sbot_client; -use std::process; -use chrono::prelude::*; - - -fn main() { - // initalize the logger - env_logger::init(); -// -// println!("Hello, world its debug!"); -// let result = set_new_password("password3"); -// println!("result: {:?}", result); -// -// let result = verify_password("password1"); -// println!("result should be error: {:?}", result); -// -// let result = verify_password("password3"); -// println!("result should be ok: {:?}", result); -// -// -// println!("Testing temporary passwords"); -// let result = set_new_temporary_password("abcd"); -// println!("result: {:?}", result); -// -// let result = verify_temporary_password("password1"); -// println!("result should be error: {:?}", result); -// -// let result = verify_temporary_password("abcd"); -// println!("result should be ok: {:?}", result); -// - let result = send_password_reset(); - println!("send password reset result should be ok: {:?}", result); - -// sbot_client::post("hi cat"); -// let result = sbot_client::whoami(); -// let result = sbot_client::create_invite(50); -// let result = sbot_client::post("is this working"); -// println!("result: {:?}", result); -// let result = sbot_client::post("nice we have contact"); -// let result = sbot_client::update_pub_name("vermont-pub"); -// let result = sbot_client::private_message("this is a private message", "@LZx+HP6/fcjUm7vef2eaBKAQ9gAKfzmrMVGzzdJiQtA=.ed25519"); -// println!("result: {:?}", result); - -// let result = send_password_reset(); -// let result = add_ssb_admin_id("xyzdab"); -// println!("result: {:?}", result); -// let result = delete_ssb_admin_id("xyzdab"); -// println!("result: {:?}", result); -// let result = delete_ssb_admin_id("ab"); -// println!("result: {:?}", result); - -//// let result = log_successful_nsupdate(); -//// let result = get_num_seconds_since_successful_dns_update(); -// let is_online = is_dns_updater_online(); -// println!("is online: {:?}", is_online); -// -//// let result = get_last_successful_dns_update(); -//// println!("result: {:?}", result); -//// register_domain("newquarter299.dyn.peachcloud.org"); -// let result = dyndns_update_ip(); -// println!("result: {:?}", result); -} diff --git a/peach-lib/examples/config.rs b/peach-lib/examples/config.rs new file mode 100644 index 0000000..2580150 --- /dev/null +++ b/peach-lib/examples/config.rs @@ -0,0 +1,11 @@ +use peach_lib::config_manager::{get_config_value, save_config_value}; + +fn main() { + println!("Running example of PeachCloud configuration management"); + let v = get_config_value("ADDR").unwrap(); + println!("ADDR: {}", v); + + save_config_value("ADDR", "1.1.1.1".to_string()); + let v = get_config_value("ADDR").unwrap(); + println!("ADDR: {}", v); +} diff --git a/peach-lib/src/config_manager.rs b/peach-lib/src/config_manager.rs index 343c8b6..abcb19f 100644 --- a/peach-lib/src/config_manager.rs +++ b/peach-lib/src/config_manager.rs @@ -11,11 +11,12 @@ //! The configuration file is located at: "/var/lib/peachcloud/config.yml" //! unless its path is configured by setting PEACH_CONFIG_PATH env variable. +use std::collections::{BTreeMap, HashMap}; use std::{env, fs}; -use std::collections::HashMap; use fslock::LockFile; use lazy_static::lazy_static; +use log::debug; use crate::error::PeachError; @@ -37,31 +38,6 @@ lazy_static! { static ref LOCK_FILE_PATH: String = format!("{}.lock", *CONFIG_PATH); } -// primary interface for getting config values -pub fn get_config_value(key: &str) -> Result { - // first check if it is an environmental variable - if let Ok(val) = env::var(key) { - Ok(val) - } else { - // then check disc - let peach_config_on_disc = load_peach_config_from_disc()?; - let val = peach_config_on_disc.get(key); - // then check defaults - match val { - Some(v) => Ok(v.to_string()), - None => { - match get_peach_config_defaults().get(key) { - Some(v) => Ok(v.to_string()), - None => { - Err(PeachError::InvalidKey { msg: format!("No default config value set for key: {}", key) }) - } - } - } - } - } -} - - // Default values for PeachCloud configs which are used for any key which is not set // via an environment variable or in a saved configuration file. pub fn get_peach_config_defaults() -> HashMap { @@ -72,36 +48,95 @@ pub fn get_peach_config_defaults() -> HashMap { ("PORT".to_string(), "8000".to_string()), ("EXTERNAL_DOMAIN".to_string(), "".to_string()), ("DYN_DOMAIN".to_string(), "".to_string()), - ("DYN_DNS_SERVER_ADDRESS".to_string(), "http://dynserver.dyn.peachcloud.org".to_string()), + ( + "DYN_DNS_SERVER_ADDRESS".to_string(), + "http://dynserver.dyn.peachcloud.org".to_string(), + ), ("DYN_USE_CUSTOM_SERVER".to_string(), "true".to_string()), ("DYN_TSIG_KEY_PATH".to_string(), "".to_string()), - ("DYN_NAMESERVER".to_string(), "ns.peachcloud.org".to_string()), + ( + "DYN_NAMESERVER".to_string(), + "ns.peachcloud.org".to_string(), + ), ("DYN_ENABLED".to_string(), "false".to_string()), - ("SSB_ADMIN_IDS".to_string(), "[]".to_string()), + ("SSB_ADMIN_IDS".to_string(), "".to_string()), ("ADMIN_PASSWORD_HASH".to_string(), "146".to_string()), ("TEMPORARY_PASSWORD_HASH".to_string(), "".to_string()), ("GO_SBOT_DATADIR".to_string(), "".to_string()), - ("PEACH_CONFIGDIR".to_string(), "/var/lib/peachcloud".to_string()), + ( + "PEACH_CONFIGDIR".to_string(), + "/var/lib/peachcloud".to_string(), + ), ]); peach_config_defaults } - -// helper function to load PeachCloud configuration files saved to disc -pub fn load_peach_config_from_disc() -> Result, PeachError> { - let peach_config : HashMap = HashMap::new(); - // TODO: implement - Ok(peach_config) +// primary interface for getting config values +// Config values are looked up from three locations in this order by key name: +// 1. from environmental variables +// 2. from a configuration file +// 3. from default values +pub fn get_config_value(key: &str) -> Result { + // first check if there is an environmental variable set + if let Ok(val) = env::var(key) { + Ok(val) + } else { + // then check if a value is set in the config file + let peach_config_on_disc = load_peach_config_from_disc()?; + let val = peach_config_on_disc.get(key); + // if no value is found in the config file, then get the default value + match val { + // return config value + Some(v) => Ok(v.to_string()), + // get default value + None => { + match get_peach_config_defaults().get(key) { + Some(v) => Ok(v.to_string()), + // if this key was not found in the defaults, then it was an invalid key + None => Err(PeachError::InvalidKey { + key: key.to_string(), + }), + } + } + } + } } -pub fn save_peach_config_to_disc(peach_config: HashMap) -> Result, PeachError> { +// helper function to load PeachCloud configuration file saved to disc +pub fn load_peach_config_from_disc() -> Result, PeachError> { + let peach_config_exists = std::path::Path::new(CONFIG_PATH.as_str()).exists(); + // if config file does not exist, return an emtpy HashMap + if !peach_config_exists { + let peach_config: HashMap = HashMap::new(); + Ok(peach_config) + } + // otherwise we load peach config from disk + else { + debug!("Loading peach config: {} exists", CONFIG_PATH.as_str()); + let contents = + fs::read_to_string(CONFIG_PATH.as_str()).map_err(|source| PeachError::Read { + source, + path: CONFIG_PATH.to_string(), + })?; + let peach_config: HashMap = serde_yaml::from_str(&contents)?; + Ok(peach_config) + } +} +// helper function to save PeachCloud configuration file to disc +// takes in a Hashmap and saves the whole HashMap as a yaml file +// with the keys in alphabetical order +pub fn save_peach_config_to_disc( + peach_config: HashMap, +) -> Result, PeachError> { // use a file lock to avoid race conditions while saving config let mut lock = LockFile::open(&*LOCK_FILE_PATH)?; lock.lock()?; - // convert HashMap to yaml - let yaml_str = serde_yaml::to_string(&peach_config)?; + // first convert Hashmap to BTreeMap (so that keys are saved in deterministic alphabetical order) + let ordered: BTreeMap<_, _> = peach_config.iter().collect(); + // then serialize BTreeMap as yaml + let yaml_str = serde_yaml::to_string(&ordered)?; // write yaml to file fs::write(CONFIG_PATH.as_str(), yaml_str).map_err(|source| PeachError::Write { @@ -116,9 +151,8 @@ pub fn save_peach_config_to_disc(peach_config: HashMap) -> Resul Ok(peach_config) } -// helper functions for serializing and deserializing PeachConfig from disc -pub fn save_peach_config_value(key: &str, value: String) -> Result, PeachError> { - +// helper functions for serializing and deserializing PeachConfig values from disc +pub fn save_config_value(key: &str, value: String) -> Result, PeachError> { // get current config from disc let mut peach_config = load_peach_config_from_disc()?; @@ -129,7 +163,6 @@ pub fn save_peach_config_value(key: &str, value: String) -> Result "true", - false => "false" + false => "false", }; peach_config.insert("DYN_DOMAIN".to_string(), dyn_domain.to_string()); - peach_config.insert("DYN_DNS_SERVER_ADDRESS".to_string(), dyn_dns_server_address.to_string()); - peach_config.insert("DYN_TSIG_KEY_PATH".to_string(), dyn_tsig_key_path.to_string()); + peach_config.insert( + "DYN_DNS_SERVER_ADDRESS".to_string(), + dyn_dns_server_address.to_string(), + ); + peach_config.insert( + "DYN_TSIG_KEY_PATH".to_string(), + dyn_tsig_key_path.to_string(), + ); peach_config.insert("DYN_ENABLED".to_string(), dyn_enabled_str.to_string()); save_peach_config_to_disc(peach_config) } -pub fn set_external_domain(new_external_domain: &str) -> Result, PeachError> { - save_peach_config_value("EXTERNAL_DOMAIN", new_external_domain.to_string()) +pub fn set_external_domain( + new_external_domain: &str, +) -> Result, PeachError> { + save_config_value("EXTERNAL_DOMAIN", new_external_domain.to_string()) } pub fn get_peachcloud_domain() -> Result, PeachError> { let external_domain = get_config_value("EXTERNAL_DOMAIN")?; let dyn_domain = get_config_value("DYN_DOMAIN")?; if !external_domain.is_empty() { - Ok(Some(external_domain.to_string())) + Ok(Some(external_domain)) } else if !dyn_domain.is_empty() { - Ok(Some(dyn_domain.to_string())) + Ok(Some(dyn_domain)) } else { Ok(None) } @@ -169,24 +210,59 @@ pub fn get_dyndns_server_address() -> Result { get_config_value("DYN_DNS_SERVER_ADDRESS") } -pub fn set_dyndns_enabled_value(enabled_value: bool) -> Result, PeachError> { +pub fn set_dyndns_enabled_value( + enabled_value: bool, +) -> Result, PeachError> { match enabled_value { - true => save_peach_config_value("DYN_ENABLED", "true".to_string()), - false => save_peach_config_value("DYN_ENABLED", "false".to_string()) + true => save_config_value("DYN_ENABLED", "true".to_string()), + false => save_config_value("DYN_ENABLED", "false".to_string()), } } pub fn get_dyndns_enabled_value() -> Result { let val = get_config_value("DYN_ENABLED")?; - return Ok(val == "true") + Ok(val == "true") } +pub fn set_admin_password_hash( + password_hash: String, +) -> Result, PeachError> { + save_config_value("ADMIN_PASSWORD_HASH", password_hash) +} + +pub fn get_admin_password_hash() -> Result { + let admin_password_hash = get_config_value("ADMIN_PASSWORD_HASH")?; + if !admin_password_hash.is_empty() { + Ok(admin_password_hash) + } else { + Err(PeachError::PasswordNotSet) + } +} + +pub fn set_temporary_password_hash( + password_hash: String, +) -> Result, PeachError> { + save_config_value("TEMPORARY_PASSWORD_HASH", password_hash) +} + +pub fn get_temporary_password_hash() -> Result { + let admin_password_hash = get_config_value("TEMPORARY_PASSWORD_HASH")?; + if !admin_password_hash.is_empty() { + Ok(admin_password_hash) + } else { + Err(PeachError::PasswordNotSet) + } +} + +// add ssb_id to vector of admin ids and save new value for SSB_ADMIN_IDS pub fn add_ssb_admin_id(ssb_id: &str) -> Result, PeachError> { let mut ssb_admin_ids = get_ssb_admin_ids()?; ssb_admin_ids.push(ssb_id.to_string()); save_ssb_admin_ids(ssb_admin_ids) } +// remove ssb_id from vector of admin ids if found and save new value for SSB_ADMIN_IDS +// if value is not found then return an error pub fn delete_ssb_admin_id(ssb_id: &str) -> Result, PeachError> { let mut ssb_admin_ids = get_ssb_admin_ids()?; let index_result = ssb_admin_ids.iter().position(|x| *x == ssb_id); @@ -201,39 +277,16 @@ pub fn delete_ssb_admin_id(ssb_id: &str) -> Result, PeachError> { } } -pub fn save_ssb_admin_ids(ssb_admin_ids: Vec) -> Result, PeachError> { - // save_peach_config_value("SSB_ADMIN_IDS", ssb_admin_ids.to_string()) - // TODO: implement - Ok(ssb_admin_ids) -} - -pub fn set_admin_password_hash(password_hash: String) -> Result, PeachError> { - save_peach_config_value("ADMIN_PASSWORD_HASH", password_hash) -} - -pub fn get_admin_password_hash() -> Result { - let admin_password_hash = get_config_value("ADMIN_PASSWORD_HASH")?; - if !admin_password_hash.is_empty() { - Ok(admin_password_hash.to_string()) - } else { - Err(PeachError::PasswordNotSet) - } -} - -pub fn set_temporary_password_hash(password_hash: String) -> Result, PeachError> { - save_peach_config_value("TEMPORARY_PASSWORD_HASH", password_hash) -} - -pub fn get_temporary_password_hash() -> Result { - let admin_password_hash = get_config_value("TEMPORARY_PASSWORD_HASH")?; - if !admin_password_hash.is_empty() { - Ok(admin_password_hash.to_string()) - } else { - Err(PeachError::PasswordNotSet) - } -} - +// looks up the String value for SSB_ADMIN_IDS and converts it into a Vec pub fn get_ssb_admin_ids() -> Result, PeachError> { - let mut ssb_admin_ids = vec!["x".to_string(), "y".to_string(), "z".to_string()]; + let ssb_admin_ids_str = get_config_value("SSB_ADMIN_IDS")?; + let ssb_admin_ids: Vec = serde_json::from_str(&ssb_admin_ids_str)?; + Ok(ssb_admin_ids) +} + +// takes in a Vec and saves SSB_ADMIN_IDS as a json string representation of this vec +pub fn save_ssb_admin_ids(ssb_admin_ids: Vec) -> Result, PeachError> { + let ssb_admin_ids_as_json_str = serde_json::to_string(&ssb_admin_ids)?; + save_config_value("SSB_ADMIN_IDS", ssb_admin_ids_as_json_str)?; Ok(ssb_admin_ids) } diff --git a/peach-lib/src/dyndns_client.rs b/peach-lib/src/dyndns_client.rs index a169d25..cfa8acf 100644 --- a/peach-lib/src/dyndns_client.rs +++ b/peach-lib/src/dyndns_client.rs @@ -18,7 +18,9 @@ use jsonrpc_client_http::HttpTransport; use log::{debug, info}; use regex::Regex; -use crate::config_manager::{get_dyndns_server_address, get_config_value, get_dyndns_enabled_value}; +use crate::config_manager::{ + get_config_value, get_dyndns_enabled_value, get_dyndns_server_address, +}; use crate::{config_manager, error::PeachError}; /// constants for dyndns configuration @@ -120,11 +122,7 @@ pub fn dyndns_update_ip() -> Result { dyn_enabled: {:?} dyn_nameserver: {:?} ", - dyn_tsig_key_path, - dyn_domain, - dyn_dns_server_address, - dyn_enabled, - dyn_nameserver, + dyn_tsig_key_path, dyn_domain, dyn_dns_server_address, dyn_enabled, dyn_nameserver, ); if !dyn_enabled { info!("dyndns is not enabled, not updating"); @@ -132,10 +130,7 @@ pub fn dyndns_update_ip() -> Result { } else { // call nsupdate passing appropriate configs let mut nsupdate_command = Command::new("nsupdate"); - nsupdate_command - .arg("-k") - .arg(&dyn_tsig_key_path) - .arg("-v"); + nsupdate_command.arg("-k").arg(&dyn_tsig_key_path).arg("-v"); // pass nsupdate commands via stdin let public_ip_address = get_public_ip_address()?; info!("found public ip address: {}", public_ip_address); diff --git a/peach-lib/src/error.rs b/peach-lib/src/error.rs index 7d49111..42a4993 100644 --- a/peach-lib/src/error.rs +++ b/peach-lib/src/error.rs @@ -9,7 +9,8 @@ use std::{io, str, string}; pub enum PeachError { /// Represents looking up a Config value with a non-existent key InvalidKey { - msg: String, + /// the key value which was invalid + key: String, }, /// Represents a failure to determine the path of the user's home directory. @@ -107,7 +108,7 @@ impl std::error::Error for PeachError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match *self { PeachError::HomeDir => None, - PeachError::InvalidKey{ .. } => None, + PeachError::InvalidKey { .. } => None, PeachError::Io(_) => None, PeachError::JsonRpcClientCore(_) => None, PeachError::JsonRpcCore(_) => None, @@ -136,8 +137,8 @@ impl std::error::Error for PeachError { impl std::fmt::Display for PeachError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match *self { - PeachError::InvalidKey { ref msg} => { - write!(f, "Invalid key in config lookup: {}", msg) + PeachError::InvalidKey { ref key } => { + write!(f, "Invalid key in config lookup for key: {}", key) } PeachError::HomeDir => { write!( diff --git a/peach-lib/src/sbot.rs b/peach-lib/src/sbot.rs index 0c0d816..ee9434f 100644 --- a/peach-lib/src/sbot.rs +++ b/peach-lib/src/sbot.rs @@ -5,7 +5,6 @@ use std::{fs, fs::File, io, io::Write, path::PathBuf, process::Command, str}; use serde::{Deserialize, Serialize}; use crate::error::PeachError; -use crate::config_manager::get_config_value; /* HELPER FUNCTIONS */ From 600f9c58bf5a647333824e120bb62e3cdf79529c Mon Sep 17 00:00:00 2001 From: notplants Date: Tue, 10 May 2022 13:07:50 +0200 Subject: [PATCH 4/8] Use &str instead of String in save_config_value --- peach-lib/src/config_manager.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/peach-lib/src/config_manager.rs b/peach-lib/src/config_manager.rs index abcb19f..b02c85a 100644 --- a/peach-lib/src/config_manager.rs +++ b/peach-lib/src/config_manager.rs @@ -152,12 +152,12 @@ pub fn save_peach_config_to_disc( } // helper functions for serializing and deserializing PeachConfig values from disc -pub fn save_config_value(key: &str, value: String) -> Result, PeachError> { +pub fn save_config_value(key: &str, value: &str) -> Result, PeachError> { // get current config from disc let mut peach_config = load_peach_config_from_disc()?; // insert new key/value - peach_config.insert(key.to_string(), value); + peach_config.insert(key.to_string(), value.to_string()); // save hte modified hashmap to disc save_peach_config_to_disc(peach_config) @@ -191,7 +191,7 @@ pub fn set_peach_dyndns_config( pub fn set_external_domain( new_external_domain: &str, ) -> Result, PeachError> { - save_config_value("EXTERNAL_DOMAIN", new_external_domain.to_string()) + save_config_value("EXTERNAL_DOMAIN", new_external_domain) } pub fn get_peachcloud_domain() -> Result, PeachError> { @@ -214,8 +214,8 @@ pub fn set_dyndns_enabled_value( enabled_value: bool, ) -> Result, PeachError> { match enabled_value { - true => save_config_value("DYN_ENABLED", "true".to_string()), - false => save_config_value("DYN_ENABLED", "false".to_string()), + true => save_config_value("DYN_ENABLED", "true"), + false => save_config_value("DYN_ENABLED", "false"), } } @@ -227,7 +227,7 @@ pub fn get_dyndns_enabled_value() -> Result { pub fn set_admin_password_hash( password_hash: String, ) -> Result, PeachError> { - save_config_value("ADMIN_PASSWORD_HASH", password_hash) + save_config_value("ADMIN_PASSWORD_HASH", &password_hash) } pub fn get_admin_password_hash() -> Result { @@ -242,7 +242,7 @@ pub fn get_admin_password_hash() -> Result { pub fn set_temporary_password_hash( password_hash: String, ) -> Result, PeachError> { - save_config_value("TEMPORARY_PASSWORD_HASH", password_hash) + save_config_value("TEMPORARY_PASSWORD_HASH", &password_hash) } pub fn get_temporary_password_hash() -> Result { @@ -287,6 +287,6 @@ pub fn get_ssb_admin_ids() -> Result, PeachError> { // takes in a Vec and saves SSB_ADMIN_IDS as a json string representation of this vec pub fn save_ssb_admin_ids(ssb_admin_ids: Vec) -> Result, PeachError> { let ssb_admin_ids_as_json_str = serde_json::to_string(&ssb_admin_ids)?; - save_config_value("SSB_ADMIN_IDS", ssb_admin_ids_as_json_str)?; + save_config_value("SSB_ADMIN_IDS", &ssb_admin_ids_as_json_str)?; Ok(ssb_admin_ids) } From 8a6ad4ad61e9f74d3d9dae1898cb7449935833e2 Mon Sep 17 00:00:00 2001 From: notplants Date: Tue, 10 May 2022 13:08:32 +0200 Subject: [PATCH 5/8] Fix example --- peach-lib/examples/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peach-lib/examples/config.rs b/peach-lib/examples/config.rs index 2580150..756bfe4 100644 --- a/peach-lib/examples/config.rs +++ b/peach-lib/examples/config.rs @@ -5,7 +5,7 @@ fn main() { let v = get_config_value("ADDR").unwrap(); println!("ADDR: {}", v); - save_config_value("ADDR", "1.1.1.1".to_string()); + save_config_value("ADDR", "1.1.1.1"); let v = get_config_value("ADDR").unwrap(); println!("ADDR: {}", v); } From 3ae182caa9aa7edbb7e4b9ffe3e1be08069b4b27 Mon Sep 17 00:00:00 2001 From: notplants Date: Tue, 10 May 2022 13:23:39 +0200 Subject: [PATCH 6/8] Fix clippy warnings in peach-web --- peach-web/src/main.rs | 15 +-------------- peach-web/src/routes/settings/admin/configure.rs | 4 ++-- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/peach-web/src/main.rs b/peach-web/src/main.rs index 80966e2..cd7e356 100644 --- a/peach-web/src/main.rs +++ b/peach-web/src/main.rs @@ -26,8 +26,7 @@ use std::{ }; use lazy_static::lazy_static; -use log::{debug, info}; -use peach_lib::{config_manager, config_manager::YAML_PATH as PEACH_CONFIG}; +use log::{info}; // crate-local dependencies use config::Config; @@ -50,18 +49,6 @@ fn main() { // initialize logger env_logger::init(); - // check if /var/lib/peachcloud/config.yml exists - if !std::path::Path::new(PEACH_CONFIG).exists() { - debug!("PeachCloud configuration file not found; loading default values"); - // since we're in the intialisation phase, panic if the loading fails - let config = - config_manager::load_peach_config().expect("peachcloud configuration loading failed"); - - debug!("Saving default PeachCloud configuration values to file"); - // this ensures a config file is created if it does not already exist - config_manager::save_peach_config(config).expect("peachcloud configuration saving failed"); - } - // set ip address / hostname and port for the webserver // defaults to "127.0.0.1:8000" let addr_and_port = format!("{}:{}", CONFIG.addr, CONFIG.port); diff --git a/peach-web/src/routes/settings/admin/configure.rs b/peach-web/src/routes/settings/admin/configure.rs index fdb8621..4b823eb 100644 --- a/peach-web/src/routes/settings/admin/configure.rs +++ b/peach-web/src/routes/settings/admin/configure.rs @@ -13,8 +13,8 @@ pub fn build_template(request: &Request) -> PreEscaped { let (mut flash_name, mut flash_msg) = request.retrieve_flash(); // attempt to load peachcloud config file - let ssb_admins = match config_manager::load_peach_config() { - Ok(config) => Some(config.ssb_admin_ids), + let ssb_admins = match config_manager::get_ssb_admin_ids() { + Ok(ssb_admin_ids) => Some(ssb_admin_ids), // note: this will overwrite any received flash cookie values // TODO: find a way to include the `err` in the flash_msg // currently produces an error because we end up with Some(String) From f4c1bc11698b745b216ba8c4e0c8ebb7bc5dde75 Mon Sep 17 00:00:00 2001 From: notplants Date: Tue, 10 May 2022 13:25:53 +0200 Subject: [PATCH 7/8] Fix cargo fmt in peach-web --- peach-web/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peach-web/src/main.rs b/peach-web/src/main.rs index cd7e356..b43d669 100644 --- a/peach-web/src/main.rs +++ b/peach-web/src/main.rs @@ -26,7 +26,7 @@ use std::{ }; use lazy_static::lazy_static; -use log::{info}; +use log::info; // crate-local dependencies use config::Config; From 610d60d98911294995330c14f6b3ac5b878e8520 Mon Sep 17 00:00:00 2001 From: notplants Date: Wed, 11 May 2022 10:34:53 +0200 Subject: [PATCH 8/8] Fix typo --- peach-lib/src/config_manager.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peach-lib/src/config_manager.rs b/peach-lib/src/config_manager.rs index b02c85a..5c9a849 100644 --- a/peach-lib/src/config_manager.rs +++ b/peach-lib/src/config_manager.rs @@ -159,7 +159,7 @@ pub fn save_config_value(key: &str, value: &str) -> Result