Add --account N flag and fix credential priority in sh/lua/pl/tcl
When --account N is passed, it should bypass env vars and load accounts.csv row N directly. Previously, env vars were checked first so the explicit --account flag had no effect when UNSANDBOX_PUBLIC_KEY and UNSANDBOX_SECRET_KEY were set. Correct credential priority (all 4 files): 1. Explicit -p/-k key flags 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) 5. ./accounts.csv default (row 0) Files updated: un.sh (bash), un.lua, un.pl (perl), un.tcl Also fixes load_accounts_csv in sh and tcl to support reading an arbitrary row index rather than always returning the first line.
This commit is contained in:
parent
ed6c52b001
commit
ce327b35e9
4 changed files with 137 additions and 19 deletions
|
|
@ -21,6 +21,7 @@ VERSION="4.2.50"
|
|||
API_BASE="https://api.unsandbox.com"
|
||||
PORTAL_BASE="https://unsandbox.com"
|
||||
LAST_ERROR=""
|
||||
ACCOUNT_INDEX=-1
|
||||
|
||||
# Colors
|
||||
BLUE='\033[34m'
|
||||
|
|
@ -104,8 +105,19 @@ hmac_sign() {
|
|||
|
||||
load_accounts_csv() {
|
||||
local path="${1:-$HOME/.unsandbox/accounts.csv}"
|
||||
local row="${2:-0}"
|
||||
[ -f "$path" ] || return 1
|
||||
head -1 "$path" 2>/dev/null | grep -v '^#'
|
||||
local n=0
|
||||
while IFS= read -r line; do
|
||||
[[ "$line" =~ ^# ]] && continue
|
||||
[ -z "$line" ] && continue
|
||||
if [ "$n" -eq "$row" ]; then
|
||||
echo "$line"
|
||||
return 0
|
||||
fi
|
||||
n=$((n + 1))
|
||||
done < "$path"
|
||||
return 1
|
||||
}
|
||||
|
||||
get_credentials() {
|
||||
|
|
@ -115,7 +127,20 @@ get_credentials() {
|
|||
return
|
||||
fi
|
||||
|
||||
# Tier 2: Environment
|
||||
# Tier 2: --account N flag → bypass env vars, load CSV row N directly
|
||||
if [ "$ACCOUNT_INDEX" -ge 0 ] 2>/dev/null; then
|
||||
local creds
|
||||
creds=$(load_accounts_csv "$HOME/.unsandbox/accounts.csv" "$ACCOUNT_INDEX" 2>/dev/null || true)
|
||||
[ -z "$creds" ] && creds=$(load_accounts_csv "./accounts.csv" "$ACCOUNT_INDEX" 2>/dev/null || true)
|
||||
if [ -n "$creds" ]; then
|
||||
echo "$creds"
|
||||
return
|
||||
fi
|
||||
set_error "Account index $ACCOUNT_INDEX not found in accounts.csv"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Tier 3: Environment
|
||||
if [ -n "${UNSANDBOX_PUBLIC_KEY:-}" ] && [ -n "${UNSANDBOX_SECRET_KEY:-}" ]; then
|
||||
echo "$UNSANDBOX_PUBLIC_KEY:$UNSANDBOX_SECRET_KEY"
|
||||
return
|
||||
|
|
@ -127,7 +152,7 @@ get_credentials() {
|
|||
return
|
||||
fi
|
||||
|
||||
# Tier 3: Home directory
|
||||
# Tier 4: Home directory
|
||||
local creds
|
||||
creds=$(load_accounts_csv "$HOME/.unsandbox/accounts.csv" 2>/dev/null || true)
|
||||
if [ -n "$creds" ]; then
|
||||
|
|
@ -135,7 +160,7 @@ get_credentials() {
|
|||
return
|
||||
fi
|
||||
|
||||
# Tier 4: Local directory
|
||||
# Tier 5: Local directory
|
||||
creds=$(load_accounts_csv "./accounts.csv" 2>/dev/null || true)
|
||||
if [ -n "$creds" ]; then
|
||||
echo "$creds"
|
||||
|
|
@ -1230,6 +1255,21 @@ if [ "${BASH_SOURCE[0]}" = "$0" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Pre-scan for --account N before dispatching
|
||||
_args=("$@")
|
||||
_new_args=()
|
||||
_i=0
|
||||
while [ $_i -lt ${#_args[@]} ]; do
|
||||
if [ "${_args[$_i]}" = "--account" ]; then
|
||||
_i=$((_i + 1))
|
||||
ACCOUNT_INDEX="${_args[$_i]}"
|
||||
else
|
||||
_new_args+=("${_args[$_i]}")
|
||||
fi
|
||||
_i=$((_i + 1))
|
||||
done
|
||||
set -- "${_new_args[@]+"${_new_args[@]}"}"
|
||||
|
||||
case "$1" in
|
||||
languages)
|
||||
shift
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ Un.API_BASE = "https://api.unsandbox.com"
|
|||
Un.PORTAL_BASE = "https://unsandbox.com"
|
||||
Un.VERSION = "4.3.4"
|
||||
Un.LAST_ERROR = ""
|
||||
Un.ACCOUNT_INDEX = -1 -- -1 means not set; set to N to use accounts.csv row N
|
||||
|
||||
-- Colors
|
||||
local BLUE = "\027[34m"
|
||||
|
|
@ -116,7 +117,20 @@ function Un.get_credentials(opts)
|
|||
return opts.public_key, opts.secret_key
|
||||
end
|
||||
|
||||
-- Tier 2: Environment
|
||||
-- Tier 2: --account N flag → bypass env vars, load CSV row N directly
|
||||
local ai = opts.account_index
|
||||
if (ai == nil) and Un.ACCOUNT_INDEX >= 0 then ai = Un.ACCOUNT_INDEX end
|
||||
if ai and ai >= 0 then
|
||||
local row = ai + 1 -- Lua tables are 1-indexed
|
||||
local accounts = Un.load_accounts_csv()
|
||||
if #accounts >= row then return accounts[row][1], accounts[row][2] end
|
||||
accounts = Un.load_accounts_csv("./accounts.csv")
|
||||
if #accounts >= row then return accounts[row][1], accounts[row][2] end
|
||||
Un.set_error("Account index " .. ai .. " not found in accounts.csv")
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
-- Tier 3: Environment
|
||||
local pk = os.getenv("UNSANDBOX_PUBLIC_KEY")
|
||||
local sk = os.getenv("UNSANDBOX_SECRET_KEY")
|
||||
if pk and sk then return pk, sk end
|
||||
|
|
@ -126,11 +140,11 @@ function Un.get_credentials(opts)
|
|||
return os.getenv("UNSANDBOX_API_KEY"), ""
|
||||
end
|
||||
|
||||
-- Tier 3: Home directory
|
||||
-- Tier 4: Home directory
|
||||
local accounts = Un.load_accounts_csv()
|
||||
if #accounts > 0 then return accounts[1][1], accounts[1][2] end
|
||||
|
||||
-- Tier 4: Local directory
|
||||
-- Tier 5: Local directory
|
||||
accounts = Un.load_accounts_csv("./accounts.csv")
|
||||
if #accounts > 0 then return accounts[1][1], accounts[1][2] end
|
||||
|
||||
|
|
@ -744,6 +758,21 @@ if arg and arg[0] then
|
|||
local args = arg
|
||||
local i = 1
|
||||
|
||||
-- Pre-scan for --account N; strip it from args before dispatch
|
||||
local _filtered = {}
|
||||
local _j = 1
|
||||
while _j <= #args do
|
||||
if args[_j] == "--account" then
|
||||
_j = _j + 1
|
||||
Un.ACCOUNT_INDEX = tonumber(args[_j]) or -1
|
||||
else
|
||||
table.insert(_filtered, args[_j])
|
||||
end
|
||||
_j = _j + 1
|
||||
end
|
||||
for k = 1, #_filtered do args[k] = _filtered[k] end
|
||||
for k = #_filtered + 1, #args do args[k] = nil end
|
||||
|
||||
if #args == 0 then
|
||||
print("Usage: lua un.lua [options] <source_file>")
|
||||
print(" lua un.lua -s <language> '<code>'")
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ our $PORTAL_BASE = 'https://unsandbox.com';
|
|||
|
||||
# Thread-local error storage
|
||||
our $LAST_ERROR = "";
|
||||
our $ACCOUNT_INDEX = -1; # -1 means not set; set to N to use accounts.csv row N
|
||||
|
||||
# Colors
|
||||
my $BLUE = "\033[34m";
|
||||
|
|
@ -122,7 +123,18 @@ sub get_credentials {
|
|||
# Tier 1: Arguments
|
||||
return ($opts{public_key}, $opts{secret_key}) if $opts{public_key} && $opts{secret_key};
|
||||
|
||||
# Tier 2: Environment
|
||||
# Tier 2: --account N flag → bypass env vars, load CSV row N directly
|
||||
my $ai = exists $opts{account_index} ? $opts{account_index} : $Un::ACCOUNT_INDEX;
|
||||
if (defined $ai && $ai >= 0) {
|
||||
my $home_accounts = load_accounts_csv();
|
||||
return @{$home_accounts->[$ai]} if @$home_accounts > $ai;
|
||||
my $local_accounts = load_accounts_csv("./accounts.csv");
|
||||
return @{$local_accounts->[$ai]} if @$local_accounts > $ai;
|
||||
set_error("Account index $ai not found in accounts.csv");
|
||||
return (undef, undef);
|
||||
}
|
||||
|
||||
# Tier 3: Environment
|
||||
if ($ENV{UNSANDBOX_PUBLIC_KEY} && $ENV{UNSANDBOX_SECRET_KEY}) {
|
||||
return ($ENV{UNSANDBOX_PUBLIC_KEY}, $ENV{UNSANDBOX_SECRET_KEY});
|
||||
}
|
||||
|
|
@ -132,11 +144,11 @@ sub get_credentials {
|
|||
return ($ENV{UNSANDBOX_API_KEY}, '');
|
||||
}
|
||||
|
||||
# Tier 3: Home directory
|
||||
# Tier 4: Home directory
|
||||
my $home_accounts = load_accounts_csv();
|
||||
return @{$home_accounts->[0]} if @$home_accounts;
|
||||
|
||||
# Tier 4: Local directory
|
||||
# Tier 5: Local directory
|
||||
my $local_accounts = load_accounts_csv("./accounts.csv");
|
||||
return @{$local_accounts->[0]} if @$local_accounts;
|
||||
|
||||
|
|
@ -1541,6 +1553,8 @@ sub main {
|
|||
} elsif ($arg eq 'env' && $options{command} && $options{command} eq 'service') {
|
||||
$options{env_action} = $ARGV[++$i];
|
||||
$options{env_target} = $ARGV[++$i] if defined $ARGV[$i+1] && $ARGV[$i+1] !~ /^-/;
|
||||
} elsif ($arg eq '--account') {
|
||||
$Un::ACCOUNT_INDEX = int($ARGV[++$i]);
|
||||
} elsif ($arg eq '--help' || $arg eq '-h') {
|
||||
show_help();
|
||||
} elsif ($arg =~ /^-/) {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ namespace eval Un {
|
|||
variable LANGUAGES_CACHE_TTL 3600
|
||||
variable LANGUAGES_CACHE_FILE [file join $::env(HOME) ".unsandbox" "languages.json"]
|
||||
variable LAST_ERROR ""
|
||||
variable ACCOUNT_INDEX -1
|
||||
|
||||
# Colors
|
||||
variable BLUE "\033\[34m"
|
||||
|
|
@ -109,22 +110,43 @@ namespace eval Un {
|
|||
# Credential Management
|
||||
# ============================================================================
|
||||
|
||||
proc load_accounts_csv {path} {
|
||||
proc load_accounts_csv {path {row 0}} {
|
||||
if {![file exists $path]} { return "" }
|
||||
if {[catch {open $path r} fp]} { return "" }
|
||||
set line [gets $fp]
|
||||
set n 0
|
||||
set result ""
|
||||
while {[gets $fp line] >= 0} {
|
||||
if {[string index $line 0] eq "#" || [string trim $line] eq ""} { continue }
|
||||
if {$n == $row} { set result $line; break }
|
||||
incr n
|
||||
}
|
||||
close $fp
|
||||
if {[string index $line 0] eq "#"} { return "" }
|
||||
return $line
|
||||
return $result
|
||||
}
|
||||
|
||||
proc get_credentials {{public_key ""} {secret_key ""}} {
|
||||
proc get_credentials {{public_key ""} {secret_key ""} {account_index -1}} {
|
||||
variable ACCOUNT_INDEX
|
||||
|
||||
# Tier 1: Arguments
|
||||
if {$public_key ne "" && $secret_key ne ""} {
|
||||
return [list $public_key $secret_key]
|
||||
}
|
||||
|
||||
# Tier 2: Environment
|
||||
# Tier 2: --account N flag → bypass env vars, load CSV row N directly
|
||||
set ai $account_index
|
||||
if {$ai < 0} { set ai $ACCOUNT_INDEX }
|
||||
if {$ai >= 0} {
|
||||
set creds [load_accounts_csv [file join $::env(HOME) ".unsandbox" "accounts.csv"] $ai]
|
||||
if {$creds eq ""} { set creds [load_accounts_csv "./accounts.csv" $ai] }
|
||||
if {$creds ne ""} {
|
||||
set parts [split $creds ","]
|
||||
return [list [lindex $parts 0] [lindex $parts 1]]
|
||||
}
|
||||
set_error "Account index $ai not found in accounts.csv"
|
||||
error "Account index $ai not found in accounts.csv"
|
||||
}
|
||||
|
||||
# Tier 3: Environment
|
||||
if {[info exists ::env(UNSANDBOX_PUBLIC_KEY)] && [info exists ::env(UNSANDBOX_SECRET_KEY)]} {
|
||||
return [list $::env(UNSANDBOX_PUBLIC_KEY) $::env(UNSANDBOX_SECRET_KEY)]
|
||||
}
|
||||
|
|
@ -134,14 +156,14 @@ namespace eval Un {
|
|||
return [list $::env(UNSANDBOX_API_KEY) ""]
|
||||
}
|
||||
|
||||
# Tier 3: Home directory
|
||||
# Tier 4: Home directory
|
||||
set creds [load_accounts_csv [file join $::env(HOME) ".unsandbox" "accounts.csv"]]
|
||||
if {$creds ne ""} {
|
||||
set parts [split $creds ","]
|
||||
return [list [lindex $parts 0] [lindex $parts 1]]
|
||||
}
|
||||
|
||||
# Tier 4: Local directory
|
||||
# Tier 5: Local directory
|
||||
set creds [load_accounts_csv "./accounts.csv"]
|
||||
if {$creds ne ""} {
|
||||
set parts [split $creds ","]
|
||||
|
|
@ -1030,7 +1052,20 @@ Environment:
|
|||
}
|
||||
|
||||
proc main {argv} {
|
||||
variable BLUE RED RESET
|
||||
variable BLUE RED RESET ACCOUNT_INDEX
|
||||
|
||||
# Pre-scan for --account N; strip it from argv before dispatch
|
||||
set filtered {}
|
||||
for {set i 0} {$i < [llength $argv]} {incr i} {
|
||||
set a [lindex $argv $i]
|
||||
if {$a eq "--account"} {
|
||||
incr i
|
||||
set ACCOUNT_INDEX [lindex $argv $i]
|
||||
} else {
|
||||
lappend filtered $a
|
||||
}
|
||||
}
|
||||
set argv $filtered
|
||||
|
||||
if {[llength $argv] == 0} {
|
||||
show_help
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue