use std::{env, fs, path::Path}; use anyhow::{Result, Context, anyhow}; use fully_pub::fully_pub; use log::info; use crate::{ consts::{DEFAULT_CONFIG_PATH, DEFAULT_DB_PATH, DEFAULT_SIGNING_KEY_PATH}, database::prepare_database, models::config::Config, repositories::storage::Storage }; /// get server config fn get_config(path: String) -> Result { let inp_def_yaml = fs::read_to_string(path) .expect("Should have been able to read the the config file"); toml::from_str(&inp_def_yaml) .map_err(|e| anyhow!("Failed to parse config, {:?}", e)) } #[fully_pub] struct StartKernelConfig { config_path: Option, database_path: Option, } #[derive(Debug, Clone)] #[fully_pub] struct AppSecrets { /// RSA keypair (public, private) used to signed the JWT issued by minauthator in PEM conainer format signing_keypair: (Vec, Vec) } #[derive(Debug, Clone)] #[fully_pub] struct ComputedConfig { signing_public_key: Vec, signing_private_key: Vec } #[derive(Debug, Clone)] #[fully_pub] struct KernelContext { config: Config, secrets: AppSecrets, storage: Storage } fn get_signing_keypair(key_path: &str) -> Result<(Vec, Vec)> { let key_path = Path::new(key_path); let pub_key_path = key_path.with_extension("pub"); let private_key: Vec = fs::read_to_string(&key_path) .context(format!("Failed to read private key from path {:?}.", key_path))? .as_bytes().to_vec(); let public_key: Vec = fs::read_to_string(&pub_key_path) .context(format!("Failed to read public key from path {:?}.", pub_key_path))? .as_bytes().to_vec(); Ok((public_key, private_key)) } pub async fn get_kernel_context(start_config: StartKernelConfig) -> Result { env_logger::init(); let _ = dotenvy::dotenv(); let database_path = &start_config.database_path.unwrap_or(DEFAULT_DB_PATH.to_string()); info!("Using database file at {}", database_path); let storage = prepare_database(database_path).await.context("Could not prepare db.")?; let config_path = start_config.config_path.unwrap_or(DEFAULT_CONFIG_PATH.to_string()); info!("Using config file at {}", &config_path); let config: Config = get_config(config_path) .expect("Cannot get config."); let signing_key_path = config.signing_key.clone().unwrap_or(DEFAULT_SIGNING_KEY_PATH.to_string()); // optionally load dotenv file let _ = dotenvy::dotenv(); let secrets = AppSecrets { signing_keypair: get_signing_keypair(&signing_key_path)? }; Ok(KernelContext { config, secrets, storage }) }