#![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", "--", "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", "--", "sh", "-c", "echo $API_KEY"])
.assert()
.success()
.stdout(predicate::str::contains("op_api_token_xyz"));
}