mod common;
use serial_test::serial;
use std::process::Command;
use torc::client::apis;
use torc::client::apis::configuration::Configuration;
fn get_exe_path(name: &str) -> String {
common::get_exe_path(name)
}
#[test]
#[serial(auth)]
fn test_reload_auth_success() {
let server = common::start_server_with_required_auth();
let admin_config = server.config_for_user("owner");
let result = apis::access_control_api::reload_auth(&admin_config);
assert!(result.is_ok(), "reload_auth should succeed for admin");
let body = result.unwrap();
assert_eq!(body.message, "Auth credentials reloaded successfully");
assert!(body.user_count > 0, "user_count should be > 0");
}
#[test]
#[serial(auth)]
fn test_reload_auth_forbidden() {
let server = common::start_server_with_required_auth();
let dave_config = server.config_for_user("dave");
let result = apis::access_control_api::reload_auth(&dave_config);
assert!(result.is_err(), "reload_auth should fail for non-admin");
}
#[test]
#[serial(auth)]
fn test_reload_auth_new_user_can_authenticate() {
let server = common::start_server_with_required_auth();
let admin_config = server.config_for_user("owner");
let htpasswd_path = server.htpasswd_path();
let status = Command::new(get_exe_path("./target/debug/torc-htpasswd"))
.arg("add")
.arg("--file")
.arg(&htpasswd_path)
.arg("--password")
.arg("correct horse battery staple")
.arg("--cost")
.arg("4")
.arg("eve")
.status()
.expect("Failed to run torc-htpasswd");
assert!(status.success(), "torc-htpasswd add should succeed");
let eve_config = server.config_for_user("eve");
let eve_result = apis::system_api::ping(&eve_config);
assert!(
eve_result.is_err(),
"Eve should NOT be able to authenticate before reload"
);
let reload_result = apis::access_control_api::reload_auth(&admin_config);
assert!(reload_result.is_ok(), "reload_auth should succeed");
let eve_result = apis::system_api::ping(&eve_config);
assert!(
eve_result.is_ok(),
"Eve should be able to authenticate after reload"
);
}
#[test]
#[serial(auth)]
fn test_reload_auth_removed_user_rejected() {
let server = common::start_server_with_required_auth();
let admin_config = server.config_for_user("owner");
let htpasswd_path = server.htpasswd_path();
let _ = Command::new(get_exe_path("./target/debug/torc-htpasswd"))
.arg("add")
.arg("--file")
.arg(&htpasswd_path)
.arg("--password")
.arg("correct horse battery staple")
.arg("--cost")
.arg("4")
.arg("carol")
.status();
let _ = apis::access_control_api::reload_auth(&admin_config);
let carol_config = server.config_for_user("carol");
let carol_result = apis::system_api::ping(&carol_config);
assert!(
carol_result.is_ok(),
"Carol should be able to authenticate initially"
);
let status = Command::new(get_exe_path("./target/debug/torc-htpasswd"))
.arg("remove")
.arg("--file")
.arg(&htpasswd_path)
.arg("carol")
.status()
.expect("Failed to run torc-htpasswd");
assert!(status.success(), "torc-htpasswd remove should succeed");
let reload_result = apis::access_control_api::reload_auth(&admin_config);
assert!(reload_result.is_ok(), "reload_auth should succeed");
let carol_result = apis::system_api::ping(&carol_config);
assert!(
carol_result.is_err(),
"Carol should NOT be able to authenticate after being removed and reloaded"
);
}
#[test]
#[serial(auth)]
fn test_reload_auth_clears_credential_cache() {
let server = common::start_server_with_required_auth();
let admin_config = server.config_for_user("owner");
let htpasswd_path = server.htpasswd_path();
let _ = Command::new(get_exe_path("./target/debug/torc-htpasswd"))
.arg("add")
.arg("--file")
.arg(&htpasswd_path)
.arg("--password")
.arg("correct horse battery staple")
.arg("--cost")
.arg("4")
.arg("bob")
.status();
let _ = apis::access_control_api::reload_auth(&admin_config);
let bob_config = server.config_for_user("bob");
let bob_result = apis::system_api::ping(&bob_config);
assert!(bob_result.is_ok(), "Bob should authenticate successfully");
let status = Command::new(get_exe_path("./target/debug/torc-htpasswd"))
.arg("add")
.arg("--file")
.arg(&htpasswd_path)
.arg("--password")
.arg("new super secret password!!")
.arg("--cost")
.arg("4")
.arg("bob")
.status()
.expect("Failed to run torc-htpasswd");
assert!(
status.success(),
"torc-htpasswd add (update) should succeed"
);
let reload_result = apis::access_control_api::reload_auth(&admin_config);
assert!(reload_result.is_ok(), "reload_auth should succeed");
let bob_old_result = apis::system_api::ping(&bob_config);
assert!(
bob_old_result.is_err(),
"Bob's old password should NOT work after reload"
);
let mut bob_new_config = Configuration::new();
bob_new_config.base_path = server.config.base_path.clone();
bob_new_config.basic_auth = Some((
"bob".to_string(),
Some("new super secret password!!".to_string()),
));
let bob_new_result = apis::system_api::ping(&bob_new_config);
assert!(
bob_new_result.is_ok(),
"Bob's new password should work after reload"
);
}
#[test]
#[serial(auth)]
fn test_reload_auth_no_auth_file() {
let server = common::start_server();
let result = apis::access_control_api::reload_auth(&server.config);
assert!(result.is_err(), "reload_auth should fail without auth file");
}