fix: resolve CI workflow path and add lint job
Some checks failed
CI / test (push) Has been cancelled
CI / lint (push) Has been cancelled

This commit is contained in:
2026-01-31 23:08:33 +00:00
parent 3e38a5522e
commit c59dd97f19

375
src/main.rs Normal file
View File

@@ -0,0 +1,375 @@
mod cli;
mod vault;
mod token;
mod rotation;
mod env_injector;
mod crypto;
use cli::Cli;
use vault::Vault;
use crypto::CryptoManager;
use std::process;
fn main() {
let cli = Cli::parse();
match cli.command {
cli::Commands::Init { master_password, project } => {
let password = master_password.unwrap_or_else(|| {
rpassword::prompt_password("Enter master password: ").unwrap_or_else(|_| {
eprintln!("Failed to read password");
process::exit(1);
})
});
let project_name = project.unwrap_or_else(|| {
"default".to_string()
});
match Vault::initialize(&password, &project_name) {
Ok(_) => println!("Vault initialized for project '{}'", project_name),
Err(e) => {
eprintln!("Failed to initialize vault: {}", e);
process::exit(1);
}
}
}
cli::Commands::Generate { name, length, project, master_password } => {
let password = master_password.unwrap_or_else(|| {
rpassword::prompt_password("Enter master password: ").unwrap_or_else(|_| {
eprintln!("Failed to read password");
process::exit(1);
})
});
let project_name = project.unwrap_or_else(|| {
std::env::var("API_VAULT_PROJECT").unwrap_or_else(|_| "default".to_string())
});
let token_length = length.unwrap_or(32);
match Vault::load(&password, &project_name) {
Ok(mut vault) => {
match vault.generate_token(&name, token_length) {
Ok(generated_token) => {
match vault.save(&password) {
Ok(_) => println!("Generated token '{}': {}", name, generated_token),
Err(e) => {
eprintln!("Failed to save vault: {}", e);
process::exit(1);
}
}
}
Err(e) => {
eprintln!("Failed to generate token: {}", e);
process::exit(1);
}
}
}
Err(e) => {
eprintln!("Failed to load vault: {}", e);
process::exit(1);
}
}
}
cli::Commands::List { project, master_password } => {
let password = master_password.unwrap_or_else(|| {
rpassword::prompt_password("Enter master password: ").unwrap_or_else(|_| {
eprintln!("Failed to read password");
process::exit(1);
})
});
let project_name = project.unwrap_or_else(|| {
std::env::var("API_VAULT_PROJECT").unwrap_or_else(|_| "default".to_string())
});
match Vault::load(&password, &project_name) {
Ok(vault) => {
if vault.tokens.is_empty() {
println!("No tokens found in vault for project '{}'", project_name);
} else {
println!("Tokens in vault for project '{}':", project_name);
println!("{}", "-".repeat(50));
for (name, token_data) in &vault.tokens {
println!(" Name: {}", name);
println!(" Created: {}", token_data.created_at);
if let Some(expires) = token_data.expires_at {
println!(" Expires: {}", expires);
} else {
println!(" Expires: Never");
}
println!(" Rotated: {}", if token_data.auto_rotate { "Yes" } else { "No" });
println!("{}", "-".repeat(50));
}
}
}
Err(e) => {
eprintln!("Failed to load vault: {}", e);
process::exit(1);
}
}
}
cli::Commands::Get { name, project, master_password, raw } => {
let password = master_password.unwrap_or_else(|| {
rpassword::prompt_password("Enter master password: ").unwrap_or_else(|_| {
eprintln!("Failed to read password");
process::exit(1);
})
});
let project_name = project.unwrap_or_else(|| {
std::env::var("API_VAULT_PROJECT").unwrap_or_else(|_| "default".to_string())
});
match Vault::load(&password, &project_name) {
Ok(vault) => {
match vault.get_token(&name) {
Some(token_data) => {
if raw {
print!("{}", token_data.value);
} else {
println!("Token '{}': {}", name, token_data.value);
println!("Created: {}", token_data.created_at);
if let Some(expires) = &token_data.expires_at {
println!("Expires: {}", expires);
}
}
}
None => {
eprintln!("Token '{}' not found", name);
process::exit(1);
}
}
}
Err(e) => {
eprintln!("Failed to load vault: {}", e);
process::exit(1);
}
}
}
cli::Commands::Delete { name, project, master_password } => {
let password = master_password.unwrap_or_else(|| {
rpassword::prompt_password("Enter master password: ").unwrap_or_else(|_| {
eprintln!("Failed to read password");
process::exit(1);
})
});
let project_name = project.unwrap_or_else(|| {
std::env::var("API_VAULT_PROJECT").unwrap_or_else(|_| "default".to_string())
});
match Vault::load(&password, &project_name) {
Ok(mut vault) => {
match vault.remove_token(&name) {
Ok(_) => {
match vault.save(&password) {
Ok(_) => println!("Token '{}' deleted", name),
Err(e) => {
eprintln!("Failed to save vault: {}", e);
process::exit(1);
}
}
}
Err(e) => {
eprintln!("Failed to delete token: {}", e);
process::exit(1);
}
}
}
Err(e) => {
eprintln!("Failed to load vault: {}", e);
process::exit(1);
}
}
}
cli::Commands::Rotate { name, project, master_password, force } => {
let password = master_password.unwrap_or_else(|| {
rpassword::prompt_password("Enter master password: ").unwrap_or_else(|_| {
eprintln!("Failed to read password");
process::exit(1);
})
});
let project_name = project.unwrap_or_else(|| {
std::env::var("API_VAULT_PROJECT").unwrap_or_else(|_| "default".to_string())
});
match Vault::load(&password, &project_name) {
Ok(mut vault) => {
match vault.rotate_token(&name, force) {
Ok(new_value) => {
match vault.save(&password) {
Ok(_) => println!("Rotated token '{}': {}", name, new_value),
Err(e) => {
eprintln!("Failed to save vault: {}", e);
process::exit(1);
}
}
}
Err(e) => {
eprintln!("Failed to rotate token: {}", e);
process::exit(1);
}
}
}
Err(e) => {
eprintln!("Failed to load vault: {}", e);
process::exit(1);
}
}
}
cli::Commands::SetRotation { name, days, project, master_password } => {
let password = master_password.unwrap_or_else(|| {
rpassword::prompt_password("Enter master password: ").unwrap_or_else(|_| {
eprintln!("Failed to read password");
process::exit(1);
})
});
let project_name = project.unwrap_or_else(|| {
std::env::var("API_VAULT_PROJECT").unwrap_or_else(|_| "default".to_string())
});
match Vault::load(&password, &project_name) {
Ok(mut vault) => {
match vault.set_rotation(&name, days) {
Ok(_) => {
match vault.save(&password) {
Ok(_) => println!("Auto-rotation set for '{}': every {} days", name, days),
Err(e) => {
eprintln!("Failed to save vault: {}", e);
process::exit(1);
}
}
}
Err(e) => {
eprintln!("Failed to set rotation: {}", e);
process::exit(1);
}
}
}
Err(e) => {
eprintln!("Failed to load vault: {}", e);
process::exit(1);
}
}
}
cli::Commands::Inject { env_file, token_prefix, project, master_password, dry_run } => {
let password = master_password.unwrap_or_else(|| {
rpassword::prompt_password("Enter master password: ").unwrap_or_else(|_| {
eprintln!("Failed to read password");
process::exit(1);
})
});
let project_name = project.unwrap_or_else(|| {
std::env::var("API_VAULT_PROJECT").unwrap_or_else(|_| "default".to_string())
});
let env_path = env_file.unwrap_or_else(|| {
".env".to_string()
});
match Vault::load(&password, &project_name) {
Ok(vault) => {
match env_injector::inject_tokens(&vault, &env_path, token_prefix, dry_run) {
Ok(()) => {
if dry_run {
println!("Dry run complete. No changes made.");
} else {
println!("Tokens injected into {}", env_path);
}
}
Err(e) => {
eprintln!("Failed to inject tokens: {}", e);
process::exit(1);
}
}
}
Err(e) => {
eprintln!("Failed to load vault: {}", e);
process::exit(1);
}
}
}
cli::Commands::CheckExpired { project, master_password } => {
let password = master_password.unwrap_or_else(|| {
rpassword::prompt_password("Enter master password: ").unwrap_or_else(|_| {
eprintln!("Failed to read password");
process::exit(1);
})
});
let project_name = project.unwrap_or_else(|| {
std::env::var("API_VAULT_PROJECT").unwrap_or_else(|_| "default".to_string())
});
match Vault::load(&password, &project_name) {
Ok(vault) => {
let expired = vault.check_expired_tokens();
if expired.is_empty() {
println!("No expired tokens found");
} else {
println!("Expired tokens:");
for (name, token_data) in expired {
println!(" {} - expired at {}", name, token_data.expires_at.unwrap());
}
}
}
Err(e) => {
eprintln!("Failed to load vault: {}", e);
process::exit(1);
}
}
}
cli::Commands::RotateExpired { project, master_password } => {
let password = master_password.unwrap_or_else(|| {
rpassword::prompt_password("Enter master password: ").unwrap_or_else(|_| {
eprintln!("Failed to read password");
process::exit(1);
})
});
let project_name = project.unwrap_or_else(|| {
std::env::var("API_VAULT_PROJECT").unwrap_or_else(|_| "default".to_string())
});
match Vault::load(&password, &project_name) {
Ok(mut vault) => {
let rotated = vault.rotate_expired_tokens();
if rotated.is_empty() {
println!("No expired tokens to rotate");
} else {
match vault.save(&password) {
Ok(_) => {
println!("Rotated {} expired token(s):", rotated.len());
for name in rotated {
println!(" - {}", name);
}
}
Err(e) => {
eprintln!("Failed to save vault: {}", e);
process::exit(1);
}
}
}
}
Err(e) => {
eprintln!("Failed to load vault: {}", e);
process::exit(1);
}
}
}
}
}