use std::path::{Path, PathBuf}; use clap::Parser; use crate::constants::{ APP_NAME, CLIENTS_LIST_FILE, OIDC_PROVIDER_CB_URI, PROVIDERS_LIST_FILE, USERS_LIST_FILE, }; /// Basic OIDC provider #[derive(Parser, Debug, Clone)] #[clap(author, version, about, long_about = None)] pub struct AppConfig { /// Listen address #[clap(short, long, env, default_value = "0.0.0.0:8000")] pub listen_address: String, /// Storage path #[clap(short, long, env)] pub storage_path: String, /// App token token #[clap(short, long, env, default_value = "")] pub token_key: String, /// Website origin #[clap(short, long, env, default_value = "http://localhost:8000")] pub website_origin: String, /// Proxy IP, might end with a star "*" #[clap(short, long, env)] pub proxy_ip: Option, /// IP location service API /// /// Up instance of IP location service : https://gitlab.com/pierre42100/iplocationserver /// /// Example: "https://api.geoip.rs" #[arg(long, short, env)] pub ip_location_service: Option, } lazy_static::lazy_static! { static ref ARGS: AppConfig = { let mut config = AppConfig::parse(); // In debug mode only, use dummy token if cfg!(debug_assertions) && config.token_key.is_empty() { config.token_key = String::from_utf8_lossy(&[32; 64]).to_string(); } config }; } impl AppConfig { /// Get parsed command line arguments pub fn get() -> &'static AppConfig { &ARGS } pub fn secure_cookie(&self) -> bool { self.website_origin.starts_with("https:") } pub fn storage_path(&self) -> &Path { self.storage_path.as_ref() } pub fn users_file(&self) -> PathBuf { self.storage_path().join(USERS_LIST_FILE) } pub fn clients_file(&self) -> PathBuf { self.storage_path().join(CLIENTS_LIST_FILE) } pub fn providers_file(&self) -> PathBuf { self.storage_path().join(PROVIDERS_LIST_FILE) } pub fn full_url(&self, uri: &str) -> String { if uri.starts_with('/') { format!("{}{}", self.website_origin, uri) } else { format!("{}/{}", self.website_origin, uri) } } /// Get the URL where a upstream OpenID provider should redirect /// the user after an authentication pub fn oidc_provider_redirect_url(&self) -> String { AppConfig::get().full_url(OIDC_PROVIDER_CB_URI) } pub fn domain_name(&self) -> &str { self.website_origin.split('/').nth(2).unwrap_or(APP_NAME) } /// Get the domain without the port pub fn domain_name_without_port(&self) -> &str { let domain = self.domain_name(); domain.split_once(':').map(|i| i.0).unwrap_or(domain) } } #[cfg(test)] mod test { use crate::data::app_config::AppConfig; #[test] fn verify_cli() { use clap::CommandFactory; AppConfig::command().debug_assert() } }