use std::collections::HashMap; use serde::{Serialize, Deserialize}; //use serde_json::value::{to_value, Value}; use log::error; use pasetoken_lib::ConfigPaSeToken; use pasetors::footer::Footer; use crate::{ FILE_SCHEME, defs::{ Local, TotpAlgorithm, TotpMode, deserialize_totp_algorithm, deserialize_totp_mode, FromFile, load_from_file, load_dict_from_file, }, }; use std::path::Path; // use crate::tools::generate_uuid; // fn default_server_uid() -> String { // generate_uuid(String::from("abcdef0123456789")) // } fn default_config_resource() -> String { "/".to_string() } fn default_config_array_resource() -> Vec { Vec::new() } fn default_config_serv_paths()-> Vec { Vec::new() } fn default_config_dflt_lang() -> String { "en".to_string() } fn default_config_org() -> String { "".to_string() } fn default_config_empty() -> String { "".to_string() } fn default_config_locales() -> HashMap { HashMap::new() } fn default_config_tpls() -> HashMap { HashMap::new() } fn default_is_restricted() -> bool { false } fn default_config_use_mail() -> bool { false } fn default_config_use_token() -> bool { false } fn default_config_invite_expire() -> u64 { 300 } fn default_config_web_menu_items() -> Vec { Vec::new() } fn default_web_menu_item_roles() -> Vec { Vec::new() } fn default_auth_roles() -> Vec { Vec::new() } fn default_sub_menu_items() -> Vec { Vec::new() } fn default_config_totp_digits() -> usize { 6 } fn default_config_totp_algorithm() -> TotpAlgorithm { TotpAlgorithm::default() } fn default_config_totp_mode() -> TotpMode { TotpMode::default() } fn default_config_password_score() -> u8 { 0 } fn default_config_trace_level() -> u8 { 1 } #[derive(Debug, Clone, Serialize, Deserialize,Default)] pub struct SubMenuItem { #[serde(default = "default_config_empty")] pub typ: String, #[serde(default = "default_config_empty")] pub srctyp: String, #[serde(default = "default_config_empty")] pub text: String, #[serde(default = "default_config_empty")] pub url: String, #[serde(default = "default_web_menu_item_roles")] pub roles: Vec, } #[derive(Debug, Clone, Serialize, Deserialize,Default)] pub struct WebMenuItem { #[serde(default = "default_config_resource")] pub root_path: String, #[serde(default = "default_config_empty")] pub typ: String, #[serde(default = "default_config_empty")] pub srctyp: String, #[serde(default = "default_config_empty")] pub text: String, #[serde(default = "default_config_empty")] pub url: String, #[serde(default = "default_web_menu_item_roles")] pub roles: Vec, #[serde(default = "default_sub_menu_items")] pub items: Vec, } #[derive(Debug, Clone, Serialize, Deserialize,Default)] pub struct DataMenuItems { #[serde(default = "default_config_web_menu_items")] pub web_menu_items: Vec, } impl FromFile for DataMenuItems { fn fix_root_path(&mut self, _root_path: String ) { } } #[derive(Debug, Clone, Serialize, Deserialize,Default)] pub struct UiConfig { #[serde(default = "default_config_empty")] pub css_link: String, #[serde(default = "default_config_empty")] pub js_link: String, #[serde(default = "default_config_empty")] pub other_css_link: String, #[serde(default = "default_config_empty")] pub other_js_link: String, #[serde(default = "default_config_empty")] pub main_js_link: String, #[serde(default = "default_config_empty")] pub utils_js_link: String, #[serde(default = "default_config_web_menu_items")] pub web_menu_items: Vec, } #[derive(Debug, Clone, Serialize, Deserialize,Default)] pub struct DataServPath { #[serde(default = "default_config_serv_paths")] pub serv_paths: Vec, } impl FromFile for DataServPath { fn fix_root_path(&mut self, _root_path: String ) { } } /// ServPath collects dir path to server as static content #[derive(Debug, Clone, Serialize, Deserialize,Default)] pub struct ServPath { #[serde(default = "default_config_empty")] pub src_path: String, #[serde(default = "default_config_empty")] pub url_path: String, #[serde(default = "default_config_empty")] pub not_found: String, #[serde(default = "default_config_empty")] pub not_auth: String, #[serde(default = "default_is_restricted")] pub is_restricted: bool, #[serde(default = "default_config_empty")] pub redirect_to: String, } /// Config collects config values. #[derive(Debug, Clone, Serialize, Deserialize,Default)] pub struct Config { pub hostport: String, pub bind: String, pub port: u16, pub protocol: String, #[serde(default = "default_config_org")] pub org: String, pub name: String, pub verbose: u8, pub prefix: String, pub resources_path: String, pub cert_file: String, pub key_file: String, //pub certs_store_path: String, //pub cert_file_sufix: String, #[serde(default = "default_config_array_resource")] pub allow_origin: Vec, #[serde(default = "default_config_array_resource")] pub langs: Vec, #[serde(default = "default_config_dflt_lang")] pub dflt_lang: String, #[serde(default = "default_config_empty")] pub path_locales_config: String, #[serde(default = "default_config_locales")] pub locales: HashMap, // Some paths #[serde(default = "default_config_resource")] pub root_path: String, #[serde(default = "default_config_resource")] pub defaults_path: String, #[serde(default = "default_config_serv_paths")] pub serv_paths: Vec, #[serde(default = "default_config_resource")] pub docs_index: String, #[serde(default = "default_config_resource")] pub templates_path: String, #[serde(default = "default_config_resource")] pub html_url: String, #[serde(default = "default_config_resource")] pub assets_url: String, #[serde(default = "default_config_resource")] pub users_store_uri: String, #[serde(default = "default_config_empty")] pub user_store_access: String, #[serde(default = "default_auth_roles")] pub auth_roles: Vec, #[serde(default = "default_config_empty")] pub trace_store_uri: String, #[serde(default = "default_config_trace_level")] pub trace_level: u8, #[serde(default = "default_config_empty")] pub signup_mode: String, #[serde(default = "default_config_invite_expire")] pub invite_expire: u64, #[serde(default = "default_config_use_token")] pub use_token: bool, #[serde(default = "default_config_totp_digits")] pub totp_digits: usize, #[serde(default = "default_config_totp_mode", deserialize_with = "deserialize_totp_mode")] pub totp_mode: TotpMode, #[serde(default = "default_config_totp_algorithm", deserialize_with = "deserialize_totp_algorithm")] pub totp_algorithm: TotpAlgorithm, #[serde(default = "default_config_password_score")] pub password_score: u8, #[serde(default = "default_config_empty")] pub admin_fields: String, #[serde(default = "default_config_empty")] pub mail_from: String, #[serde(default = "default_config_empty")] pub mail_reply_to: String, #[serde(default = "default_config_use_mail")] pub use_mail: bool, #[serde(default = "default_config_empty")] pub smtp: String, #[serde(default = "default_config_empty")] pub smtp_auth: String, // #[cfg(feature = "authstore")] #[serde(default = "default_config_resource")] pub authz_store_uri: String, // #[cfg(feature = "casbin")] #[serde(default = "default_config_empty")] pub authz_model_path: String, // #[cfg(feature = "casbin")] #[serde(default = "default_config_empty")] pub authz_policy_path: String, #[serde(default = "default_config_empty")] pub session_store_uri: String, #[serde(default = "default_config_empty")] pub session_store_file: String, pub session_expire: u64, pub paseto: ConfigPaSeToken, pub ui: UiConfig, #[serde(default = "default_config_tpls")] pub tpls: HashMap, #[serde(default = "default_config_resource")] pub path_menu_items: String, #[serde(default = "default_config_resource")] pub path_serv_paths: String, } impl FromFile for Config { fn fix_root_path(&mut self, root_path: String ) { if root_path != self.root_path { self.root_path = root_path.to_owned(); } if self.root_path.is_empty() || ! Path::new(&self.root_path).exists() { return; } } } impl Config { fn fix_item_path(&mut self, item: String ) -> String { if !item.is_empty() && ! Path::new(&item).exists() { format!("{}/{}",&self.root_path,&item) } else { item } } pub fn load_items(&mut self) { self.fix_root_path::(self.root_path.to_owned()); if !self.path_menu_items.is_empty() { self.path_menu_items = self.fix_item_path(self.path_menu_items.to_owned()); let data_menu_items = load_from_file(&self.path_menu_items.to_owned(), "menu_items").unwrap_or_else(|e|{ error!("Error loading menu_items from {}: {}",&self.path_menu_items,e); DataMenuItems::default() }); self.ui.web_menu_items = data_menu_items.web_menu_items; } if !self.path_serv_paths.is_empty() { self.path_serv_paths = self.fix_item_path(self.path_serv_paths.to_owned()); let data_serv_paths = load_from_file(&self.path_serv_paths.to_owned(), "serv_paths").unwrap_or_else(|e|{ error!("Error loading serv_paths from {}: {}",&self.path_serv_paths,e); DataServPath::default() }); self.serv_paths = data_serv_paths.serv_paths; } if !self.path_locales_config.is_empty() { self.path_locales_config = self.fix_item_path(self.path_locales_config.to_owned()); self.locales = load_dict_from_file(&self.path_locales_config.to_owned(), "locales").unwrap_or_else(|e|{ error!("Error loading locales from {}: {}",&self.path_locales_config,e); HashMap::new() }); } if self.users_store_uri.starts_with(FILE_SCHEME) { self.users_store_uri = format!("{}{}", FILE_SCHEME, self.fix_item_path(self.users_store_uri.replace(FILE_SCHEME,""))); } if self.session_store_uri.starts_with(FILE_SCHEME) { self.session_store_uri = format!("{}{}", FILE_SCHEME, self.fix_item_path(self.session_store_uri.replace(FILE_SCHEME,""))); } if self.trace_store_uri.starts_with(FILE_SCHEME) { self.trace_store_uri = format!("{}{}", FILE_SCHEME, self.fix_item_path(self.trace_store_uri.replace(FILE_SCHEME,""))); } self.cert_file = self.fix_item_path(self.cert_file.to_owned()); self.key_file = self.fix_item_path(self.key_file.to_owned()); self.templates_path = self.fix_item_path(self.templates_path.to_owned()); self.defaults_path = self.fix_item_path(self.defaults_path.to_owned()); #[cfg(feature = "authstore")] if self.authz_store_uri.starts_with(FILE_SCHEME) { self.authz_store_uri = format!("{}{}", FILE_SCHEME, self.fix_item_path(self.authz_store_uri.replace(FILE_SCHEME,""))); } #[cfg(feature = "casbin")] { self.authz_model_path = self.fix_item_path(self.authz_model_path.to_owned()); self.authz_policy_path = self.fix_item_path(self.authz_policy_path.to_owned()); } self.paseto.public_path = self.fix_item_path(self.paseto.public_path.to_owned()); self.paseto.secret_path = self.fix_item_path(self.paseto.secret_path.to_owned()); (self.paseto.public_data, self.paseto.secret_data) = self.paseto.load_data(); self.paseto.footer = ConfigPaSeToken::make_footer( self.paseto.map_footer.to_owned() ).unwrap_or(Footer::new()); } #[allow(dead_code)] pub fn to_json(&self) -> String { serde_json::to_string(self).unwrap_or_else(|e|{ println!("Error to convert Config to json: {}",e); String::from("") }) } // #[allow(dead_code)] // pub fn st_html_path(&self) -> &'static str { // Box::leak(self.html_path.to_owned().into_boxed_str()) // } #[allow(dead_code)] pub fn full_html_url(&self, url: &str) -> String { format!("{}://{}:{}/{}", &self.protocol,&self.bind,&self.port, url ) } }