#![allow(clippy::unwrap_used, clippy::expect_used)]
use std::path::{Path, PathBuf};
use assert_cmd::Command;
use predicates::prelude::*;
use tempfile::TempDir;
fn install_mock_aws(dir: &TempDir, body: &str) -> PathBuf {
secretenv_testing::install_mock_aws(dir.path(), body)
}
fn install_mock_op(dir: &TempDir, body: &str) -> PathBuf {
secretenv_testing::install_mock_op(dir.path(), body)
}
fn write(path: &Path, contents: &str) {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).unwrap();
}
std::fs::write(path, contents).unwrap();
}
fn secretenv_with_mock(fixture: &Path, mock_dir: &Path) -> Command {
let parent_path = std::env::var("PATH").unwrap_or_default();
let injected = format!("{}:{}", mock_dir.display(), parent_path);
let mut cmd = Command::cargo_bin("secretenv").unwrap();
cmd.current_dir(fixture).env("PATH", injected).env_remove("SECRETENV_REGISTRY");
cmd
}
#[test]
fn ssm_mocked_run_injects_resolved_secret_into_child_env() {
let mock_dir = TempDir::new().unwrap();
install_mock_aws(
&mock_dir,
r#"
case "$*" in
"--version"*)
echo "aws-cli/2.15.17 Python/3.11.8 Darwin/23.0.0" ;;
"sts "*)
echo '{"UserId":"AIDA","Account":"123456789012","Arn":"arn:aws:iam::123456789012:user/test"}' ;;
"ssm get-parameter --with-decryption --name /registries/shared "*)
echo '{"stripe-key":"aws-ssm-prod:///prod/stripe"}' ;;
"ssm get-parameter --with-decryption --name /prod/stripe "*)
echo "sk_live_abc" ;;
*)
echo "mock aws: unrecognized: $*" >&2
exit 2 ;;
esac
"#,
);
let fixture = TempDir::new().unwrap();
write(
&fixture.path().join("config.toml"),
r#"
[registries.default]
sources = ["aws-ssm-prod:///registries/shared"]
[backends.aws-ssm-prod]
type = "aws-ssm"
aws_region = "us-east-1"
"#,
);
write(
&fixture.path().join("secretenv.toml"),
r#"
[secrets]
STRIPE = { from = "secretenv://stripe-key" }
"#,
);
secretenv_with_mock(fixture.path(), mock_dir.path())
.args(["--config", fixture.path().join("config.toml").to_str().unwrap()])
.args(["run", "--no-redact", "--i-know", "--", "sh", "-c", "echo $STRIPE"])
.assert()
.success()
.stdout(predicate::str::contains("sk_live_abc"));
}
#[test]
fn ssm_mocked_missing_alias_errors_with_name() {
let mock_dir = TempDir::new().unwrap();
install_mock_aws(
&mock_dir,
r#"
case "$*" in
"--version"*) echo "aws-cli/2.15.17" ;;
"sts "*) echo '{"UserId":"A","Account":"1","Arn":"arn"}' ;;
"ssm get-parameter --with-decryption --name /registries/shared "*)
echo '{"other-alias":"aws-ssm-prod:///prod/other"}' ;;
*) echo "mock aws: $*" >&2; exit 2 ;;
esac
"#,
);
let fixture = TempDir::new().unwrap();
write(
&fixture.path().join("config.toml"),
r#"
[registries.default]
sources = ["aws-ssm-prod:///registries/shared"]
[backends.aws-ssm-prod]
type = "aws-ssm"
aws_region = "us-east-1"
"#,
);
write(
&fixture.path().join("secretenv.toml"),
r#"
[secrets]
STRIPE = { from = "secretenv://stripe-key" }
"#,
);
secretenv_with_mock(fixture.path(), mock_dir.path())
.args(["--config", fixture.path().join("config.toml").to_str().unwrap()])
.args(["run", "--", "true"])
.assert()
.failure()
.stderr(predicate::str::contains("stripe-key"))
.stderr(predicate::str::contains("not found"));
}
#[test]
fn doctor_flags_not_authenticated_when_sts_fails() {
let mock_dir = TempDir::new().unwrap();
install_mock_aws(
&mock_dir,
r#"
case "$*" in
"--version"*) echo "aws-cli/2.15.17" ;;
"sts "*)
echo "Unable to locate credentials. You can configure credentials by running \"aws configure\"." >&2
exit 255 ;;
*) echo "mock aws: $*" >&2; exit 2 ;;
esac
"#,
);
let fixture = TempDir::new().unwrap();
write(
&fixture.path().join("config.toml"),
r#"
[backends.aws-ssm-prod]
type = "aws-ssm"
aws_region = "us-east-1"
"#,
);
secretenv_with_mock(fixture.path(), mock_dir.path())
.args(["--config", fixture.path().join("config.toml").to_str().unwrap()])
.arg("doctor")
.assert()
.failure()
.stdout(predicate::str::contains("not authenticated"))
.stdout(predicate::str::contains("Unable to locate credentials"));
}
#[test]
fn dry_run_fetches_registry_but_not_values() {
let mock_dir = TempDir::new().unwrap();
let call_log = mock_dir.path().join("calls.log");
let call_log_str = call_log.to_str().unwrap().to_owned();
install_mock_aws(
&mock_dir,
&format!(
r#"
echo "$*" >> "{call_log_str}"
case "$*" in
"--version"*) echo "aws-cli/2.15.17" ;;
"sts "*) echo '{{"UserId":"A","Account":"1","Arn":"arn"}}' ;;
"ssm get-parameter --with-decryption --name /registries/shared "*)
echo '{{"stripe-key":"aws-ssm-prod:///prod/stripe"}}' ;;
"ssm get-parameter --with-decryption --name /prod/stripe "*)
echo "sk_live_abc" ;;
*) echo "mock aws: $*" >&2; exit 2 ;;
esac
"#
),
);
let fixture = TempDir::new().unwrap();
write(
&fixture.path().join("config.toml"),
r#"
[registries.default]
sources = ["aws-ssm-prod:///registries/shared"]
[backends.aws-ssm-prod]
type = "aws-ssm"
aws_region = "us-east-1"
"#,
);
write(
&fixture.path().join("secretenv.toml"),
r#"
[secrets]
STRIPE = { from = "secretenv://stripe-key" }
"#,
);
secretenv_with_mock(fixture.path(), mock_dir.path())
.args(["--config", fixture.path().join("config.toml").to_str().unwrap()])
.args(["run", "--dry-run", "--", "true"])
.assert()
.success();
let log = std::fs::read_to_string(&call_log).unwrap();
let registry_hits = log.lines().filter(|l| l.contains("/registries/shared")).count();
let value_hits = log.lines().filter(|l| l.contains("/prod/stripe")).count();
assert_eq!(registry_hits, 1, "registry should be fetched exactly once:\n{log}");
assert_eq!(value_hits, 0, "secret value must NOT be fetched in dry-run:\n{log}");
}
#[test]
fn direct_backend_uri_in_manifest_is_rejected() {
let fixture = TempDir::new().unwrap();
write(
&fixture.path().join("config.toml"),
r#"
[backends.local]
type = "local"
"#,
);
write(
&fixture.path().join("secretenv.toml"),
r#"
[secrets]
STRIPE = { from = "aws-ssm-prod:///prod/stripe" }
"#,
);
let mock_dir = TempDir::new().unwrap();
secretenv_with_mock(fixture.path(), mock_dir.path())
.args(["--config", fixture.path().join("config.toml").to_str().unwrap()])
.args(["run", "--registry", "local:///tmp/noop.toml", "--", "true"])
.assert()
.failure()
.stderr(predicate::str::contains("direct backend URI"))
.stderr(predicate::str::contains("STRIPE"));
}
#[test]
fn op_mocked_run_injects_resolved_secret_into_child_env() {
let mock_dir = TempDir::new().unwrap();
install_mock_op(
&mock_dir,
r#"
case "$1" in
--version) echo "2.30.0" ;;
whoami)
echo '{"url":"my.1password.com","email":"me@example.com"}' ;;
read)
# $2 is the op://vault/item/field URI.
case "$2" in
"op://Shared/Registry/body")
cat <<'TOML'
api-key = "1password-personal://Eng/API/key"
TOML
;;
"op://Eng/API/key")
echo "op_api_token_xyz"
;;
*)
echo "mock op read: unknown URI: $2" >&2
exit 1
;;
esac
;;
*)
echo "mock op: unknown command: $*" >&2
exit 2
;;
esac
"#,
);
let fixture = TempDir::new().unwrap();
write(
&fixture.path().join("config.toml"),
r#"
[registries.default]
sources = ["1password-personal://Shared/Registry/body"]
[backends.1password-personal]
type = "1password"
"#,
);
write(
&fixture.path().join("secretenv.toml"),
r#"
[secrets]
API_KEY = { from = "secretenv://api-key" }
"#,
);
secretenv_with_mock(fixture.path(), mock_dir.path())
.args(["--config", fixture.path().join("config.toml").to_str().unwrap()])
.args(["run", "--no-redact", "--i-know", "--", "sh", "-c", "echo $API_KEY"])
.assert()
.success()
.stdout(predicate::str::contains("op_api_token_xyz"));
}
#[test]
fn strict_mock_matches_exact_argv_and_injects_resolved_secret() {
let mock_dir = TempDir::new().unwrap();
let registry_path = mock_dir.path().join("registry.toml");
write(®istry_path, r#"stripe_key = "aws-ssm-prod:///prod/stripe""#);
let _ = secretenv_testing::StrictMock::new("aws")
.on(
&[
"ssm",
"get-parameter",
"--with-decryption",
"--name",
"/prod/stripe",
"--query",
"Parameter.Value",
"--output",
"text",
"--region",
"us-east-1",
],
secretenv_testing::Response::success("sk_live_strict_abc\n"),
)
.install(mock_dir.path());
let fixture = TempDir::new().unwrap();
write(
&fixture.path().join("config.toml"),
&format!(
r#"
[registries.default]
sources = ["local:///{reg}"]
[backends.local]
type = "local"
[backends.aws-ssm-prod]
type = "aws-ssm"
aws_region = "us-east-1"
"#,
reg = registry_path.display(),
),
);
write(
&fixture.path().join("secretenv.toml"),
r#"
[secrets]
STRIPE = { from = "secretenv://stripe_key" }
"#,
);
secretenv_with_mock(fixture.path(), mock_dir.path())
.args(["--config", fixture.path().join("config.toml").to_str().unwrap()])
.args(["run", "--no-redact", "--i-know", "--", "sh", "-c", "echo $STRIPE"])
.assert()
.success()
.stdout(predicate::str::contains("sk_live_strict_abc"));
}
#[test]
fn strict_mock_rejects_argv_drift_with_exit_97() {
let mock_dir = TempDir::new().unwrap();
let registry_path = mock_dir.path().join("registry.toml");
write(®istry_path, r#"stripe_key = "aws-ssm-prod:///prod/stripe""#);
let _ = secretenv_testing::StrictMock::new("aws")
.on(
&[
"ssm",
"get-parameter",
"--name",
"/prod/stripe",
"--query",
"Parameter.Value",
"--output",
"text",
"--region",
"us-east-1",
],
secretenv_testing::Response::success("should-not-be-seen"),
)
.install(mock_dir.path());
let fixture = TempDir::new().unwrap();
write(
&fixture.path().join("config.toml"),
&format!(
r#"
[registries.default]
sources = ["local:///{reg}"]
[backends.local]
type = "local"
[backends.aws-ssm-prod]
type = "aws-ssm"
aws_region = "us-east-1"
"#,
reg = registry_path.display(),
),
);
write(
&fixture.path().join("secretenv.toml"),
r#"
[secrets]
STRIPE = { from = "secretenv://stripe_key" }
"#,
);
secretenv_with_mock(fixture.path(), mock_dir.path())
.args(["--config", fixture.path().join("config.toml").to_str().unwrap()])
.args(["run", "--no-redact", "--i-know", "--", "sh", "-c", "echo $STRIPE"])
.assert()
.failure()
.stderr(predicate::str::contains("strict-mock-no-match"))
.stderr(predicate::str::contains("--with-decryption"));
}