merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

test_merchant_mfa.sh (11341B)


      1 #!/usr/bin/env bash
      2 # This file is part of TALER
      3 # Copyright (C) 2025 Taler Systems SA
      4 #
      5 # TALER is free software; you can redistribute it and/or modify
      6 # it under the terms of the GNU General Public License as
      7 # published by the Free Software Foundation; either version 3, or
      8 # (at your option) any later version.
      9 #
     10 # TALER is distributed in the hope that it will be useful, but
     11 # WITHOUT ANY WARRANTY; without even the implied warranty of
     12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 # GNU General Public License for more details.
     14 #
     15 # You should have received a copy of the GNU General Public
     16 # License along with TALER; see the file COPYING.  If not, see
     17 # <http://www.gnu.org/licenses/>
     18 #
     19 set -eu
     20 
     21 . setup.sh
     22 
     23 
     24 # Launch system.
     25 setup \
     26     -c "test_merchant_mfa.conf" \
     27     -m
     28 LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX)
     29 
     30 echo -n "Configuring a merchant admin instance ..."
     31 
     32 STATUS=$(curl -H "Content-Type: application/json" -X POST \
     33     -H 'Authorization: Bearer secret-token:super_secret' \
     34     http://localhost:9966/management/instances \
     35     -d '{"auth":{"method":"external"},"id":"admin","name":"default","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \
     36     -w "%{http_code}" -s \
     37     -o "$LAST_RESPONSE")
     38 
     39 if [ "$STATUS" != "204" ]
     40 then
     41     jq < "$LAST_RESPONSE"
     42     exit_fail "Expected 204 ok, instance created. got: $STATUS"
     43 fi
     44 
     45 STATUS=$(curl -H "Content-Type: application/json" -X POST \
     46     -H 'Authorization: Bearer secret-token:super_secret' \
     47     http://localhost:9966/private/accounts \
     48     -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/43?receiver-name=user43"}' \
     49     -w "%{http_code}" -s \
     50     -o "$LAST_RESPONSE")
     51 
     52 
     53 if [ "$STATUS" != "200" ]
     54 then
     55     jq < "$LAST_RESPONSE"
     56     exit_fail "Expected 200 OK. Got: $STATUS"
     57 fi
     58 
     59 echo " OK"
     60 echo -n "Self-provision instance ..."
     61 
     62 STATUS=$(curl -H "Content-Type: application/json" -X POST \
     63     http://localhost:9966/instances \
     64     -d '{"auth":{"method":"token", "password":"pass1234"},"id":"self","name":"default","phone_number":"+4171234","email":"self@example.com","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \
     65     -w "%{http_code}" -s \
     66     -o "$LAST_RESPONSE")
     67 
     68 if [ "$STATUS" != "202" ]
     69 then
     70     jq < "$LAST_RESPONSE"
     71     exit_fail "Expected 202 Accepted. Got: $STATUS"
     72 fi
     73 echo " OK"
     74 
     75 C1=$(jq -r .challenges[0].challenge_id < "$LAST_RESPONSE")
     76 C2=$(jq -r .challenges[1].challenge_id < "$LAST_RESPONSE")
     77 
     78 echo -n "Requesting challenge $C1 "
     79 
     80 STATUS=$(curl -H "Content-Type: application/json" -X POST \
     81     "http://localhost:9966/challenge/$C1" \
     82     -d '{}' \
     83     -w "%{http_code}" -s \
     84     -o "$LAST_RESPONSE")
     85 
     86 if [ "$STATUS" != "200" ]
     87 then
     88     jq < "$LAST_RESPONSE"
     89     exit_fail "Expected 200 OK. Got: $STATUS"
     90 fi
     91 echo "OK"
     92 
     93 TAN=$(cat /tmp/test-merchant-email-tan.txt | head -n1 | awk '{print $1}')
     94 ADDR=$(cat /tmp/test-merchant-email-address.txt)
     95 
     96 if [ "$ADDR" != "self@example.com" ]
     97 then
     98     exit_fail "Expected address 'self@example.com'. Got: $ADDR"
     99 fi
    100 
    101 echo -n "Sending challenge $C1 solution "
    102 
    103 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    104     "http://localhost:9966/challenge/$C1/confirm" \
    105     -d '{"tan":"'"$TAN"'"}' \
    106     -w "%{http_code}" -s \
    107     -o "$LAST_RESPONSE")
    108 
    109 if [ "$STATUS" != "204" ]
    110 then
    111     jq < "$LAST_RESPONSE"
    112     exit_fail "Expected 204 OK. Got: $STATUS"
    113 fi
    114 echo "OK"
    115 
    116 
    117 echo -n "Requesting challenge $C2 "
    118 
    119 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    120     "http://localhost:9966/challenge/$C2" \
    121     -d '{}' \
    122     -w "%{http_code}" -s \
    123     -o "$LAST_RESPONSE")
    124 
    125 if [ "$STATUS" != "200" ]
    126 then
    127     jq < "$LAST_RESPONSE"
    128     exit_fail "Expected 200 OK. Got: $STATUS"
    129 fi
    130 echo "OK"
    131 
    132 TAN=$(cat /tmp/test-merchant-sms-tan.txt | head -n1 | awk '{print $1}')
    133 
    134 echo -n "Sending challenge $C2 solution "
    135 
    136 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    137     "http://localhost:9966/challenge/$C2/confirm" \
    138     -d '{"tan":"'"$TAN"'"}' \
    139     -w "%{http_code}" -s \
    140     -o "$LAST_RESPONSE")
    141 
    142 if [ "$STATUS" != "204" ]
    143 then
    144     jq < "$LAST_RESPONSE"
    145     exit_fail "Expected 204 OK. Got: $STATUS"
    146 fi
    147 echo "OK"
    148 
    149 
    150 echo -n "Retrying instance creation with other body "
    151 
    152 STATUS=$(curl \
    153     -H "Content-Type: application/json" \
    154     -H "Taler-Challenge-Ids: $C1,$C2" \
    155     -X POST \
    156     http://localhost:9966/instances \
    157     -d '{"auth":{"method":"external"},"id":"self","name":"change","phone_number":"+4171234","email":"self@example.com","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \
    158     -w "%{http_code}" -s \
    159     -o "$LAST_RESPONSE")
    160 
    161 if [ "$STATUS" != "202" ]
    162 then
    163     jq < "$LAST_RESPONSE"
    164     exit_fail "Expected 202 Accepted. Got: $STATUS"
    165 fi
    166 echo "OK"
    167 
    168 
    169 
    170 echo -n "Retrying instance creation with original body "
    171 
    172 STATUS=$(curl \
    173     -H "Content-Type: application/json" \
    174     -H "Taler-Challenge-Ids: $C1,$C2" \
    175     -X POST \
    176     http://localhost:9966/instances \
    177     -d '{"auth":{"method":"token", "password":"pass1234"},"id":"self","name":"default","phone_number":"+4171234","email":"self@example.com","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \
    178     -w "%{http_code}" -s \
    179     -o "$LAST_RESPONSE")
    180 
    181 if [ "$STATUS" != "204" ]
    182 then
    183     jq < "$LAST_RESPONSE"
    184     exit_fail "Expected 204 OK. Got: $STATUS"
    185 fi
    186 
    187 echo "OK"
    188 
    189 
    190 echo -n "Unauthorized trigger MFA to add bank account "
    191 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    192     -H 'Authorization: Bearer secret-token:bad_password' \
    193     http://localhost:9966/instances/self/private/accounts \
    194     -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/44?receiver-name=user44"}' \
    195     -w "%{http_code}" -s \
    196     -o "$LAST_RESPONSE")
    197 
    198 if [ "$STATUS" != "401" ]
    199 then
    200     jq < "$LAST_RESPONSE"
    201     exit_fail "Expected 401 Forbidden. Got: $STATUS"
    202 fi
    203 
    204 echo " OK"
    205 
    206 
    207 echo -n "Do NOT Trigger MFA to add first bank account "
    208 STATUS=$(curl \
    209     -H "Content-Type: application/json" \
    210     -X POST \
    211     -H 'Authorization: Bearer secret-token:pass1234' \
    212     http://localhost:9966/instances/self/private/accounts \
    213     -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/44?receiver-name=user44"}' \
    214     -w "%{http_code}" -s \
    215     -o "$LAST_RESPONSE")
    216 
    217 if [ "$STATUS" != "200" ]
    218 then
    219     jq < "$LAST_RESPONSE"
    220     exit_fail "Expected 200 OK. Got: $STATUS"
    221 fi
    222 
    223 echo " OK"
    224 
    225 
    226 echo -n "Trigger MFA to add 2nd bank account with 2-FA authorization "
    227 STATUS=$(curl \
    228     -H "Content-Type: application/json" \
    229     -X POST \
    230     -H 'Authorization: Bearer secret-token:pass1234' \
    231     http://localhost:9966/instances/self/private/accounts \
    232     -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/45?receiver-name=user45"}' \
    233     -w "%{http_code}" -s \
    234     -o "$LAST_RESPONSE")
    235 
    236 if [ "$STATUS" != "202" ]
    237 then
    238     jq < "$LAST_RESPONSE"
    239     exit_fail "Expected 202 Accepted. Got: $STATUS"
    240 fi
    241 
    242 echo " OK"
    243 
    244 
    245 C1=$(jq -r .challenges[0].challenge_id < "$LAST_RESPONSE")
    246 
    247 # Delete old TANs.
    248 rm /tmp/test-merchant-*-tan.txt
    249 echo -n "Requesting challenge $C1 "
    250 
    251 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    252     "http://localhost:9966/challenge/$C1" \
    253     -d '{}' \
    254     -w "%{http_code}" -s \
    255     -o "$LAST_RESPONSE")
    256 
    257 if [ "$STATUS" != "200" ]
    258 then
    259     jq < "$LAST_RESPONSE"
    260     exit_fail "Expected 200 OK. Got: $STATUS"
    261 fi
    262 echo "OK"
    263 
    264 TAN=$(cat /tmp/test-merchant-email-tan.txt | head -n1 | awk '{print $1}')
    265 ADDR=$(cat /tmp/test-merchant-email-address.txt)
    266 
    267 if [ "$ADDR" != "self@example.com" ]
    268 then
    269     exit_fail "Expected address 'self@example.com'. Got: $ADDR"
    270 fi
    271 
    272 echo -n "Sending challenge $C1 solution "
    273 
    274 STATUS=$(curl \
    275     -H "Content-Type: application/json" \
    276     -X POST \
    277     "http://localhost:9966/challenge/$C1/confirm" \
    278     -d '{"tan":"'"$TAN"'"}' \
    279     -w "%{http_code}" -s \
    280     -o "$LAST_RESPONSE")
    281 
    282 if [ "$STATUS" != "204" ]
    283 then
    284     jq < "$LAST_RESPONSE"
    285     exit_fail "Expected 204 OK. Got: $STATUS"
    286 fi
    287 echo "OK"
    288 
    289 echo -n "Finally, add 2nd bank account "
    290 STATUS=$(curl \
    291     -X POST \
    292     -H "Content-Type: application/json" \
    293     -H "Taler-Challenge-Ids: $C1" \
    294     -H 'Authorization: Bearer secret-token:pass1234' \
    295     http://localhost:9966/instances/self/private/accounts \
    296     -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/45?receiver-name=user45"}' \
    297     -w "%{http_code}" -s \
    298     -o "$LAST_RESPONSE")
    299 
    300 if [ "$STATUS" != "200" ]
    301 then
    302     jq < "$LAST_RESPONSE"
    303     exit_fail "Expected 200 OK. Got: $STATUS"
    304 fi
    305 
    306 echo " OK"
    307 
    308 
    309 echo -n "Begin forgotten password reset "
    310 STATUS=$(curl \
    311     -X POST \
    312     -H "Content-Type: application/json" \
    313     http://localhost:9966/instances/self/forgot-password \
    314     -d '{"method":"token","password":"amnesia"}' \
    315     -w "%{http_code}" -s \
    316     -o "$LAST_RESPONSE")
    317 
    318 if [ "$STATUS" != "202" ]
    319 then
    320     jq < "$LAST_RESPONSE"
    321     exit_fail "Expected 202 Accepted. Got: $STATUS"
    322 fi
    323 
    324 echo " OK"
    325 
    326 C1=$(jq -r .challenges[0].challenge_id < "$LAST_RESPONSE")
    327 C2=$(jq -r .challenges[1].challenge_id < "$LAST_RESPONSE")
    328 
    329 echo -n "Requesting challenge $C1 "
    330 
    331 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    332     "http://localhost:9966/challenge/$C1" \
    333     -d '{}' \
    334     -w "%{http_code}" -s \
    335     -o "$LAST_RESPONSE")
    336 
    337 if [ "$STATUS" != "200" ]
    338 then
    339     jq < "$LAST_RESPONSE"
    340     exit_fail "Expected 200 OK. Got: $STATUS"
    341 fi
    342 echo "OK"
    343 
    344 TAN=$(cat /tmp/test-merchant-email-tan.txt | head -n1 | awk '{print $1}')
    345 ADDR=$(cat /tmp/test-merchant-email-address.txt)
    346 
    347 if [ "$ADDR" != "self@example.com" ]
    348 then
    349     exit_fail "Expected address 'self@example.com'. Got: $ADDR"
    350 fi
    351 
    352 echo -n "Sending challenge $C1 solution "
    353 
    354 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    355     "http://localhost:9966/challenge/$C1/confirm" \
    356     -d '{"tan":"'"$TAN"'"}' \
    357     -w "%{http_code}" -s \
    358     -o "$LAST_RESPONSE")
    359 
    360 if [ "$STATUS" != "204" ]
    361 then
    362     jq < "$LAST_RESPONSE"
    363     exit_fail "Expected 204 OK. Got: $STATUS"
    364 fi
    365 echo "OK"
    366 
    367 
    368 echo -n "Requesting challenge $C2 "
    369 
    370 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    371     "http://localhost:9966/challenge/$C2" \
    372     -d '{}' \
    373     -w "%{http_code}" -s \
    374     -o "$LAST_RESPONSE")
    375 
    376 if [ "$STATUS" != "200" ]
    377 then
    378     jq < "$LAST_RESPONSE"
    379     exit_fail "Expected 200 OK. Got: $STATUS"
    380 fi
    381 echo "OK"
    382 
    383 TAN=$(cat /tmp/test-merchant-sms-tan.txt | head -n1 | awk '{print $1}')
    384 
    385 echo -n "Sending challenge $C2 solution "
    386 
    387 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    388     "http://localhost:9966/challenge/$C2/confirm" \
    389     -d '{"tan":"'"$TAN"'"}' \
    390     -w "%{http_code}" -s \
    391     -o "$LAST_RESPONSE")
    392 
    393 if [ "$STATUS" != "204" ]
    394 then
    395     jq < "$LAST_RESPONSE"
    396     exit_fail "Expected 204 OK. Got: $STATUS"
    397 fi
    398 echo "OK"
    399 
    400 echo -n "Complete password reset "
    401 STATUS=$(curl \
    402     -X POST \
    403     -H "Content-Type: application/json" \
    404     -H "Taler-Challenge-Ids: $C1,$C2" \
    405     http://localhost:9966/instances/self/forgot-password \
    406     -d '{"method":"token","password":"amnesia"}' \
    407     -w "%{http_code}" -s \
    408     -o "$LAST_RESPONSE")
    409 
    410 if [ "$STATUS" != "204" ]
    411 then
    412     jq < "$LAST_RESPONSE"
    413     exit_fail "Expected 204 No content. Got: $STATUS"
    414 fi
    415 
    416 echo " OK"
    417 
    418 
    419 
    420 
    421 
    422 echo "TEST PASSED"
    423 
    424 exit 0