anastasis-gtk

Demonstrator GUI for Anastasis
Log | Files | Refs | README | LICENSE

test_prepare.sh (17498B)


      1 #!/bin/bash
      2 # Shell script to launch Taler components
      3 # and Anastasis providers for local test
      4 # using TESTKUDOS.
      5 
      6 set -eu
      7 
      8 # Exit, with status code "skip" (no 'real' failure)
      9 function exit_skip() {
     10     echo " SKIP: $1"
     11     exit 77
     12 }
     13 
     14 # Exit, with error message (hard failure)
     15 function exit_fail() {
     16     echo " FAIL: $1"
     17     exit 1
     18 }
     19 
     20 # Cleanup to run whenever we exit
     21 function cleanup()
     22 {
     23     if test -n "${SETUP_PID:-}"
     24     then
     25         kill -TERM "$SETUP_PID" 2> /dev/null || true
     26         wait "$SETUP_PID" 2> /dev/null || true
     27     fi
     28     for n in `jobs -p`
     29     do
     30         kill -SIGCONT $n # in case one provider was suspended
     31         kill $n 2> /dev/null || true
     32     done
     33     rm -rf $CONF $CONF.edited $CONF_4 $CONF_IBAN $WALLET_DB $R1FILE $R2FILE $B1FILE $B2FILE $TMP_DIR
     34     wait
     35 }
     36 
     37 
     38 # Launch the GNU Taler services (bank, exchange, merchant) via
     39 # taler-unified-setup.sh and return once they are up.  Mirrors the setup()
     40 # helper of exchange/src/testing/setup.sh; we cannot source that file as it is
     41 # not installed.  Arguments are passed on to taler-unified-setup.sh.
     42 function taler_setup()
     43 {
     44     local FIFO_DIR
     45     local FIFO_OUT
     46 
     47     # Create a named pipe in a temp directory we own.
     48     FIFO_DIR=`mktemp -d fifo-XXXXXX`
     49     FIFO_OUT="$FIFO_DIR/out"
     50     mkfifo "$FIFO_OUT"
     51     # Open pipe as FD 3 (RW) and FD 4 (RO)
     52     exec 3<> "$FIFO_OUT" 4< "$FIFO_OUT"
     53     rm -rf "$FIFO_DIR"
     54     # '-W' is required for our termination logic to work.
     55     taler-unified-setup.sh -W "$@" >&3 2> taler-unified-setup.log &
     56     SETUP_PID=$!
     57     exec 3>&-
     58     # taler-unified-setup.sh prints "READY:$TESTROOT" once everything is up.
     59     # Read until EOF instead of 'sed -u /READY:/ q' so that we can tell "the
     60     # system came up" apart from "taler-unified-setup.sh died first".
     61     READY=0
     62     while IFS= read -r LINE <&4
     63     do
     64         case "$LINE" in
     65             READY:*)
     66                 READY=1
     67                 break
     68                 ;;
     69         esac
     70     done
     71     exec 4>&-
     72     if test 1 != $READY
     73     then
     74         exit_skip "Failed to launch Taler services, see taler-unified-setup.log"
     75     fi
     76 }
     77 
     78 
     79 # Create a bank account at libeufin-bank.  Prints its payto URI.
     80 # $1 = username, $2 = password, $3 = legal name, $4 = payto URI (optional)
     81 function make_bank_account() {
     82     if test -z "${4:-}"
     83     then
     84         libeufin-bank create-account \
     85                       -c $CONF_IBAN \
     86                       -u "$1" -p "$2" --name "$3" 2>> iban-setup.log
     87     else
     88         libeufin-bank create-account \
     89                       -c $CONF_IBAN \
     90                       -u "$1" -p "$2" --name "$3" --payto_uri "$4" 2>> iban-setup.log
     91     fi
     92 }
     93 
     94 
     95 # Transfer funds from the debit account to the Anastasis account and have
     96 # the Anastasis IBAN helper pick the transfer up.
     97 # $1 = amount ($CURRENCY:X.Y), $2 = subject.
     98 function wire_transfer_to_anastasis() {
     99     curl -s -X POST \
    100          --user "${DEBIT_USERNAME}:${DEBIT_PASSWORD}" \
    101          -H "Content-Type: application/json" \
    102          -d "{\"payto_uri\":\"${PAYTO_CREDIT}&message=$(echo "$2" | jq -sRr @uri)&amount=$1\"}" \
    103          "${IBAN_BANK_URL}accounts/${DEBIT_USERNAME}/transactions" > /dev/null
    104     anastasis-helper-authorization-iban -c $CONF_4 -t -L INFO
    105 }
    106 
    107 
    108 if test "${1:-}" != "free" -a "${1:-}" != "fees"
    109 then
    110     echo "Launch script with either 'free' or 'fees' argument to launch providers with/without fees."
    111     exit 1
    112 fi
    113 
    114 export CONF_1="test_anastasis_reducer_1.conf"
    115 export CONF_2="test_anastasis_reducer_2.conf"
    116 export CONF_3="test_anastasis_reducer_3.conf"
    117 if test $1 = 'free'
    118 then
    119     CONF4="test_anastasis_reducer_4_free.conf"
    120 else
    121     CONF4="test_anastasis_reducer_4.conf"
    122 fi
    123 
    124 # Taler configuration file will be edited, so we create one
    125 # from the template.
    126 export CONF=`mktemp test_reducerXXXXXX.conf`
    127 export CONF_4=`mktemp test_reducer_4XXXXXX.conf`
    128 export CONF_IBAN=`mktemp test_reducer_ibanXXXXXX.conf`
    129 cp test_reducer.conf $CONF
    130 cp $CONF4 $CONF_4
    131 
    132 TMP_DIR=`mktemp -d keys-tmp-XXXXXX`
    133 # wallet-core needs an sqlite3 database; a '.json' name selects the
    134 # no-longer-supported in-memory backend.
    135 WALLET_DB=`mktemp test_reducer_walletXXXXXX.sqlite3`
    136 B1FILE=`mktemp test_reducer_stateB1XXXXXX`
    137 B2FILE=`mktemp test_reducer_stateB2XXXXXX`
    138 R1FILE=`mktemp test_reducer_stateR1XXXXXX`
    139 R2FILE=`mktemp test_reducer_stateR2XXXXXX`
    140 IBAN_ACTIVE='false'
    141 SETUP_PID=''
    142 
    143 # Install cleanup handler (except for kill -9)
    144 trap cleanup EXIT
    145 
    146 # Check we can actually run
    147 if test $1 = 'fees'
    148 then
    149     echo -n "Testing for taler"
    150     taler-exchange-httpd -h > /dev/null || exit_skip " taler-exchange required"
    151     taler-merchant-httpd -h > /dev/null || exit_skip " taler-merchant required"
    152     # note: 'taler-unified-setup.sh -h' exits non-zero (its exit trap wins)
    153     command -v taler-unified-setup.sh > /dev/null || exit_skip " taler-unified-setup.sh required"
    154     echo " FOUND"
    155 
    156     echo -n "Testing for libeufin-bank"
    157     libeufin-bank --help >/dev/null </dev/null || exit_skip " MISSING"
    158     echo " FOUND"
    159 
    160     echo -n "Testing for taler-wallet-cli"
    161     taler-wallet-cli -v >/dev/null </dev/null || exit_skip " MISSING"
    162     echo " FOUND"
    163 
    164     echo -n "Testing for jq"
    165     jq --version >/dev/null </dev/null || exit_skip " MISSING"
    166     echo " FOUND"
    167 fi
    168 
    169 echo -n "Testing for anastasis-httpd"
    170 anastasis-httpd -h >/dev/null </dev/null || exit_skip " MISSING"
    171 echo " FOUND"
    172 
    173 echo -n "Initialize anastasis database ..."
    174 # Name of the Postgres database we will use for the script.
    175 # Will be dropped, do NOT use anything that might be used
    176 # elsewhere
    177 TARGET_DB_1=`anastasis-config -c $CONF_1 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
    178 TARGET_DB_2=`anastasis-config -c $CONF_2 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
    179 TARGET_DB_3=`anastasis-config -c $CONF_3 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
    180 TARGET_DB_4=`anastasis-config -c $CONF_4 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
    181 
    182 dropdb $TARGET_DB_1 >/dev/null 2>/dev/null || true
    183 createdb $TARGET_DB_1 || exit_skip "Could not create database $TARGET_DB_1"
    184 anastasis-dbinit -c $CONF_1 2> anastasis-dbinit_1.log
    185 dropdb $TARGET_DB_2 >/dev/null 2>/dev/null || true
    186 createdb $TARGET_DB_2 || exit_skip "Could not create database $TARGET_DB_2"
    187 anastasis-dbinit -c $CONF_2 2> anastasis-dbinit_2.log
    188 dropdb $TARGET_DB_3 >/dev/null 2>/dev/null || true
    189 createdb $TARGET_DB_3 || exit_skip "Could not create database $TARGET_DB_3"
    190 anastasis-dbinit -c $CONF_3 2> anastasis-dbinit_3.log
    191 dropdb $TARGET_DB_4 >/dev/null 2>/dev/null || true
    192 createdb $TARGET_DB_4 || exit_skip "Could not create database $TARGET_DB_4"
    193 anastasis-dbinit -c $CONF_4 2> anastasis-dbinit_4.log
    194 
    195 echo " OK"
    196 
    197 if test $1 = 'fees'
    198 then
    199 
    200     echo -n "Setting up Taler databases ..."
    201     TALER_DB=talercheck
    202     # bank, exchange and merchant share one database here
    203     taler-exchange-config -c $CONF -s exchangedb-postgres -o CONFIG -V postgres:///$TALER_DB
    204     taler-exchange-config -c $CONF -s merchantdb-postgres -o CONFIG -V postgres:///$TALER_DB
    205     taler-exchange-config -c $CONF -s libeufin-bankdb-postgres -o CONFIG -V postgres:///$TALER_DB
    206     taler-exchange-config -c $CONF -s exchange -o KEYDIR -V "${TMP_DIR}/keydir/"
    207     taler-exchange-config -c $CONF -s exchange -o REVOCATION_DIR -V "${TMP_DIR}/revdir/"
    208     DATA_DIR=`taler-exchange-config -f -c $CONF -s PATHS -o TALER_HOME`
    209     rm -rf $DATA_DIR
    210     dropdb $TALER_DB >/dev/null 2>/dev/null || true
    211     createdb $TALER_DB || exit_skip "Could not create database $TALER_DB"
    212     echo " OK"
    213 
    214     # taler-unified-setup.sh launches the bank (libeufin-bank), the exchange
    215     # (including the secmods and the offline key ceremony) and the merchant
    216     # (including taler-merchant-exchangekeyupdate, without which the merchant
    217     # never learns the exchange's keys and refuses to create orders).  It
    218     # writes the configuration it actually uses to "$CONF.edited".
    219     echo "Launching Taler services ..."
    220     taler_setup -c $CONF -L INFO -b -e -m -w -r merchant-exchange-default
    221     echo "Taler services up"
    222 
    223     BANK_PORT=`taler-exchange-config -c $CONF.edited -s libeufin-bank -o PORT`
    224     BANK_URL="http://localhost:${BANK_PORT}/"
    225     EXCHANGE_URL=`taler-exchange-config -c $CONF.edited -s exchange -o BASE_URL`
    226     MERCHANT_PORT=`taler-merchant-config -c $CONF.edited -s merchant -o PORT`
    227     MERCHANT_URL="http://localhost:${MERCHANT_PORT}/"
    228 
    229     echo -n "Configuring merchant instance ..."
    230     # POST to the merchant and fail loudly if it does not like the request.
    231     # $1 = path, $2 = JSON body
    232     function merchant_post() {
    233         local RESP
    234         local CODE
    235 
    236         RESP=`curl -s -w '\n%{http_code}' -H "Content-Type: application/json" \
    237                    -X POST -d "$2" "${MERCHANT_URL}$1"`
    238         CODE=`echo "$RESP" | tail -n1`
    239         case "$CODE" in
    240             20*)
    241                 ;;
    242             *)
    243                 echo " FAILED ($CODE)"
    244                 echo "$RESP" | head -n-1
    245                 exit_fail "merchant rejected POST /$1"
    246                 ;;
    247         esac
    248     }
    249     # The default instance is called "admin" and is served at the root of the
    250     # merchant; the historic /instances/default/ prefix is gone.  'use_stefan'
    251     # is required by the current merchant protocol.
    252     merchant_post management/instances \
    253         '{"auth":{"method":"external"},"id":"admin","name":"default","address":{},"jurisdiction":{},"use_stefan":true,"default_max_wire_fee":"TESTKUDOS:1","default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us":3600000000},"default_pay_delay":{"d_us":3600000000}}'
    254     # 'fortythree' is one of the accounts taler-unified-setup.sh registers
    255     merchant_post private/accounts \
    256         '{"payto_uri":"payto://x-taler-bank/localhost/fortythree?receiver-name=Forty+Three"}'
    257     echo " OK"
    258 
    259     echo -n "Preparing wallet"
    260     rm -f $WALLET_DB
    261     taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api \
    262                      --expect-success 'withdrawTestBalance' \
    263                      "$(jq -n '
    264     {
    265         amount: "TESTKUDOS:100",
    266         corebankApiBaseUrl: $BANK_URL,
    267         exchangeBaseUrl: $EXCHANGE_URL
    268     }' \
    269     --arg BANK_URL "$BANK_URL" \
    270     --arg EXCHANGE_URL "$EXCHANGE_URL"
    271   )" 2> wallet-withdraw.log >/dev/null
    272     echo -n "."
    273     # the wallet's withdrawal only completes once the exchange has seen the
    274     # incoming wire transfer
    275     taler-exchange-wirewatch -c $CONF.edited -t 2> wirewatch-once.log
    276     echo -n "."
    277     taler-wallet-cli --wallet-db=$WALLET_DB run-until-done 2> wallet-run.log >/dev/null
    278     echo " OK"
    279 
    280     echo -n "Setting up IBAN authentication ..."
    281     # The IBAN challenge needs a bank that speaks IBAN and whose incoming
    282     # transfers Anastasis can see through the taler-revenue API.  That cannot
    283     # be the bank the exchange uses: libeufin-bank serves a single WIRE_TYPE,
    284     # and the exchange side of this test is x-taler-bank.  So we run a second,
    285     # IBAN-typed libeufin-bank for this one authorization method -- it also
    286     # matches the fact that the IBAN challenge is priced in EUR.
    287     IBAN_DB=anastasisibancheck
    288     IBAN_BANK_PORT=8092
    289     IBAN_BANK_URL="http://localhost:${IBAN_BANK_PORT}/"
    290     REASON=""
    291     # both IBANs must pass the checksum: libeufin-bank rejects malformed ones
    292     IBAN_CREDIT="DE44500105175407324931"
    293     IBAN_DEBIT="FR1420041010050500013M02606"
    294     PERSON_CREDIT_NAME="Person Credit"
    295     CREDIT_USERNAME=anastasis-credit-user
    296     CREDIT_PASSWORD=anastasis-credit-password
    297     DEBIT_USERNAME=anastasis-debit-user
    298     DEBIT_PASSWORD=anastasis-debit-password
    299     PAYTO_CREDIT="payto://iban/${IBAN_CREDIT}?receiver-name=Person+Credit"
    300     PAYTO_DEBIT="payto://iban/${IBAN_DEBIT}?receiver-name=Person+Debit"
    301     IBAN_REVENUE_URL="${IBAN_BANK_URL}accounts/${CREDIT_USERNAME}/taler-revenue/"
    302     # the challenge is priced in this currency, e.g. "EUR:1"
    303     IBAN_CURRENCY=`anastasis-config -c $CONF_4 -s authorization-iban -o COST | cut -d: -f1`
    304     cat > $CONF_IBAN <<EOF
    305 # Generated by test_prepare.sh: the "customer's bank" for IBAN challenges.
    306 [PATHS]
    307 TALER_HOME = \${PWD}/test_reducer_home/
    308 TALER_DATA_HOME = \$TALER_HOME/.local/share/taler/
    309 TALER_CONFIG_HOME = \$TALER_HOME/.config/taler/
    310 TALER_CACHE_HOME = \$TALER_HOME/.cache/taler/
    311 TALER_RUNTIME_DIR = \${TMPDIR:-\${TMP:-/tmp}}/taler-system-runtime-\${USER}/
    312 
    313 [libeufin-bank]
    314 CURRENCY = ${IBAN_CURRENCY}
    315 BASE_URL = ${IBAN_BANK_URL}
    316 SERVE = tcp
    317 PORT = ${IBAN_BANK_PORT}
    318 WIRE_TYPE = iban
    319 IBAN_PAYTO_BIC = SANDBOXX
    320 DEFAULT_CUSTOMER_DEBT_LIMIT = ${IBAN_CURRENCY}:200
    321 DEFAULT_ADMIN_DEBT_LIMIT = ${IBAN_CURRENCY}:2000
    322 ALLOW_REGISTRATION = YES
    323 PWD_HASH_CONFIG = { "cost": 4 }
    324 PWD_AUTH_COMPAT = yes
    325 
    326 [libeufin-bankdb-postgres]
    327 CONFIG = postgres:///${IBAN_DB}
    328 EOF
    329     IBAN_ACTIVE='true'
    330     dropdb $IBAN_DB >/dev/null 2>/dev/null || true
    331     if ! createdb $IBAN_DB 2>> iban-setup.log
    332     then
    333         IBAN_ACTIVE='false'
    334     else
    335         libeufin-bank dbinit -c $CONF_IBAN >> iban-setup.log 2>&1
    336         libeufin-bank serve -c $CONF_IBAN >> iban-setup.log 2>&1 &
    337         IBAN_BANK_PID=$!
    338         for n in `seq 1 50`
    339         do
    340             sleep 0.2
    341             wget --tries=1 --timeout=1 "${IBAN_BANK_URL}config" \
    342                  -o /dev/null -O /dev/null >/dev/null && break
    343         done
    344         make_bank_account "$CREDIT_USERNAME" "$CREDIT_PASSWORD" \
    345                           "$PERSON_CREDIT_NAME" "$PAYTO_CREDIT" > /dev/null &&
    346         make_bank_account "$DEBIT_USERNAME" "$DEBIT_PASSWORD" \
    347                           "Person Debit" "$PAYTO_DEBIT" > /dev/null &&
    348         libeufin-bank edit-account -c $CONF_IBAN \
    349                       --debit_threshold="${IBAN_CURRENCY}:1000" \
    350                       "$DEBIT_USERNAME" >> iban-setup.log 2>&1 ||
    351             IBAN_ACTIVE='false'
    352         # Make sure the bank speaks the revenue API that
    353         # anastasis-helper-authorization-iban expects (an empty history is
    354         # answered with 204), so that a version mismatch disables IBAN
    355         # authentication instead of failing challenges at run time.
    356         CODE=`curl -s -o /dev/null -w "%{http_code}" \
    357               --user "${CREDIT_USERNAME}:${CREDIT_PASSWORD}" \
    358               "${IBAN_REVENUE_URL}history?limit=1"`
    359         if test $IBAN_ACTIVE = 'true' &&
    360            test 200 != "$CODE" && test 204 != "$CODE"
    361         then
    362             REASON="revenue API at ${IBAN_REVENUE_URL} answered $CODE"
    363             IBAN_ACTIVE='false'
    364             kill $IBAN_BANK_PID 2> /dev/null || true
    365         fi
    366     fi
    367     if test $IBAN_ACTIVE = 'false'
    368     then
    369         echo " DISABLED (${REASON:-see iban-setup.log})"
    370         anastasis-config -c $CONF_4 -s authorization-iban -o ENABLED -V NO
    371     else
    372         anastasis-config -c $CONF_4 -s authorization-iban -o CURRENCY -V "${IBAN_CURRENCY}"
    373         anastasis-config -c $CONF_4 -s authorization-iban -o CREDIT_IBAN -V "${IBAN_CREDIT}"
    374         anastasis-config -c $CONF_4 -s authorization-iban -o BUSINESS_NAME -V "${PERSON_CREDIT_NAME}"
    375         anastasis-config -c $CONF_4 -s authorization-iban -o WIRE_GATEWAY_URL \
    376                          -V "${IBAN_REVENUE_URL}"
    377         anastasis-config -c $CONF_4 -s authorization-iban -o WIRE_GATEWAY_AUTH_METHOD -V "basic"
    378         anastasis-config -c $CONF_4 -s authorization-iban -o USERNAME -V "${CREDIT_USERNAME}"
    379         anastasis-config -c $CONF_4 -s authorization-iban -o PASSWORD -V "${CREDIT_PASSWORD}"
    380         anastasis-config -c $CONF_4 -s authorization-iban -o ENABLED -V YES
    381         echo " OK"
    382     fi
    383 else
    384     anastasis-config -c $CONF_4 -s authorization-iban -o ENABLED -V NO
    385 fi
    386 
    387 
    388 echo -n "Launching anastasis services ..."
    389 # PREFIX="valgrind --log-file=anastasis-httpd.%p.log"
    390 PREFIX=""
    391 $PREFIX anastasis-httpd -L INFO -c $CONF_1 2> anastasis-httpd_1.log &
    392 PPID_1=$!
    393 $PREFIX anastasis-httpd -L INFO -c $CONF_2 2> anastasis-httpd_2.log &
    394 PPID_2=$!
    395 $PREFIX anastasis-httpd -L INFO -c $CONF_3 2> anastasis-httpd_3.log &
    396 PPID_3=$!
    397 $PREFIX anastasis-httpd -L INFO -c $CONF_4 2> anastasis-httpd_4.log &
    398 PPID_4=$!
    399 export PPID_1
    400 export PPID_2
    401 export PPID_3
    402 export PPID_4
    403 echo " OK"
    404 
    405 echo -n "Waiting for anastasis services ..."
    406 
    407 # Wait for anastasis services to be available
    408 for n in `seq 1 50`
    409 do
    410     echo -n "."
    411     sleep 0.1
    412     OK=0
    413    # anastasis_01
    414     wget --tries=1 --timeout=1 http://localhost:8086/ -o /dev/null -O /dev/null >/dev/null || continue
    415     # anastasis_02
    416     wget --tries=1 --timeout=1 http://localhost:8087/ -o /dev/null -O /dev/null >/dev/null || continue
    417     # anastasis_03
    418     wget --tries=1 --timeout=1 http://localhost:8088/ -o /dev/null -O /dev/null >/dev/null || continue
    419     # anastasis_04
    420     wget --tries=1 --timeout=1 http://localhost:8089/ -o /dev/null -O /dev/null >/dev/null || continue
    421     OK=1
    422     break
    423 done
    424 
    425 if [ 1 != $OK ]
    426 then
    427     exit_skip "Failed to launch anastasis services"
    428 fi
    429 echo "OK"
    430 
    431 export -f wire_transfer_to_anastasis
    432 
    433 echo "You can now run anastasis-gtk in TESTLAND."
    434 echo " "
    435 echo "We will now start a sub-shell. Please note:"
    436 echo '- to terminate the test environment by leaving the sub-shell use: exit'
    437 if test $IBAN_ACTIVE = 'true'
    438 then
    439     echo '- for IBAN authentication use: wire_transfer_to_anastasis "$AMOUNT" "$SUBJECT"'
    440     echo "- for your customer IBAN, use: ${IBAN_DEBIT}"
    441     export IBAN_BANK_URL
    442     export PAYTO_CREDIT
    443     export DEBIT_USERNAME
    444     export DEBIT_PASSWORD
    445     export CONF_4
    446 fi
    447 if test $1 = 'fees'
    448 then
    449     echo '- to pay, use: taler-wallet-cli --wallet-db=$WALLET_DB handle-uri $PAY_URI -y'
    450     export WALLET_DB
    451 fi
    452 
    453 echo '- use kill -SIGSTOP $PPID_$NUM ($NUM: 1-4) to suspend providers'
    454 
    455 bash
    456 
    457 exit 0