106 lines
3.8 KiB
Rust

mod general_config;
mod providers;
use std::hash::Hash;
use std::{collections::HashMap, sync::OnceLock};
use std::fs;
use std::path::Path;
use clap::builder::Str;
use serde::{ser, Deserialize};
use crate::services::beggars::Beggars;
use crate::services::providers::Providers;
use crate::errors::AutoDecryptError;
use general_config::{Platform, TomlAppConfig};
#[derive(Debug, Deserialize)]
pub(crate) struct AppConfig {
pub(crate) port: u16,
pub(crate) addresses: Vec<String>,
pub(crate) platform: Platform,
pub(crate) ssh_known_host_file: String,
pub(crate) user_confirmation_expiration: i64,
pub(crate) db_file: String,
pub(crate) crypto_key: String,
pub(crate) beggars: HashMap<String, Beggars>, // We request to unlock owned services
pub(crate) providers: HashMap<String, Providers>, // We offer to unlock these services
}
impl Default for AppConfig {
fn default() -> Self {
AppConfig {
port: 8080,
addresses: vec!["*".to_string()],
beggars: HashMap::new(),
crypto_key: "default_key_change_me".to_string(),
providers: HashMap::new(),
user_confirmation_expiration: 60 * 60 * 24, // 24 hours
platform: Platform::OMV,
ssh_known_host_file: "".to_string(),
db_file: "/var/auto-decrypt/db.sqlite".to_string(),
}
}
}
impl AppConfig {
fn from_toml(toml_config: Option<TomlAppConfig>, base_config_dir: &Path) -> Self {
let default = AppConfig::default();
if let Some(toml_config) = toml_config {
return AppConfig {
port: toml_config.port.unwrap_or(default.port),
addresses: toml_config.addresses.unwrap_or(default.addresses),
crypto_key: toml_config.crypto_key.unwrap_or(default.crypto_key),
platform: toml_config.platform.unwrap_or(default.platform),
user_confirmation_expiration: toml_config.user_confirmation_expiration.unwrap_or(default.user_confirmation_expiration),
ssh_known_host_file: toml_config.ssh_known_host_file.unwrap_or(default.ssh_known_host_file),
db_file: toml_config.db_file.unwrap_or(default.db_file),
beggars: toml_config.beggars.unwrap_or(default.beggars),
providers: toml_config.providers.and_then(|providers|
Some(providers.into_iter().map(|(name, service)|
(name, service.to_internal(base_config_dir).expect("Err"))
).collect::<HashMap<String, Providers>>())
).unwrap_or(default.providers),
};
}
return default;
}
}
impl AppConfig {
pub fn load_from_file(path: &Path ) -> Result<Self, AutoDecryptError> {
if !path.is_dir(){
return Err(AutoDecryptError::ConfigurationError { comment: ("The provided configuration path is not a Folder!".to_string()) })
}
let contents = fs::read_to_string(path.join("config.toml"))
.unwrap_or_else(|err| {
eprintln!("Failed to read config file: {err}. Using default configuration.");
return String::new(); // Return empty string to fall back to default
});
let basic_config = AppConfig::from_toml(
toml::from_str::<TomlAppConfig>(&contents)
.map_err(|err| {
eprintln!("Failed to parse config file: {err}. Using default configuration.");
err
})
.ok()
, path);
return Ok(basic_config);
}
}
pub static CONFIG: OnceLock<AppConfig> = OnceLock::new();
pub fn init_config(file: &str) {
let config = AppConfig::load_from_file(Path::new(file))
.expect("Failed to load configuration file");
CONFIG.set(config).expect("AppConfig can only be initialized once");
}