Initial upload: api-token-vault Rust CLI tool with encrypted vault storage

This commit is contained in:
2026-01-31 22:54:35 +00:00
parent 35504ace62
commit 1ee329453e

View File

@@ -0,0 +1,418 @@
use assert_cmd::prelude::*;
use predicates::prelude::*;
use std::process::Command;
use std::fs;
use std::path::PathBuf;
fn get_test_vault_path() -> PathBuf {
PathBuf::from("/tmp/api-token-vault-test-vault.json")
}
fn cleanup_test_vault() {
let vault_path = get_test_vault_path();
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
}
#[test]
fn test_cli_help() {
let mut cmd = Command::cargo_bin("api-token-vault").unwrap();
cmd.arg("--help");
cmd.assert()
.success()
.stdout(predicate::str::contains("API Token Vault"));
}
#[test]
fn test_cli_version() {
let mut cmd = Command::cargo_bin("api-token-vault").unwrap();
cmd.arg("--version");
cmd.assert()
.success()
.stdout(predicate::str::contains("0.1.0"));
}
#[test]
fn test_init_command() {
cleanup_test_vault();
let mut cmd = Command::cargo_bin("api-token-vault").unwrap();
cmd.arg("init")
.arg("--project")
.arg("test-init-project")
.env("API_VAULT_PROJECT", "");
let assert = cmd.assert();
cleanup_test_vault();
}
#[test]
fn test_generate_command() {
cleanup_test_vault();
let password = "test_password_123";
let project = "test-gen-project";
let vault_dir = PathBuf::from("/tmp/.config/api-token-vault");
let vault_path = vault_dir.join("test-gen-project.json");
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
if !vault_dir.exists() {
let _ = fs::create_dir_all(&vault_dir);
}
let mut init_cmd = Command::cargo_bin("api-token-vault").unwrap();
init_cmd.arg("init")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
let _ = init_cmd.output();
let mut gen_cmd = Command::cargo_bin("api-token-vault").unwrap();
gen_cmd.arg("generate")
.arg("--name")
.arg("test_token")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
gen_cmd.assert()
.success()
.stdout(predicate::str::contains("Generated token"));
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
}
#[test]
fn test_list_command() {
cleanup_test_vault();
let password = "test_password";
let project = "test-list-project";
let vault_dir = PathBuf::from("/tmp/.config/api-token-vault");
let vault_path = vault_dir.join("test-list-project.json");
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
if !vault_dir.exists() {
let _ = fs::create_dir_all(&vault_dir);
}
let mut init_cmd = Command::cargo_bin("api-token-vault").unwrap();
init_cmd.arg("init")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
let _ = init_cmd.output();
let mut list_cmd = Command::cargo_bin("api-token-vault").unwrap();
list_cmd.arg("list")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
list_cmd.assert()
.success()
.stdout(predicate::str::contains("Tokens in vault"));
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
}
#[test]
fn test_rotate_command() {
cleanup_test_vault();
let password = "test_password";
let project = "test-rotate-project";
let vault_dir = PathBuf::from("/tmp/.config/api-token-vault");
let vault_path = vault_dir.join("test-rotate-project.json");
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
if !vault_dir.exists() {
let _ = fs::create_dir_all(&vault_dir);
}
let mut init_cmd = Command::cargo_bin("api-token-vault").unwrap();
init_cmd.arg("init")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
let _ = init_cmd.output();
let mut gen_cmd = Command::cargo_bin("api-token-vault").unwrap();
gen_cmd.arg("generate")
.arg("--name")
.arg("rotate_me")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
let _ = gen_cmd.output();
let mut rotate_cmd = Command::cargo_bin("api-token-vault").unwrap();
rotate_cmd.arg("rotate")
.arg("--name")
.arg("rotate_me")
.arg("--force")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
rotate_cmd.assert()
.success()
.stdout(predicate::str::contains("Rotated token"));
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
}
#[test]
fn test_set_rotation_command() {
cleanup_test_vault();
let password = "test_password";
let project = "test-set-rotation-project";
let vault_dir = PathBuf::from("/tmp/.config/api-token-vault");
let vault_path = vault_dir.join("test-set-rotation-project.json");
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
if !vault_dir.exists() {
let _ = fs::create_dir_all(&vault_dir);
}
let mut init_cmd = Command::cargo_bin("api-token-vault").unwrap();
init_cmd.arg("init")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
let _ = init_cmd.output();
let mut gen_cmd = Command::cargo_bin("api-token-vault").unwrap();
gen_cmd.arg("generate")
.arg("--name")
.arg("auto_rotate_token")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
let _ = gen_cmd.output();
let mut set_cmd = Command::cargo_bin("api-token-vault").unwrap();
set_cmd.arg("set-rotation")
.arg("--name")
.arg("auto_rotate_token")
.arg("--days")
.arg("30")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
set_cmd.assert()
.success()
.stdout(predicate::str::contains("Auto-rotation set"));
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
}
#[test]
fn test_check_expired_command() {
cleanup_test_vault();
let password = "test_password";
let project = "test-check-expired-project";
let vault_dir = PathBuf::from("/tmp/.config/api-token-vault");
let vault_path = vault_dir.join("test-check-expired-project.json");
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
if !vault_dir.exists() {
let _ = fs::create_dir_all(&vault_dir);
}
let mut init_cmd = Command::cargo_bin("api-token-vault").unwrap();
init_cmd.arg("init")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
let _ = init_cmd.output();
let mut gen_cmd = Command::cargo_bin("api-token-vault").unwrap();
gen_cmd.arg("generate")
.arg("--name")
.arg("expired_token")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
let _ = gen_cmd.output();
let mut check_cmd = Command::cargo_bin("api-token-vault").unwrap();
check_cmd.arg("check-expired")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
check_cmd.assert()
.success();
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
}
#[test]
fn test_inject_command() {
cleanup_test_vault();
let password = "test_password";
let project = "test-inject-project";
let env_path = PathBuf::from("/tmp/test-inject.env");
let vault_dir = PathBuf::from("/tmp/.config/api-token-vault");
let vault_path = vault_dir.join("test-inject-project.json");
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
if !vault_dir.exists() {
let _ = fs::create_dir_all(&vault_dir);
}
if env_path.exists() {
let _ = fs::remove_file(&env_path);
}
let mut init_cmd = Command::cargo_bin("api-token-vault").unwrap();
init_cmd.arg("init")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
let _ = init_cmd.output();
let mut gen_cmd = Command::cargo_bin("api-token-vault").unwrap();
gen_cmd.arg("generate")
.arg("--name")
.arg("injectable_token")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
let _ = gen_cmd.output();
let mut inject_cmd = Command::cargo_bin("api-token-vault").unwrap();
inject_cmd.arg("inject")
.arg("--env-file")
.arg(env_path.to_str().unwrap())
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
inject_cmd.assert()
.success()
.stdout(predicate::str::contains("injected"));
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
if env_path.exists() {
let _ = fs::remove_file(&env_path);
}
}
#[test]
fn test_dry_run_inject() {
cleanup_test_vault();
let password = "test_password";
let project = "test-dry-run-project";
let env_path = PathBuf::from("/tmp/test-dry-run.env");
let vault_dir = PathBuf::from("/tmp/.config/api-token-vault");
let vault_path = vault_dir.join("test-dry-run-project.json");
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
if !vault_dir.exists() {
let _ = fs::create_dir_all(&vault_dir);
}
if env_path.exists() {
let _ = fs::remove_file(&env_path);
}
let mut init_cmd = Command::cargo_bin("token-vault").unwrap();
init_cmd.arg("init")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
let _ = init_cmd.output();
let mut gen_cmd = Command::cargo_bin("api-token-vault").unwrap();
gen_cmd.arg("generate")
.arg("--name")
.arg("dry_token")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
let _ = gen_cmd.output();
fs::write(&env_path, "EXISTING=value").unwrap();
let mut inject_cmd = Command::cargo_bin("api-token-vault").unwrap();
inject_cmd.arg("inject")
.arg("--env-file")
.arg(env_path.to_str().unwrap())
.arg("--dry-run")
.arg("--master-password")
.arg(password)
.arg("--project")
.arg(project);
inject_cmd.assert()
.success()
.stdout(predicate::str::contains("Dry run"));
let content = fs::read_to_string(&env_path).unwrap();
assert_eq!(content.trim(), "EXISTING=value");
if vault_path.exists() {
let _ = fs::remove_file(&vault_path);
}
if env_path.exists() {
let _ = fs::remove_file(&env_path);
}
}