use predicates::prelude::PredicateBooleanExt;
use predicates::str::contains;
use tempfile::tempdir;
use tsafe_core::age_crypto;
use super::{tsafe, write_age_identity};
#[test]
fn team_vault_cli_supports_normal_crud_surface() {
let dir = tempdir().unwrap();
let vault_dir = dir.path().join("vaults");
let alice_identity = dir.path().join("alice.txt");
let bob_identity = dir.path().join("bob.txt");
let (alice_secret, alice_recipient) = age_crypto::generate_identity();
let (bob_secret, bob_recipient) = age_crypto::generate_identity();
write_age_identity(&alice_identity, &alice_secret);
write_age_identity(&bob_identity, &bob_secret);
tsafe()
.args([
"--profile",
"team",
"team",
"init",
"--identity",
alice_identity.to_str().unwrap(),
])
.env("TSAFE_VAULT_DIR", &vault_dir)
.assert()
.success()
.stdout(contains("Team vault created"));
tsafe()
.args(["--profile", "team", "team", "members"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.assert()
.success()
.stdout(contains("Team members (1):").and(contains(&alice_recipient)));
tsafe()
.args(["--profile", "team", "set", "APP_SECRET", "alpha"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &alice_identity)
.assert()
.success();
tsafe()
.args(["--profile", "team", "team", "add-member", &bob_recipient])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &alice_identity)
.args(["--identity", alice_identity.to_str().unwrap()])
.assert()
.success()
.stdout(contains("Added team member").and(contains(&bob_recipient)));
tsafe()
.args(["--profile", "team", "team", "members"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.assert()
.success()
.stdout(
contains("Team members (2):")
.and(contains(&alice_recipient))
.and(contains(&bob_recipient)),
);
tsafe()
.args(["--profile", "team", "list"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &bob_identity)
.assert()
.success()
.stdout(contains("APP_SECRET"));
tsafe()
.args(["--profile", "team", "get", "APP_SECRET"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &bob_identity)
.assert()
.success()
.stdout("alpha");
tsafe()
.args([
"--profile",
"team",
"set",
"APP_SECRET",
"beta",
"--overwrite",
])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &bob_identity)
.assert()
.success();
tsafe()
.args(["--profile", "team", "export"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &bob_identity)
.assert()
.success()
.stdout(contains("APP_SECRET=beta"));
tsafe()
.args(["--profile", "team", "set", "BOB_ONLY_SECRET", "gamma"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &bob_identity)
.assert()
.success();
tsafe()
.args(["--profile", "team", "get", "BOB_ONLY_SECRET"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &alice_identity)
.assert()
.success()
.stdout("gamma");
tsafe()
.args(["--profile", "team", "delete", "APP_SECRET"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &bob_identity)
.assert()
.success()
.stdout(contains("Deleted 'APP_SECRET'"));
tsafe()
.args(["--profile", "team", "list"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &alice_identity)
.assert()
.success()
.stdout(contains("BOB_ONLY_SECRET").and(contains("APP_SECRET").not()));
tsafe()
.args(["--profile", "team", "delete", "BOB_ONLY_SECRET"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &alice_identity)
.assert()
.success()
.stdout(contains("Deleted 'BOB_ONLY_SECRET'"));
tsafe()
.args(["--profile", "team", "list"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &bob_identity)
.assert()
.success()
.stdout(contains("No secrets in profile 'team'"));
tsafe()
.args(["--profile", "team", "get", "APP_SECRET"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &alice_identity)
.assert()
.failure()
.stderr(contains("secret 'APP_SECRET' not found"));
}
#[test]
fn team_vault_cli_rekeys_on_remove_member_and_blocks_removed_member_reads() {
let dir = tempdir().unwrap();
let vault_dir = dir.path().join("vaults");
let alice_identity = dir.path().join("alice.txt");
let bob_identity = dir.path().join("bob.txt");
let (alice_secret, alice_recipient) = age_crypto::generate_identity();
let (bob_secret, bob_recipient) = age_crypto::generate_identity();
write_age_identity(&alice_identity, &alice_secret);
write_age_identity(&bob_identity, &bob_secret);
tsafe()
.args([
"--profile",
"team",
"team",
"init",
"--identity",
alice_identity.to_str().unwrap(),
])
.env("TSAFE_VAULT_DIR", &vault_dir)
.assert()
.success()
.stdout(contains("Team vault created"));
tsafe()
.args(["--profile", "team", "set", "TEAM_SECRET", "alpha"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &alice_identity)
.assert()
.success();
tsafe()
.args(["--profile", "team", "team", "add-member", &bob_recipient])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &alice_identity)
.args(["--identity", alice_identity.to_str().unwrap()])
.assert()
.success()
.stdout(contains("Added team member").and(contains(&bob_recipient)));
tsafe()
.args(["--profile", "team", "get", "TEAM_SECRET"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &bob_identity)
.assert()
.success()
.stdout("alpha");
tsafe()
.args([
"--profile",
"team",
"team",
"remove-member",
&bob_recipient,
"--identity",
alice_identity.to_str().unwrap(),
])
.env("TSAFE_VAULT_DIR", &vault_dir)
.assert()
.success()
.stdout(contains("Removed team member").and(contains(&bob_recipient)));
tsafe()
.args(["--profile", "team", "team", "members"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.assert()
.success()
.stdout(
contains("Team members (1):")
.and(contains(&alice_recipient))
.and(contains(&bob_recipient).not()),
);
tsafe()
.args(["--profile", "team", "list"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &bob_identity)
.assert()
.failure()
.stderr(contains("cannot decrypt team vault"));
tsafe()
.args(["--profile", "team", "get", "TEAM_SECRET"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &bob_identity)
.assert()
.failure()
.stderr(contains("cannot decrypt team vault"));
tsafe()
.args(["--profile", "team", "get", "TEAM_SECRET"])
.env("TSAFE_VAULT_DIR", &vault_dir)
.env("TSAFE_AGE_IDENTITY", &alice_identity)
.assert()
.success()
.stdout("alpha");
}