cli: avoid data-dir initialization for version; create db parent dirs; redact generated passwords in CLI output
- Prevent 'nx9-wg version' from creating data directories by avoiding database initialization. - Create parent directories when an explicit --database path is provided. - Redact printed generated administrator passwords; announce file path or redact instead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
commit
2ac6c81dfe
140 files changed
+31342
No files matched your search
@@ -0,0 +1,164 @@
|
||||
//! Automated validation suite for environment variable namespace and precedence.
|
||||
|
||||
use nx9_wg_core::config::{AppConfig, BootstrapConfig};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Mutex;
|
||||
|
||||
static ENV_MUTEX: Mutex<()> = Mutex::new(());
|
||||
|
||||
#[test]
|
||||
fn test_nx9_wg_env_variable_precedence_and_overrides() {
|
||||
let _lock = ENV_MUTEX.lock().unwrap();
|
||||
let mut config = AppConfig::default();
|
||||
|
||||
// Set canonical NX9_WG_ environment variables
|
||||
unsafe {
|
||||
std::env::set_var("NX9_WG_CONFIG", "/custom/etc/config.toml");
|
||||
std::env::set_var("NX9_WG_DATA_DIR", "/custom/var/data");
|
||||
std::env::set_var("NX9_WG_LISTEN_ADDR", "127.0.0.1:9090");
|
||||
std::env::set_var("NX9_WG_LOG_LEVEL", "warn");
|
||||
std::env::set_var("NX9_WG_SESSION_TIMEOUT", "72");
|
||||
std::env::set_var("NX9_WG_RECONCILIATION_INTERVAL", "15");
|
||||
std::env::set_var("NX9_WG_BACKUP_DIR", "/custom/backups");
|
||||
std::env::set_var("NX9_WG_BACKUP_MAX_COUNT", "20");
|
||||
std::env::set_var("NX9_WG_BACKUP_SCHEDULE", "0 3 * * *");
|
||||
std::env::set_var("NX9_WG_ADMIN_USERNAME", "superadmin");
|
||||
std::env::set_var("NX9_WG_ADMIN_PASSWORD", "SuperSecretPW987!");
|
||||
}
|
||||
|
||||
config.apply_env_overrides().expect("apply env overrides");
|
||||
|
||||
assert_eq!(config.config_file, PathBuf::from("/custom/etc/config.toml"));
|
||||
assert_eq!(config.data_dir, PathBuf::from("/custom/var/data"));
|
||||
assert_eq!(config.bind_address, "127.0.0.1:9090".parse().unwrap());
|
||||
assert_eq!(config.log_level, "warn");
|
||||
assert_eq!(config.session_expiry_hours, 72);
|
||||
assert_eq!(config.reconciliation_interval_secs, 15);
|
||||
assert_eq!(config.backup.dir, PathBuf::from("/custom/backups"));
|
||||
assert_eq!(config.backup.max_count, 20);
|
||||
assert_eq!(config.backup.schedule, Some("0 3 * * *".to_string()));
|
||||
|
||||
let boot = config.bootstrap.expect("bootstrap should be present");
|
||||
assert_eq!(boot.admin_username, Some("superadmin".to_string()));
|
||||
assert_eq!(boot.admin_password, Some("SuperSecretPW987!".to_string()));
|
||||
|
||||
// Clean up
|
||||
unsafe {
|
||||
std::env::remove_var("NX9_WG_CONFIG");
|
||||
std::env::remove_var("NX9_WG_DATA_DIR");
|
||||
std::env::remove_var("NX9_WG_LISTEN_ADDR");
|
||||
std::env::remove_var("NX9_WG_LOG_LEVEL");
|
||||
std::env::remove_var("NX9_WG_SESSION_TIMEOUT");
|
||||
std::env::remove_var("NX9_WG_RECONCILIATION_INTERVAL");
|
||||
std::env::remove_var("NX9_WG_BACKUP_DIR");
|
||||
std::env::remove_var("NX9_WG_BACKUP_MAX_COUNT");
|
||||
std::env::remove_var("NX9_WG_BACKUP_SCHEDULE");
|
||||
std::env::remove_var("NX9_WG_ADMIN_USERNAME");
|
||||
std::env::remove_var("NX9_WG_ADMIN_PASSWORD");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_env_variable_values() {
|
||||
let _lock = ENV_MUTEX.lock().unwrap();
|
||||
let mut config = AppConfig::default();
|
||||
unsafe {
|
||||
std::env::set_var("NX9_WG_LISTEN_ADDR", "invalid-ip-and-port");
|
||||
}
|
||||
assert!(config.apply_env_overrides().is_err());
|
||||
unsafe {
|
||||
std::env::remove_var("NX9_WG_LISTEN_ADDR");
|
||||
}
|
||||
|
||||
unsafe {
|
||||
std::env::set_var("NX9_WG_SESSION_TIMEOUT", "not-a-number");
|
||||
}
|
||||
assert!(config.apply_env_overrides().is_err());
|
||||
unsafe {
|
||||
std::env::remove_var("NX9_WG_SESSION_TIMEOUT");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_secret_redaction() {
|
||||
let boot = BootstrapConfig {
|
||||
admin_username: Some("admin".to_string()),
|
||||
admin_password: Some("secret12345".to_string()),
|
||||
};
|
||||
let formatted = format!("{boot:?}");
|
||||
assert!(!formatted.contains("secret12345"));
|
||||
assert!(formatted.contains("[REDACTED]"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_database_path_resolution() {
|
||||
// Default database path should be data_dir/nx9-wg.db
|
||||
let config = AppConfig::default();
|
||||
let expected_db = config.data_dir.join("nx9-wg.db");
|
||||
assert_eq!(expected_db, PathBuf::from("/var/lib/nx9-wg/nx9-wg.db"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_explicit_database_dir_override() {
|
||||
let _lock = ENV_MUTEX.lock().unwrap();
|
||||
let config = AppConfig::default();
|
||||
// When --database is explicitly provided, it should be used directly
|
||||
// The test verifies the default path is what we expect
|
||||
assert_eq!(config.data_dir, PathBuf::from("/var/lib/nx9-wg"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_backup_directory_consistency() {
|
||||
let config = AppConfig::default();
|
||||
// Backup directory should always be consistent: /var/lib/nx9-wg/backups
|
||||
assert_eq!(config.backup.dir, PathBuf::from("/var/lib/nx9-wg/backups"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nx9_wg_database_env_var() {
|
||||
let _lock = ENV_MUTEX.lock().unwrap();
|
||||
// NX9_WG_DATABASE should be honored via CLI args
|
||||
// This test documents that the env var is in the canonical namespace
|
||||
let cli_args = &["--database", "/custom/path/test.db"];
|
||||
// We're verifying this is the correct pattern to use
|
||||
assert_eq!(cli_args[0], "--database");
|
||||
assert_eq!(cli_args[1], "/custom/path/test.db");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_canonical_env_namespace_only() {
|
||||
let _lock = ENV_MUTEX.lock().unwrap();
|
||||
// Verify only NX9_WG_* variables are used
|
||||
let mut config = AppConfig::default();
|
||||
|
||||
// Try setting a non-canonical variable - should be ignored
|
||||
unsafe {
|
||||
std::env::set_var("RUST_LOG", "debug");
|
||||
std::env::set_var("NX9_LOG_LEVEL", "error");
|
||||
}
|
||||
|
||||
config.apply_env_overrides().expect("apply env overrides");
|
||||
|
||||
// These non-canonical variables should be ignored
|
||||
assert_eq!(config.log_level, "info"); // Should remain default
|
||||
|
||||
// Clean up
|
||||
unsafe {
|
||||
std::env::remove_var("RUST_LOG");
|
||||
std::env::remove_var("NX9_LOG_LEVEL");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_bind_address_is_localhost() {
|
||||
let config = AppConfig::default();
|
||||
// Verify bind address default
|
||||
assert_eq!(config.bind_address, "127.0.0.1:8080".parse().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_reconciliation_interval() {
|
||||
let config = AppConfig::default();
|
||||
// Default reconciliation interval should be 60 seconds
|
||||
assert_eq!(config.reconciliation_interval_secs, 60);
|
||||
}
|
||||
Reference in new issue
Block a user