extern crate serde; use std::env; use std::fs; use serde::Deserialize; pub type Pass = String; const CONFIG_PATH_DEFAULT: &str = "config.toml"; /// Returns config path from envioronment or a provided default value pub fn get_config_path() -> String { match env::var("CONFIG_PATH") { Ok(config_path) => config_path, Err(_) => String::from(CONFIG_PATH_DEFAULT), } } // Tries to read configuration from file, failing that from the environment, // panics if it can't pub fn read_config() -> Config { match read_config_from_file() { Ok(config) => config, Err(err) => { println!("{}", err); match read_config_from_env() { Ok(config) => config, Err(err) => panic!("{}", err), } } } } /// Tries to read configuration from file pub fn read_config_from_file() -> Result { let config_path = get_config_path(); let contents = fs::read_to_string(&config_path) .map_err(|err| format!("Failed to open config file at {}: {}", config_path, err))?; let config: Config = toml::from_str(contents.as_str()) .map_err(|err| format!("Failed to parse config file at {}: {}", config_path, err))?; println!("Config read from file at {}", config_path); Ok(config) } // Tries to read configuration from environment pub fn read_config_from_env() -> Result { let config = envy::prefixed("APP_") .from_env() .map_err(|err| format!("Error parsing config from env: {}", err))?; println!("Config read from environment"); Ok(config) } #[derive(Deserialize)] #[serde(deny_unknown_fields)] /// Contains all config values for LDAP syncing pub struct Config { // Bitwarden connection config vaultwarden_url: String, vaultwarden_admin_token: String, vaultwarden_root_cert_file: Option, // LDAP Connection config ldap_host: String, ldap_scheme: Option, ldap_ssl: Option, ldap_starttls: Option, ldap_port: Option, ldap_no_tls_verify: Option, // LDAP auth config ldap_bind_dn: String, ldap_bind_password: Pass, // LDAP search config ldap_search_base_dn: String, ldap_search_filter: String, // LDAP record attributes ldap_mail_field: Option, // Interval syncing config ldap_sync_interval_seconds: Option, // Should start background sync loop ldap_sync_loop: Option, } impl Config { /// Create a config instance from file pub fn from_file() -> Config { read_config() } pub fn get_vaultwarden_url(&self) -> String { self.vaultwarden_url.clone() } pub fn get_vaultwarden_admin_token(&self) -> String { self.vaultwarden_admin_token.clone() } pub fn get_vaultwarden_root_cert_file(&self) -> String { match &self.vaultwarden_root_cert_file { Some(vaultwarden_root_cert_file) => vaultwarden_root_cert_file.clone(), None => String::new(), } } pub fn get_ldap_url(&self) -> String { format!( "{}://{}:{}", self.get_ldap_scheme(), self.get_ldap_host(), self.get_ldap_port() ) } pub fn get_ldap_host(&self) -> String { self.ldap_host.clone() } pub fn get_ldap_scheme(&self) -> String { match &self.ldap_scheme { Some(ldap_scheme) => ldap_scheme.clone(), None => { if self.get_ldap_ssl() { String::from("ldaps") } else { String::from("ldap") } } } } pub fn get_ldap_ssl(&self) -> bool { self.ldap_ssl.unwrap_or(false) } pub fn get_ldap_starttls(&self) -> bool { self.ldap_starttls.unwrap_or(false) } pub fn get_ldap_no_tls_verify(&self) -> bool { self.ldap_no_tls_verify.unwrap_or(false) } pub fn get_ldap_port(&self) -> u16 { match self.ldap_port { Some(ldap_port) => ldap_port, None => { if self.get_ldap_ssl() { 636 } else { 389 } } } } pub fn get_ldap_bind_dn(&self) -> String { self.ldap_bind_dn.clone() } pub fn get_ldap_bind_password(&self) -> String { self.ldap_bind_password.clone() } pub fn get_ldap_search_base_dn(&self) -> String { self.ldap_search_base_dn.clone() } pub fn get_ldap_search_filter(&self) -> String { self.ldap_search_filter.clone() } pub fn get_ldap_mail_field(&self) -> String { match &self.ldap_mail_field { Some(mail_field) => mail_field.clone(), None => String::from("mail"), } } pub fn get_ldap_sync_interval_seconds(&self) -> u64 { self.ldap_sync_interval_seconds.unwrap_or(60) } pub fn get_ldap_sync_loop(&self) -> bool { self.ldap_sync_loop.unwrap_or(true) } }