test_anastasis_reducer_recovery_enter_user_attributes.sh (14061B)
1 #!/bin/bash 2 # This file is in the public domain. 3 4 # shellcheck disable=SC2317 5 6 set -eu 7 8 # Replace with 0 for nexus... 9 USE_FAKEBANK=1 10 if [ 1 = "$USE_FAKEBANK" ] 11 then 12 ACCOUNT="exchange-account-2" 13 WIRE_METHOD="x-taler-bank" 14 BANK_FLAGS="-f -d $WIRE_METHOD -u $ACCOUNT" 15 BANK_URL="http://localhost:18082/" 16 MERCHANT_PAYTO="payto://x-taler-bank/localhost/anastasis?receiver-name=anastasis" 17 else 18 ACCOUNT="exchange-account-1" 19 WIRE_METHOD="iban" 20 BANK_FLAGS="-ns -d $WIRE_METHOD -u $ACCOUNT" 21 BANK_URL="http://localhost:18082/" 22 MERCHANT_PAYTO="payto://iban/SANDBOXX/DE648226?receiver-name=anastasis" 23 fi 24 25 # Check we can actually run 26 echo -n "Testing for jq" 27 jq -h > /dev/null || exit_skip "jq required" 28 echo " FOUND" 29 echo -n "Testing for anastasis-reducer ..." 30 anastasis-reducer -h > /dev/null || exit_skip "anastasis-reducer required" 31 echo " FOUND" 32 33 echo -n "Testing for taler" 34 taler-exchange-httpd -h > /dev/null || exit_skip " taler-exchange required" 35 taler-merchant-httpd -h > /dev/null || exit_skip " taler-merchant required" 36 echo " FOUND" 37 38 echo -n "Testing for taler-wallet-cli" 39 taler-wallet-cli -v >/dev/null </dev/null || exit_skip " MISSING" 40 echo " FOUND" 41 42 echo -n "Testing for anastasis-httpd" 43 anastasis-httpd -h >/dev/null </dev/null || exit_skip " MISSING" 44 echo " FOUND" 45 46 . setup.sh 47 # Launch exchange, merchant and bank. 48 # shellcheck disable=SC2086 49 setup -c "test_reducer.conf" \ 50 -emw \ 51 -r merchant-exchange-default \ 52 $BANK_FLAGS 53 54 # Cleanup to run whenever we exit 55 function cleanup() 56 { 57 exit_cleanup 58 for n in $(jobs -p) 59 do 60 kill "$n" 2> /dev/null || true 61 done 62 rm -rf "$CONF" "$WALLET_DB" "$R1FILE" "$R2FILE" "$B1FILE" "$B2FILE" "$TMP_DIR" 63 wait 64 } 65 66 function sync_providers() { 67 infile=$1 68 outfile=$2 69 echo "Synchronizing providers" 70 # Sync with providers (up to 3 providers aren't synced here) 71 for x in 1 2 3; do 72 echo "Synchronizing providers (round $x)" 73 anastasis-reducer sync_providers < "$infile" > "$outfile" 2> /dev/null || true 74 CODE=$(jq -r -e ".code // 0" < "$outfile") 75 # ANASTASIS_REDUCER_PROVIDERS_ALREADY_SYNCED 76 # FIXME: Temporary workaround for C reducer. See #7227. 77 if [ "$CODE" = "8420" ] 78 then 79 # restore previous non-error state 80 cat "$infile" > "$outfile" 81 break 82 fi 83 # ANASTASIS_REDUCER_ACTION_INVALID 84 if [ "$CODE" = "8400" ] 85 then 86 # restore previous non-error state 87 cat "$infile" > "$outfile" 88 break 89 fi 90 if [ "$CODE" != "0" ] 91 then 92 exit_fail "Expected no error or 8420/8400, got $CODE" 93 fi 94 cat "$outfile" > "$infile" 95 done 96 echo "Providers synced." 97 } 98 99 100 CONF_1="test_anastasis_reducer_1.conf" 101 CONF_2="test_anastasis_reducer_2.conf" 102 CONF_3="test_anastasis_reducer_3.conf" 103 CONF_4="test_anastasis_reducer_4.conf" 104 105 106 # Configuration file will be edited, so we create one 107 # from the template. 108 CONF="$(mktemp -p "${TMPDIR:-/tmp}" test_reducerXXXXXX.conf)" 109 cp test_reducer.conf "$CONF" 110 111 TMP_DIR=$(mktemp -p "${TMPDIR:-/tmp}" -d keys-tmp-XXXXXX) 112 WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_walletXXXXXX.json) 113 B1FILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_stateB1XXXXXX) 114 B2FILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_stateB2XXXXXX) 115 R1FILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_stateR1XXXXXX) 116 R2FILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_stateR2XXXXXX) 117 118 # Install cleanup handler (except for kill -9) 119 trap cleanup EXIT 120 121 echo -n "Initialize anastasis database ..." 122 # Name of the Postgres database we will use for the script. 123 # Will be dropped, do NOT use anything that might be used 124 # elsewhere 125 TARGET_DB_1=$(anastasis-config -c $CONF_1 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///") 126 TARGET_DB_2=$(anastasis-config -c $CONF_2 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///") 127 TARGET_DB_3=$(anastasis-config -c $CONF_3 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///") 128 TARGET_DB_4=$(anastasis-config -c $CONF_4 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///") 129 130 dropdb "$TARGET_DB_1" >/dev/null 2>/dev/null || true 131 createdb "$TARGET_DB_1" || exit_skip "Could not create database $TARGET_DB_1" 132 anastasis-dbinit -c "$CONF_1" 2> anastasis-dbinit_1.log 133 dropdb "$TARGET_DB_2" >/dev/null 2>/dev/null || true 134 createdb "$TARGET_DB_2" || exit_skip "Could not create database $TARGET_DB_2" 135 anastasis-dbinit -c "$CONF_2" 2> anastasis-dbinit_2.log 136 dropdb "$TARGET_DB_3" >/dev/null 2>/dev/null || true 137 createdb "$TARGET_DB_3" || exit_skip "Could not create database $TARGET_DB_3" 138 anastasis-dbinit -c "$CONF_3" 2> anastasis-dbinit_3.log 139 dropdb "$TARGET_DB_4" >/dev/null 2>/dev/null || true 140 createdb "$TARGET_DB_4" || exit_skip "Could not create database $TARGET_DB_4" 141 anastasis-dbinit -c "$CONF_4" 2> anastasis-dbinit_4.log 142 143 echo " OK" 144 145 echo -n "Launching anastasis services ..." 146 PREFIX="" #valgrind 147 $PREFIX anastasis-httpd -c "$CONF_1" 2> anastasis-httpd_1.log & 148 $PREFIX anastasis-httpd -c "$CONF_2" 2> anastasis-httpd_2.log & 149 $PREFIX anastasis-httpd -c "$CONF_3" 2> anastasis-httpd_3.log & 150 $PREFIX anastasis-httpd -c "$CONF_4" 2> anastasis-httpd_4.log & 151 152 echo "OK" 153 154 echo -n "Waiting for anastasis services ..." 155 156 # Wait for anastasis services to be available 157 for n in $(seq 1 50) 158 do 159 echo -n "." 160 sleep 0.1 161 OK=0 162 # anastasis_01 163 wget --tries=1 --timeout=1 http://localhost:8086/ -o /dev/null -O /dev/null >/dev/null || continue 164 # anastasis_02 165 wget --tries=1 --timeout=1 http://localhost:8087/ -o /dev/null -O /dev/null >/dev/null || continue 166 # anastasis_03 167 wget --tries=1 --timeout=1 http://localhost:8088/ -o /dev/null -O /dev/null >/dev/null || continue 168 # anastasis_04 169 wget --tries=1 --timeout=1 http://localhost:8089/ -o /dev/null -O /dev/null >/dev/null || continue 170 OK=1 171 break 172 done 173 174 if [ 1 != "$OK" ] 175 then 176 exit_skip "Failed to launch anastasis services" 177 fi 178 echo "OK" 179 180 echo -n "Configuring merchant instance ..." 181 # Setup merchant 182 183 curl -H "Content-Type: application/json" -X POST -d '{"auth":{"method":"external"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' http://localhost:9966/management/instances 184 185 curl -H "Content-Type: application/json" -X POST -d '{"payto_uri":"'"$MERCHANT_PAYTO"'"}' http://localhost:9966/private/accounts 186 187 echo " DONE" 188 189 echo -n "Running backup logic ...," 190 anastasis-reducer -b > "$B1FILE" 191 echo -n "." 192 anastasis-reducer -a \ 193 '{"continent": "Demoworld"}' \ 194 select_continent < "$B1FILE" > "$B2FILE" 195 echo -n "." 196 anastasis-reducer -a \ 197 '{"country_code": "xx"}' \ 198 select_country < "$B2FILE" > "$B1FILE" 199 echo -n "." 200 anastasis-reducer -a \ 201 '{"identity_attributes": { 202 "full_name": "Max Musterman", 203 "sq_number": "4", 204 "birthdate": "2000-01-01"}}' \ 205 enter_user_attributes < "$B1FILE" > "$B2FILE" 206 cat "$B2FILE" > "$B1FILE" 207 echo -n "," 208 sync_providers "$B1FILE" "$B2FILE" 209 echo -n "," 210 # "91GPWWR" encodes "Hans" 211 anastasis-reducer -a \ 212 '{"authentication_method": { 213 "type": "question", 214 "instructions": "What is your name?", 215 "challenge": "91GPWWR" 216 } }' \ 217 add_authentication < "$B2FILE" > "$B1FILE" 218 echo -n "." 219 # "64S36" encodes "123" 220 anastasis-reducer -a \ 221 '{"authentication_method": { 222 "type": "question", 223 "instructions": "How old are you?", 224 "challenge": "64S36" 225 } }' \ 226 add_authentication < "$B1FILE" > "$B2FILE" 227 echo -n "." 228 # "9NGQ4WR" encodes "Mars" 229 anastasis-reducer -a \ 230 '{"authentication_method": { 231 "type": "question", 232 "instructions": "Where do you live?", 233 "challenge": "9NGQ4WR" 234 } }' \ 235 add_authentication < "$B2FILE" > "$B1FILE" 236 echo -n "." 237 # Finished adding authentication methods 238 anastasis-reducer \ 239 next < "$B1FILE" > "$B2FILE" 240 241 242 echo -n "," 243 # Finished policy review 244 anastasis-reducer \ 245 next < "$B2FILE" > "$B1FILE" 246 echo -n "." 247 248 # Note: 'secret' must here be a Crockford base32-encoded value 249 anastasis-reducer -a \ 250 '{"secret": { "value" : "VERYHARDT0GVESSSECRET", "mime" : "text/plain" }}' \ 251 enter_secret < "$B1FILE" > "$B2FILE" 252 mv "$B2FILE" "$B1FILE" 253 anastasis-reducer next "$B1FILE" "$B2FILE" 254 echo " OK" 255 256 257 echo -n "Preparing wallet" 258 259 EXCHANGE_URL="$(taler-exchange-config -c "$CONF" -s exchange -o BASE_URL)" 260 261 rm -f "$WALLET_DB" 262 taler-wallet-cli --no-throttle --wallet-db="$WALLET_DB" api --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.err > wallet-withdraw.out 272 taler-wallet-cli \ 273 --wallet-db="$WALLET_DB" \ 274 run-until-done \ 275 2>wallet-withdraw-finish.err \ 276 >wallet-withdraw-finish.out 277 echo " OK" 278 279 echo -en "Making payments for truth uploads ... " 280 OBJECT_SIZE=$(jq -r -e '.payments | length' < "$B2FILE") 281 for ((INDEX=0; INDEX < "$OBJECT_SIZE"; INDEX++)) 282 do 283 PAY_URI=$(jq --argjson INDEX $INDEX -r -e '.payments[$INDEX]' < "$B2FILE") 284 # run wallet CLI 285 echo -n "$INDEX" 286 taler-wallet-cli \ 287 --wallet-db="$WALLET_DB" \ 288 handle-uri "$PAY_URI" \ 289 -y \ 290 2>"wallet-pay-truth-$INDEX.err" \ 291 >"wallet-pay-truth-$INDEX.out" 292 echo -n ", " 293 done 294 echo "OK" 295 echo -e "Running wallet run-until-done..." 296 taler-wallet-cli \ 297 --wallet-db="$WALLET_DB" \ 298 run-until-done \ 299 2>"wallet-pay-truth-finish-$INDEX.err" \ 300 >"wallet-pay-truth-finish-$INDEX.out" 301 echo -e "Payments done" 302 303 echo -en "Try to upload again ..." 304 $PREFIX anastasis-reducer pay "$B2FILE" "$B1FILE" 305 mv "$B1FILE" "$B2FILE" 306 echo " OK" 307 308 echo -en "Making payments for policy uploads ... " 309 OBJECT_SIZE=$(jq -r -e '.policy_payment_requests | length' < "$B2FILE") 310 for ((INDEX=0; INDEX < "$OBJECT_SIZE"; INDEX++)) 311 do 312 PAY_URI=$(jq --argjson INDEX $INDEX -r -e '.policy_payment_requests[$INDEX].payto' < "$B2FILE") 313 # run wallet CLI 314 echo -n "$INDEX" 315 taler-wallet-cli \ 316 --wallet-db="$WALLET_DB" \ 317 handle-uri "$PAY_URI" \ 318 -y \ 319 2>"wallet-pay-policy-$INDEX.err" \ 320 >"wallet-pay-policy-$INDEX.out" 321 echo -n ", " 322 done 323 echo " OK" 324 echo -en "Running wallet run-until-done..." 325 taler-wallet-cli \ 326 --wallet-db="$WALLET_DB" \ 327 run-until-done \ 328 2>wallet-pay-policy-finish.err \ 329 >wallet-pay-policy-finish.out 330 echo -e " payments DONE" 331 332 echo -en "Try to upload again ..." 333 anastasis-reducer \ 334 pay < "$B2FILE" > "$B1FILE" 335 echo " OK: Backup finished" 336 echo -n "Final backup checks ..." 337 STATE=$(jq -r -e .backup_state < "$B1FILE") 338 if [ "$STATE" != "BACKUP_FINISHED" ] 339 then 340 exit_fail "Expected new state to be 'BACKUP_FINISHED', got '$STATE'" 341 fi 342 343 jq -r -e .core_secret < "$B1FILE" > /dev/null && exit_fail "'core_secret' was not cleared upon success" 344 345 echo " OK" 346 347 echo -n "Running recovery basic logic ..." 348 anastasis-reducer -r > "$R1FILE" 349 anastasis-reducer -a \ 350 '{"continent": "Demoworld"}' \ 351 select_continent < "$R1FILE" > "$R2FILE" 352 anastasis-reducer -a \ 353 '{"country_code": "xx"}' \ 354 select_country < "$R2FILE" > "$R1FILE" 355 anastasis-reducer -a '{"identity_attributes": { "full_name": "Max Musterman", "sq_number": "4", "birthdate": "2000-01-01" }}' enter_user_attributes < "$R1FILE" > "$R2FILE" 356 357 358 STATE=$(jq -r -e .recovery_state < "$R2FILE") 359 if [ "$STATE" != "SECRET_SELECTING" ] 360 then 361 exit_fail "Expected new state to be 'SECRET_SELECTING', got '$STATE'" 362 fi 363 echo " OK" 364 365 echo -n "Adding provider (to ensure it is loaded)" 366 anastasis-reducer -a '{"provider_url" : "http://localhost:8086/" }' add_provider < "$R2FILE" > "$R1FILE" 367 echo " OK" 368 369 echo -n "Selecting secret to recover" 370 anastasis-reducer -a '{"attribute_mask": 0, "providers" : [ { "version": 1, "url" : "http://localhost:8086/" } ] }' select_version < "$R1FILE" > "$R2FILE" 371 372 STATE=$(jq -r -e .recovery_state < "$R2FILE") 373 if [ "$STATE" != "CHALLENGE_SELECTING" ] 374 then 375 exit_fail "Expected new state to be 'CHALLENGE_SELECTING', got '$STATE'" 376 fi 377 echo " OK" 378 379 cat "$R2FILE" > "$R1FILE" 380 381 sync_providers "$R1FILE" "$R2FILE" 382 383 echo -n "Running challenge logic ..." 384 385 UUID0=$(jq -r -e .recovery_information.challenges[0].uuid < "$R2FILE") 386 UUID1=$(jq -r -e .recovery_information.challenges[1].uuid < "$R2FILE") 387 UUID2=$(jq -r -e .recovery_information.challenges[2].uuid < "$R2FILE") 388 #UUID0Q=$(jq -r -e .recovery_information.challenges[0].instructions < "$R2FILE") 389 UUID1Q=$(jq -r -e .recovery_information.challenges[1].instructions < "$R2FILE") 390 UUID2Q=$(jq -r -e .recovery_information.challenges[2].instructions < "$R2FILE") 391 392 if [ "$UUID2Q" = 'How old are you?' ] 393 then 394 AGE_UUID=$UUID2 395 elif [ "$UUID1Q" = 'How old are you?' ] 396 then 397 AGE_UUID=$UUID1 398 else 399 AGE_UUID=$UUID0 400 fi 401 402 if [ "$UUID2Q" = 'What is your name?' ] 403 then 404 NAME_UUID=$UUID2 405 elif [ "$UUID1Q" = 'What is your name?' ] 406 then 407 NAME_UUID=$UUID1 408 else 409 NAME_UUID=$UUID0 410 fi 411 412 anastasis-reducer -a \ 413 "$(jq -n ' 414 { 415 uuid: $UUID 416 }' \ 417 --arg UUID "$NAME_UUID" 418 )" \ 419 select_challenge < "$R2FILE" > "$R1FILE" 420 421 anastasis-reducer -a '{"answer": "Hans"}' \ 422 solve_challenge < "$R1FILE" > "$R2FILE" 423 424 anastasis-reducer -a \ 425 "$(jq -n ' 426 { 427 uuid: $UUID 428 }' \ 429 --arg UUID "$AGE_UUID" 430 )" \ 431 select_challenge < "$R2FILE" > "$R1FILE" 432 433 anastasis-reducer -a '{"answer": "123"}' \ 434 solve_challenge < "$R1FILE" > "$R2FILE" 435 436 echo " OK" 437 438 echo -n "Checking recovered secret ..." 439 # finally: check here that we recovered the secret... 440 441 STATE=$(jq -r -e .recovery_state < "$R2FILE") 442 if [ "$STATE" != "RECOVERY_FINISHED" ] 443 then 444 jq -e . "$R2FILE" 445 exit_fail "Expected new state to be 'RECOVERY_FINISHED', got '$STATE'" 446 fi 447 448 SECRET=$(jq -r -e .core_secret.value < "$R2FILE") 449 if [ "$SECRET" != "VERYHARDT0GVESSSECRET" ] 450 then 451 jq -e . "$R2FILE" 452 exit_fail "Expected recovered secret to be 'VERYHARDT0GVESSSECRET', got '$SECRET'" 453 fi 454 455 MIME=$(jq -r -e .core_secret.mime < "$R2FILE") 456 if [ "$MIME" != "text/plain" ] 457 then 458 jq -e . "$R2FILE" 459 exit_fail "Expected recovered mime to be 'text/plain', got '$MIME'" 460 fi 461 462 echo " OK" 463 464 exit 0