feat: EBICS bank detect, regio FLODOS, and check skips

This commit is contained in:
Hernâni Marques 2026-09-04 11:23:47 +02:00
parent bc785f8466
commit 4e4e6a2925
No known key found for this signature in database
8 changed files with 256 additions and 22 deletions

89
lib.sh
View file

@ -79,6 +79,12 @@ fi
: "${EXCHANGE_LOCAL:=http://127.0.0.1:9011}"
: "${MERCHANT_LOCAL:=https://127.0.0.1:9010}"
: "${LANDING_LOCAL:=http://127.0.0.1:9013}"
# Public libeufin bank.* checks (urls/sanity/e2e). Auto 0 for EBICS/IBAN wire.
: "${CHECK_BANK:=1}"
: "${CHECK_BANK_SET:=0}"
# x-taler-bank | ebics | unknown — filled by resolve_taler_bank_backend
: "${TALER_BANK_BACKEND:=}"
: "${TALER_BANK_BACKEND_SET:=0}"
# Hostnames/paths: set via ~/.config/taler-monitoring/env (no hardcoded machine values).
: "${KOOPA_SSH:=}"
: "${KOOPA_SSH_FALLBACKS:=}"
@ -149,16 +155,77 @@ MERCHANT_PUBLIC=${MERCHANT_PUBLIC%/}
_MONITOR_LIB_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
: "${TALER_DOMAINS_CONF:=${_MONITOR_LIB_DIR}/domains.conf}"
# host_or_url → https://… (no trailing slash)
# host_or_url → https://… (no trailing slash). Empty for EBICS skip tokens.
_to_https_base() {
local x="${1%/}"
case "$x" in
case "$(printf '%s' "$x" | tr '[:upper:]' '[:lower:]')" in
""|"-"|"."|"none"|"n/a"|"na"|"ebics"|"iban"|"skip"|"off")
printf ''
;;
https://*|http://*) printf '%s' "$x" ;;
"") printf '' ;;
*) printf 'https://%s' "$x" ;;
esac
}
# True when domains.conf bank column means "no public bank.*"
bank_host_configured() {
local b
b=$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')
case "$b" in
""|"-"|"."|"none"|"n/a"|"na"|"ebics"|"iban"|"skip"|"off") return 1 ;;
*) return 0 ;;
esac
}
# Fetch exchange /keys and classify → x-taler-bank|ebics|unknown
# (python fetch avoids SIGPIPE/pipefail on huge /keys bodies)
detect_taler_bank_backend_from_keys() {
local ex="${EXCHANGE_PUBLIC%/}"
[ -n "$ex" ] || { printf 'unknown'; return 0; }
python3 -c '
import re, ssl, sys, urllib.error, urllib.request
ex = sys.argv[1].rstrip("/")
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
req = urllib.request.Request(
ex + "/keys",
headers={"User-Agent": "taler-monitoring/bank-backend"},
method="GET",
)
try:
with urllib.request.urlopen(req, timeout=10, context=ctx) as resp:
text = resp.read(600000).decode("utf-8", "replace")
except Exception:
print("unknown")
raise SystemExit(0)
methods = {m.lower() for m in re.findall(r"payto://([a-z0-9-]+)/", text, flags=re.I)}
if "x-taler-bank" in methods:
print("x-taler-bank")
elif "iban" in methods:
print("ebics")
else:
print("unknown")
' "$ex" 2>/dev/null || printf 'unknown'
}
# Set TALER_BANK_BACKEND + auto CHECK_BANK=0 for EBICS (unless CHECK_BANK_SET=1).
resolve_taler_bank_backend() {
local backend="${TALER_BANK_BACKEND:-}"
if [ "${TALER_BANK_BACKEND_SET:-0}" = "1" ] && [ -n "$backend" ]; then
:
elif [ -z "${BANK_PUBLIC}" ]; then
backend=ebics
else
backend=$(detect_taler_bank_backend_from_keys)
fi
TALER_BANK_BACKEND="$backend"
if [ "$TALER_BANK_BACKEND" = "ebics" ] && [ "${CHECK_BANK_SET:-0}" != "1" ]; then
CHECK_BANK=0
fi
export TALER_BANK_BACKEND CHECK_BANK CHECK_BANK_SET TALER_BANK_BACKEND_SET
}
# 1 = check GOA-style /intro landing pages (assets, link crawl, demo-withdraw).
# 0 = skip (e.g. taler-ops.ch / mytops — no public landings).
: "${CHECK_LANDING:=1}"
@ -166,12 +233,19 @@ _to_https_base() {
# Declare bank + exchange + merchant (+ currency, local stack, landing, domain id).
# Usage:
# set_taler_stack BANK EXCHANGE MERCHANT [CURRENCY] [LOCAL 0|1] [LANDING 0|1] [TALER_DOMAIN]
# BANK/EXCHANGE/MERCHANT: hostname or full URL
# BANK/EXCHANGE/MERCHANT: hostname or full URL; bank may be "-" / ebics (no public bank.*)
set_taler_stack() {
local bank="${1:-}" exchange="${2:-}" merchant="${3:-}"
local currency="${4:-}" local_stack="${5:-0}" landing="${6:-}" domain_id="${7:-}"
BANK_PUBLIC=$(_to_https_base "$bank")
if bank_host_configured "$bank"; then
BANK_PUBLIC=$(_to_https_base "$bank")
else
BANK_PUBLIC=""
if [ "${TALER_BANK_BACKEND_SET:-0}" != "1" ]; then
TALER_BANK_BACKEND=ebics
fi
fi
EXCHANGE_PUBLIC=$(_to_https_base "$exchange")
MERCHANT_PUBLIC=$(_to_https_base "$merchant")
# currency "-" or empty → report-only (do not force GOA)
@ -452,6 +526,11 @@ apply_taler_domain() {
if [ "${LOCAL_STACK}" = "1" ]; then
INSIDE_PROFILE="${INSIDE_PROFILE:-koopa}"
fi
# EBICS/IBAN (TOPS) → no public bank.*; x-taler-bank → keep CHECK_BANK
if [ "${TALER_SKIP_BANK_BACKEND_DETECT:-0}" != "1" ]; then
resolve_taler_bank_backend
fi
}
# Apply TALER_DOMAIN from env once (CLI exports TALER_DOMAIN_APPLIED=1 after overrides).