feat: EBICS bank detect, regio FLODOS, and check skips
This commit is contained in:
parent
bc785f8466
commit
4e4e6a2925
8 changed files with 256 additions and 22 deletions
|
|
@ -41,6 +41,11 @@ load_monitoring_secrets_env 2>/dev/null || true
|
|||
# Area ladder.* — withdraw/pay amount ladder (any EXPECT_CURRENCY / stack)
|
||||
# Groups: ladder.plan / ladder.load / ladder.withdraw / ladder.pay / ladder.report
|
||||
set_area ladder
|
||||
if [ "${CHECK_BANK:-1}" != "1" ] || [ "${TALER_BANK_BACKEND:-}" = "ebics" ]; then
|
||||
set_group plan
|
||||
info "ladder" "skipped — backend=${TALER_BANK_BACKEND:-ebics} (needs public x-taler-bank)"
|
||||
exit 0
|
||||
fi
|
||||
set_group plan
|
||||
SECTION_T0=$(date +%s)
|
||||
now_ms() { python3 -c 'import time; print(int(time.time()*1000))'; }
|
||||
|
|
@ -128,6 +133,16 @@ INST="${MERCHANT_INSTANCE}"
|
|||
# Uses bank max_wire_transfer_amount and exchange min denom when still on GOA defaults.
|
||||
apply_ladder_stack_defaults() {
|
||||
[ "${LADDER_STACK_AUTO}" = "1" ] || return 0
|
||||
if [ "${CUR}" = "FLODOS" ] || [[ "${TALER_DOMAIN:-}" == *regio.taler.net* ]] || [ "${TALER_DOMAIN:-}" = "regio" ]; then
|
||||
CUR="FLODOS"
|
||||
# demo bank: keep ladder inside a small funded pool (override with LADDER_MAX_AMOUNT=)
|
||||
if [ "${LADDER_MAX_AMOUNT}" = "4503599627370496" ] || [ "${LADDER_MAX_AMOUNT}" = "${GOA_LADDER_CEILING:-}" ]; then
|
||||
LADDER_MAX_AMOUNT="${REGIO_LADDER_MAX:-20}"
|
||||
fi
|
||||
LADDER_MIN_AMOUNT="${LADDER_MIN_AMOUNT:-0.02}"
|
||||
info "ladder stack" "FLODOS/regio · max=${CUR}:${LADDER_MAX_AMOUNT} min=${CUR}:${LADDER_MIN_AMOUNT}"
|
||||
return 0
|
||||
fi
|
||||
if [ "${CUR}" != "TESTPAYSAN" ]; then
|
||||
case "${TALER_DOMAIN:-}" in
|
||||
stage.lefrancpaysan.ch|stage.bank.lefrancpaysan.ch|stage.exchange.lefrancpaysan.ch|stage.monnaie.lefrancpaysan.ch)
|
||||
|
|
@ -259,6 +274,28 @@ resolve_explorer_pw() {
|
|||
return 0
|
||||
fi
|
||||
|
||||
# regio.taler.net (FLODOS) — dedicated pool user, not admin (override default EXP_USER=explorer)
|
||||
if [ "${CUR:-${EXPECT_CURRENCY:-}}" = "FLODOS" ] \
|
||||
|| [[ "${TALER_DOMAIN:-}" == *regio.taler.net* ]] || [ "${TALER_DOMAIN:-}" = "regio" ]; then
|
||||
if [ -n "${REGIO_BANK_EXPLORER_USER_FILE:-}" ] && [ -f "${REGIO_BANK_EXPLORER_USER_FILE}" ]; then
|
||||
EXP_USER=$(tr -d '\n\r' <"${REGIO_BANK_EXPLORER_USER_FILE}")
|
||||
elif [ -n "${TALER_DEPLOYMENT_SECRETS:-}" ] && [ -f "${TALER_DEPLOYMENT_SECRETS}/regio/bank-explorer-user.txt" ]; then
|
||||
EXP_USER=$(tr -d '\n\r' <"${TALER_DEPLOYMENT_SECRETS}/regio/bank-explorer-user.txt")
|
||||
else
|
||||
EXP_USER="${EXP_USER:-lena.v92}"
|
||||
[ "$EXP_USER" = "explorer" ] && EXP_USER=lena.v92
|
||||
fi
|
||||
export EXP_USER
|
||||
if [ -n "${REGIO_BANK_EXPLORER_SECRET:-}" ] && [ -f "${REGIO_BANK_EXPLORER_SECRET}" ]; then
|
||||
tr -d '\n\r' <"${REGIO_BANK_EXPLORER_SECRET}"
|
||||
return 0
|
||||
fi
|
||||
if [ -n "${TALER_DEPLOYMENT_SECRETS:-}" ] && [ -f "${TALER_DEPLOYMENT_SECRETS}/regio/bank-explorer-password.txt" ]; then
|
||||
tr -d '\n\r' <"${TALER_DEPLOYMENT_SECRETS}/regio/bank-explorer-password.txt"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Stage TESTPAYSAN — never use GOA koopa-admin-secrets explorer pw first
|
||||
if [ "${CUR}" = "TESTPAYSAN" ] \
|
||||
|| [[ "${TALER_DOMAIN:-}" == stage.*lefrancpaysan* ]] \
|
||||
|
|
@ -532,6 +569,18 @@ metrics_report_load "$LOAD_BEFORE" "ladder-start" || true
|
|||
# Fresh wallet per rung — baseline empty (or last-rung DB if re-used later)
|
||||
metrics_report_coins "ladder-start" || true
|
||||
|
||||
# EXP_USER must be set in this shell (resolve_explorer_pw runs in $(…) subshell)
|
||||
if [ "${CUR:-${EXPECT_CURRENCY:-}}" = "FLODOS" ] \
|
||||
|| [[ "${TALER_DOMAIN:-}" == *regio.taler.net* ]] || [ "${TALER_DOMAIN:-}" = "regio" ]; then
|
||||
if [ -n "${REGIO_BANK_EXPLORER_USER_FILE:-}" ] && [ -f "${REGIO_BANK_EXPLORER_USER_FILE}" ]; then
|
||||
EXP_USER=$(tr -d '\n\r' <"${REGIO_BANK_EXPLORER_USER_FILE}")
|
||||
elif [ -n "${TALER_DEPLOYMENT_SECRETS:-}" ] && [ -f "${TALER_DEPLOYMENT_SECRETS}/regio/bank-explorer-user.txt" ]; then
|
||||
EXP_USER=$(tr -d '\n\r' <"${TALER_DEPLOYMENT_SECRETS}/regio/bank-explorer-user.txt")
|
||||
elif [ -z "${EXP_USER:-}" ] || [ "${EXP_USER}" = "explorer" ]; then
|
||||
EXP_USER=lena.v92
|
||||
fi
|
||||
export EXP_USER
|
||||
fi
|
||||
if ! EXP_PW=$(resolve_explorer_pw); then
|
||||
err bank "explorer password missing" \
|
||||
"set EXP_PW / EXP_PW_FILE or SECRETS_ROOT=…/koopa/host-root (taler-bank/bank-explorer-password.txt)${SECRETS_ROOT:+ · SECRETS_ROOT=${SECRETS_ROOT}}"
|
||||
|
|
@ -539,9 +588,9 @@ if ! EXP_PW=$(resolve_explorer_pw); then
|
|||
exit 1
|
||||
fi
|
||||
if [ -n "${SECRETS_ROOT:-}" ]; then
|
||||
info "explorer secret" "resolved (SECRETS_ROOT=${SECRETS_ROOT} · stage uses stagepaysan secret first when CUR=TESTPAYSAN)"
|
||||
info "explorer secret" "resolved user=${EXP_USER} (SECRETS_ROOT=${SECRETS_ROOT})"
|
||||
else
|
||||
info "explorer secret" "resolved via EXP_PW / EXP_PW_FILE / stage SSH / koopa"
|
||||
info "explorer secret" "resolved user=${EXP_USER} via EXP_PW / file / stage SSH / koopa"
|
||||
fi
|
||||
if [ -n "${CLI_JS:-}" ] && [ -f "${CLI_JS}" ]; then
|
||||
ok "wallet-cli" "$CLI_JS"
|
||||
|
|
@ -556,20 +605,66 @@ if ! wcli balance >"$SCRATCH/wcli-smoke.out" 2>&1; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# --- auto-account ---
|
||||
# --- personal account (intro auto-account, else open registration) ---
|
||||
t0=$(now_ms)
|
||||
if ! curl -sS -m 30 -o "$SCRATCH/auto-account.json" "${BANK}/intro/auto-account.json"; then
|
||||
err bank "auto-account.json unreachable"
|
||||
exit 1
|
||||
_acct_ok=0
|
||||
if curl -sS -m 30 -o "$SCRATCH/auto-account.json" "${BANK}/intro/auto-account.json" \
|
||||
&& python3 -c 'import json; d=json.load(open("'"$SCRATCH"'/auto-account.json")); assert d.get("ok") or d.get("username")' 2>/dev/null; then
|
||||
_acct_ok=1
|
||||
elif [ "${CUR:-}" = "FLODOS" ] || [[ "${TALER_DOMAIN:-}" == *regio.taler.net* ]]; then
|
||||
# regio has no /intro landings — register a discreet one-shot user (disposable mail list)
|
||||
_mail_file="${REGIO_DISPOSABLE_EMAILS:-${TALER_DEPLOYMENT_SECRETS:+$TALER_DEPLOYMENT_SECRETS/regio/disposable-emails.txt}}"
|
||||
_email=""
|
||||
if [ -n "${_mail_file:-}" ] && [ -f "$_mail_file" ]; then
|
||||
_email=$(awk -F'\t' '$2=="UNUSED" && $1 !~ /^#/ {print $1; exit}' "$_mail_file")
|
||||
fi
|
||||
: "${_email:=sofia.keller4@grr.la}"
|
||||
_user=$(printf '%s' "$_email" | python3 -c 'import sys; e=sys.stdin.read().strip().split("@")[0]; print((e.replace(".","")[:10])+str(abs(hash(e))%100))')
|
||||
_pw=$(openssl rand -base64 18 | tr -d '/+=' | head -c 20)
|
||||
_name=$(printf '%s' "$_email" | python3 -c 'import sys; e=sys.stdin.read().strip().split("@")[0].replace("."," ").title(); print(e)')
|
||||
_code=$(curl -sS -m 20 -o "$SCRATCH/auto-account.raw" -w '%{http_code}' -X POST \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "{\"username\":\"${_user}\",\"password\":\"${_pw}\",\"name\":\"${_name}\",\"email\":\"${_email}\"}" \
|
||||
"${BANK}/accounts")
|
||||
if [ "$_code" = "200" ] || [ "$_code" = "201" ]; then
|
||||
python3 - "$_user" "$_pw" "$_name" "$_email" "$SCRATCH/auto-account.json" <<'PY'
|
||||
import json,sys
|
||||
u,p,n,e,out=sys.argv[1:6]
|
||||
json.dump({"ok":True,"created_for_you":True,"username":u,"password":p,"name":n,"email":e,"balance":"FLODOS:0"}, open(out,"w"))
|
||||
PY
|
||||
if [ -n "${_mail_file:-}" ] && [ -f "$_mail_file" ]; then
|
||||
python3 - "$_mail_file" "$_email" "$_user" <<'PY'
|
||||
from pathlib import Path
|
||||
import sys
|
||||
p,email,user=Path(sys.argv[1]),sys.argv[2],sys.argv[3]
|
||||
lines=[]
|
||||
for line in p.read_text().splitlines():
|
||||
if line.startswith(email+"\t") or line.startswith(email+" "):
|
||||
parts=line.split("\t")
|
||||
while len(parts)<3: parts.append("")
|
||||
parts[1]="USED"
|
||||
parts[2]=f"personal {user}"
|
||||
line="\t".join(parts)
|
||||
lines.append(line)
|
||||
p.write_text("\n".join(lines)+"\n")
|
||||
PY
|
||||
fi
|
||||
_acct_ok=1
|
||||
info "personal account" "open-register ${_user} (no /intro; disposable mail)"
|
||||
else
|
||||
err bank "open register failed HTTP ${_code}" "$(head -c 120 "$SCRATCH/auto-account.raw" | tr '\n' ' ')"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
ms_auto=$(elapsed_ms "$t0")
|
||||
if ! python3 -c 'import json; d=json.load(open("'"$SCRATCH"'/auto-account.json")); assert d.get("ok") or d.get("username")' 2>/dev/null; then
|
||||
err bank "auto-account create failed" "$(head -c 120 "$SCRATCH/auto-account.json" | tr '\n' ' ')"
|
||||
if [ "$_acct_ok" != "1" ]; then
|
||||
err bank "auto-account create failed" "$(head -c 120 "$SCRATCH/auto-account.json" 2>/dev/null | tr '\n' ' ')"
|
||||
exit 1
|
||||
fi
|
||||
ACCT_USER=$(python3 -c 'import json; print(json.load(open("'"$SCRATCH"'/auto-account.json"))["username"])')
|
||||
ok "auto-account ${ACCT_USER} (${ms_auto}ms) — personal ${CUR}:0; pool=explorer"
|
||||
ok "auto-account ${ACCT_USER} (${ms_auto}ms) — personal ${CUR}:0; pool=${EXP_USER:-explorer}"
|
||||
info "auto-account password" "(see $SCRATCH/auto-account.json — not logged)"
|
||||
unset _acct_ok _mail_file _email _user _pw _name _code
|
||||
|
||||
# --- explorer token ---
|
||||
t0=$(now_ms)
|
||||
|
|
|
|||
Reference in a new issue