Fix --account N credential priority across all SDKs
--account N was silently ignored when UNSANDBOX_PUBLIC_KEY/SECRET_KEY env vars were set. The credential resolution checked env vars at tier 2 before ever reaching the CSV lookup, so the explicit flag had no effect. Correct priority order (all 8 SDKs): 1. CLI -p/-k flags (explicit key args) 2. --account N → direct CSV row lookup (bypasses env vars) 3. UNSANDBOX_PUBLIC_KEY / UNSANDBOX_SECRET_KEY env vars 4. ~/.unsandbox/accounts.csv default (row 0 or UNSANDBOX_ACCOUNT) SDKs updated: C, Python, Go, JavaScript, Ruby, PHP, Java, Rust Also adds: - --account N flag to CLI parsers in all 8 SDKs (Go, PHP, Java, Rust previously had no flag at all; Python/JS/Ruby had the parameter but never wired it to the CLI) - test_account_flag.sh integration test for each SDK verifying the priority behavior with real and garbage credentials - test-integration Makefile target for the C SDK
This commit is contained in:
parent
8093386568
commit
ed6c52b001
20 changed files with 1243 additions and 174 deletions
|
|
@ -108,6 +108,14 @@ test: build $(TEST_DIR)/test_library
|
|||
|
||||
test-library: test
|
||||
|
||||
test-integration: build
|
||||
@echo ""
|
||||
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
@echo "INTEGRATION: Testing --account flag priority"
|
||||
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
@echo ""
|
||||
@bash $(TEST_DIR)/test_account_flag.sh
|
||||
|
||||
test-functional: build $(TEST_DIR)/test_functional
|
||||
@echo ""
|
||||
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
|
|
|||
|
|
@ -396,7 +396,14 @@ static UnsandboxCredentials* get_credentials(const char *cli_pk, const char *cli
|
|||
return creds;
|
||||
}
|
||||
|
||||
// Priority 2: Environment variables (keys)
|
||||
// Priority 2: --account N flag → explicit CSV lookup
|
||||
// When the user explicitly selects an account, go straight to accounts.csv.
|
||||
// Env vars are intentionally bypassed — an explicit flag must win over ambient env.
|
||||
if (account_index >= 0) {
|
||||
return load_credentials_from_csv(account_index);
|
||||
}
|
||||
|
||||
// Priority 3: Environment variables (keys)
|
||||
const char *env_pk = getenv("UNSANDBOX_PUBLIC_KEY");
|
||||
const char *env_sk = getenv("UNSANDBOX_SECRET_KEY");
|
||||
|
||||
|
|
@ -416,16 +423,12 @@ static UnsandboxCredentials* get_credentials(const char *cli_pk, const char *cli
|
|||
return creds;
|
||||
}
|
||||
|
||||
// Priority 3: Config file (~/.unsandbox/accounts.csv)
|
||||
// Use account_index from --account flag, or UNSANDBOX_ACCOUNT env var, or default to 0
|
||||
int csv_index = account_index;
|
||||
if (csv_index < 0) {
|
||||
const char *env_account = getenv("UNSANDBOX_ACCOUNT");
|
||||
if (env_account && strlen(env_account) > 0) {
|
||||
csv_index = atoi(env_account);
|
||||
} else {
|
||||
csv_index = 0;
|
||||
}
|
||||
// Priority 4: Config file (~/.unsandbox/accounts.csv)
|
||||
// Use UNSANDBOX_ACCOUNT env var, or default to account 0
|
||||
int csv_index = 0;
|
||||
const char *env_account = getenv("UNSANDBOX_ACCOUNT");
|
||||
if (env_account && strlen(env_account) > 0) {
|
||||
csv_index = atoi(env_account);
|
||||
}
|
||||
return load_credentials_from_csv(csv_index);
|
||||
}
|
||||
|
|
|
|||
111
clients/c/tests/test_account_flag.sh
Executable file
111
clients/c/tests/test_account_flag.sh
Executable file
|
|
@ -0,0 +1,111 @@
|
|||
#!/usr/bin/env bash
|
||||
# Integration test: --account N flag must take priority over env vars
|
||||
#
|
||||
# Requires: UNSANDBOX_PUBLIC_KEY, UNSANDBOX_SECRET_KEY (real credentials)
|
||||
# Run: make test-integration OR bash tests/test_account_flag.sh
|
||||
#
|
||||
# The defect this guards against: get_credentials() checked env vars before
|
||||
# account_index, so --account N was silently ignored when env vars existed.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
UN_BIN="$SCRIPT_DIR/../un"
|
||||
|
||||
RED='\033[31m'
|
||||
GREEN='\033[32m'
|
||||
NC='\033[0m'
|
||||
|
||||
pass=0
|
||||
fail=0
|
||||
|
||||
check() {
|
||||
local desc="$1" result="$2"
|
||||
if [ "$result" = "pass" ]; then
|
||||
printf " ${GREEN}✓${NC} %s\n" "$desc"
|
||||
pass=$((pass + 1))
|
||||
else
|
||||
printf " ${RED}✗${NC} %s\n" "$desc"
|
||||
fail=$((fail + 1))
|
||||
fi
|
||||
}
|
||||
|
||||
# Require real credentials to be available
|
||||
if [ -z "${UNSANDBOX_PUBLIC_KEY:-}" ] || [ -z "${UNSANDBOX_SECRET_KEY:-}" ]; then
|
||||
echo "SKIP: UNSANDBOX_PUBLIC_KEY and UNSANDBOX_SECRET_KEY not set"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -x "$UN_BIN" ]; then
|
||||
echo "FAIL: UN binary not found at $UN_BIN — run make first"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REAL_PK="$UNSANDBOX_PUBLIC_KEY"
|
||||
REAL_SK="$UNSANDBOX_SECRET_KEY"
|
||||
|
||||
# Temporary HOME with accounts.csv:
|
||||
# index 0: garbage credentials (will always 401)
|
||||
# index 1: real credentials (will succeed)
|
||||
TMPHOME="$(mktemp -d)"
|
||||
mkdir -p "$TMPHOME/.unsandbox"
|
||||
trap 'rm -rf "$TMPHOME"' EXIT
|
||||
|
||||
cat > "$TMPHOME/.unsandbox/accounts.csv" <<CSV
|
||||
unsb-pk-fake-0000-0000-0000,unsb-sk-fake0-00000-00000-00000
|
||||
${REAL_PK},${REAL_SK}
|
||||
CSV
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "INTEGRATION: --account flag priority test"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
# --- Test 1: --account 1 should use CSV row 1 (real creds), ignoring env vars ---
|
||||
# Set env vars to GARBAGE so the test fails if env vars win.
|
||||
# Auth success = no 401/unauthorized (429 rate-limit means creds passed auth, just hit concurrency cap).
|
||||
OUT=$(HOME="$TMPHOME" \
|
||||
UNSANDBOX_PUBLIC_KEY=unsb-pk-fake-0000-0000-0000 \
|
||||
UNSANDBOX_SECRET_KEY=unsb-sk-fake0-00000-00000-00000 \
|
||||
"$UN_BIN" --account 1 key 2>&1 || true)
|
||||
|
||||
if ! echo "$OUT" | grep -qi "401\|unauthorized\|invalid_credential\|No credentials"; then
|
||||
check "--account 1 uses CSV row 1 (real creds) over garbage env vars" "pass"
|
||||
else
|
||||
check "--account 1 uses CSV row 1 (real creds) over garbage env vars" "fail"
|
||||
echo " output: $OUT"
|
||||
fi
|
||||
|
||||
# --- Test 2: --account 0 should use CSV row 0 (garbage creds) → 401 ---
|
||||
# Even though real env vars are set, explicit --account 0 should pick garbage creds
|
||||
OUT=$(HOME="$TMPHOME" \
|
||||
UNSANDBOX_PUBLIC_KEY="$REAL_PK" \
|
||||
UNSANDBOX_SECRET_KEY="$REAL_SK" \
|
||||
"$UN_BIN" --account 0 key 2>&1 || true)
|
||||
|
||||
if echo "$OUT" | grep -qi "401\|unauthorized\|invalid_credential\|invalid key"; then
|
||||
check "--account 0 uses CSV row 0 (garbage creds) despite real env vars, 401 as expected" "pass"
|
||||
else
|
||||
check "--account 0 uses CSV row 0 (garbage creds) despite real env vars, 401 as expected" "fail"
|
||||
echo " output: $OUT"
|
||||
fi
|
||||
|
||||
# --- Test 3: no --account flag, real env vars → env vars win over garbage CSV row 0 ---
|
||||
OUT=$(HOME="$TMPHOME" \
|
||||
UNSANDBOX_PUBLIC_KEY="$REAL_PK" \
|
||||
UNSANDBOX_SECRET_KEY="$REAL_SK" \
|
||||
"$UN_BIN" key 2>&1 || true)
|
||||
|
||||
if ! echo "$OUT" | grep -qi "401\|unauthorized\|invalid_credential\|No credentials"; then
|
||||
check "No --account flag: env vars used, succeeds" "pass"
|
||||
else
|
||||
check "No --account flag: env vars used, succeeds" "fail"
|
||||
echo " output: $OUT"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
printf "Passed: ${GREEN}%d${NC} Failed: ${RED}%d${NC}\n" "$pass" "$fail"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
[ "$fail" -eq 0 ]
|
||||
Loading…
Add table
Add a link
Reference in a new issue