commit 9eb5f4c710ed4777a1789cbc710a188e0996152d parent 6b9536244a2afa8d634ba9259889f4db9ad6bb2e Author: Christian Grothoff <christian@grothoff.org> Date: Sat, 10 Oct 2026 21:47:36 +0200 make tests post-v19 compatible (use /token, not disabled auth) Diffstat:
37 files changed, 907 insertions(+), 157 deletions(-)
diff --git a/meson.build b/meson.build @@ -335,11 +335,11 @@ if not get_option('only-doc') libltversions = [ - ['libtalermerchant', '13:0:2'], + ['libtalermerchant', '13:1:2'], ['libtalermerchantutil', '2:0:2'], ['libtalermerchantbank', '0:1:0'], ['libtalermerchantdb', '10:0:0'], - ['libtalermerchanttesting', '6:0:3'], + ['libtalermerchanttesting', '7:0:4'], ] solibversions = {} diff --git a/src/backend/taler-merchant-httpd_auth.c b/src/backend/taler-merchant-httpd_auth.c @@ -426,7 +426,7 @@ process_bearer_auth (struct TMH_HandlerContext *hc, GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Refusing deprecated secret-token:password API authN\n"); hc->auth_scope = TMH_AS_NONE; - return ec; + return TALER_EC_MERCHANT_GENERIC_UNAUTHORIZED; } } GNUNET_log (GNUNET_ERROR_TYPE_WARNING, diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c @@ -112,6 +112,7 @@ #include "merchant-database/get_exchange_wire_fee.h" #include "merchant-database/get_instance_auth.h" #include "merchant-database/update_instance_password_reset.h" +#include "merchant-database/update_instance_auth.h" #include "merchant-database/update_to_contract_terms_paid.h" #include "merchant-database/update_to_contract_terms_wired.h" #include "merchant-database/insert_refund_by_coin.h" @@ -970,7 +971,8 @@ test_get_instance_auth_null (const struct InstanceData *instance) /** * Tests that a password reset of an instance can only be started - * again once the earliest time for the next one has passed. + * again once the earliest time for the next one has passed, or + * after the password was changed. * * @param instance the instance to run the test against. * @return 0 on success, 1 otherwise. @@ -1005,6 +1007,29 @@ test_update_instance_password_reset (const struct InstanceData *instance) GNUNET_TIME_absolute_add (next, GNUNET_TIME_UNIT_MINUTES)), "Password reset after the delay was refused\n"); + { + struct TALER_MERCHANTDB_InstanceAuthSettings ias; + + TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == + TALER_MERCHANTDB_get_instance_auth ( + pg, + instance->instance.id, + &ias), + "Lookup of instance authentication failed\n"); + TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == + TALER_MERCHANTDB_update_instance_auth ( + pg, + instance->instance.id, + &ias), + "Password change failed\n"); + } + TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == + TALER_MERCHANTDB_update_instance_password_reset ( + pg, + instance->instance.id, + now, + next), + "Password reset after a password change was refused\n"); TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == TALER_MERCHANTDB_update_instance_password_reset ( pg, diff --git a/src/backenddb/update_instance_auth.c b/src/backenddb/update_instance_auth.c @@ -42,6 +42,7 @@ TALER_MERCHANTDB_update_instance_auth ( "UPDATE merchant.merchant_instances SET" " auth_hash=$2" ",auth_salt=$3" + ",earliest_password_reset=0" " WHERE merchant_id=$1"); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "update_instance_auth", diff --git a/src/include/merchant-database/update_instance_auth.h b/src/include/merchant-database/update_instance_auth.h @@ -29,7 +29,9 @@ struct TALER_MERCHANTDB_PostgresContext; /** * Update information about an instance's authentication settings - * into our database. + * into our database. A successful password change also lifts the + * limit on starting password resets of the instance, so only resets + * that are not completed delay the next one. * * @param pg database context * @param merchant_id identity of the instance diff --git a/src/include/taler/taler_merchant_testing_lib.h b/src/include/taler/taler_merchant_testing_lib.h @@ -104,6 +104,27 @@ TALER_TESTING_cmd_merchant_post_instances (const char *label, /** + * Define a "POST /instances" CMD, simple version, for an instance with + * password authentication. + * + * @param label command label. + * @param merchant_url base URL of the merchant serving the + * POST /instances request. + * @param instance_id the ID of the instance to create + * @param password password of the new instance + * @param http_status expected HTTP response code. + * @return the command. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_post_instances_with_password ( + const char *label, + const char *merchant_url, + const char *instance_id, + const char *password, + unsigned int http_status); + + +/** * Define a "POST /private/auth" CMD. * * @param label command label. @@ -177,6 +198,26 @@ struct TALER_TESTING_Command TALER_TESTING_cmd_merchant_set_instance_token (const char *label, const char *cmd_job_label); + +/** + * Log in to a merchant instance: get a login token with scope "all" + * from POST /private/token using the instance password (Basic + * authorization), and send it with all further requests of the + * interpreter, replacing any previous Authorization header. The + * instance must not require MFA for the login. + * + * @param label command label. + * @param merchant_url base URL of the merchant backend. + * @param instance_id the ID of the instance. + * @param password password of the instance. + * @return the command. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_login (const char *label, + const char *merchant_url, + const char *instance_id, + const char *password); + /** * Define a "DELETE /private/token" CMD. * diff --git a/src/lib/merchant_api_get-management-instances-INSTANCE.c b/src/lib/merchant_api_get-management-instances-INSTANCE.c @@ -325,7 +325,7 @@ TALER_MERCHANT_get_management_instance_start ( char *path; GNUNET_asprintf (&path, - "instances/%s/private", + "management/instances/%s", gmi->instance_id); gmi->url = TALER_url_join (gmi->base_url, path, diff --git a/src/testing/meson.build b/src/testing/meson.build @@ -2,6 +2,7 @@ check_SCRIPTS = [ + 'test_merchant_auth_legacy', 'test_merchant_fountains', 'test_merchant_instance_auth', 'test_merchant_instance_creation', @@ -377,6 +378,7 @@ EXTRA_DIST = [ 'test_merchant_api_proxy_merchant.conf', 'test_merchant_api_proxy_exchange.conf', 'test_merchant_mfa.conf', + 'test_merchant_auth_legacy.conf', 'test_email_helper.sh', 'test_sms_helper.sh', 'test_merchant.priv', diff --git a/src/testing/setup.sh b/src/testing/setup.sh @@ -91,6 +91,176 @@ function get_payto_uri() { libeufin-bank create-account -u "$1" -p "$2" --name "$1" 2> /dev/null } +# Print the base URL of merchant instance $1 of the backend under test. +function merchant_instance_url() +{ + if [ "$1" = "admin" ] + then + echo "http://localhost:9966/" + else + echo "http://localhost:9966/instances/$1/" + fi +} + +# Log in to merchant instance $1 with password $2 (Basic authentication +# at POST /private/token) and print the access token. $3 is the scope +# of the token, "all" by default. Instances that require MFA for the +# login need merchant_login_mfa() instead. +function merchant_login() +{ + local RESPONSE + local STATUS + + RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" merchant-login-XXXXXX) + STATUS=$(curl -s -X POST \ + -H "Content-Type: application/json" \ + -H "Authorization: Basic $(printf '%s:%s' "$1" "$2" | base64 -w0)" \ + "$(merchant_instance_url "$1")private/token" \ + -d '{"scope":"'"${3:-all}"'","duration":{"d_us":86400000000}}' \ + -w "%{http_code}" \ + -o "$RESPONSE") + if [ "$STATUS" != "200" ] + then + jq < "$RESPONSE" >&2 || true + rm -f "$RESPONSE" + exit_fail "Expected 200 OK for the login to instance $1. Got: $STATUS" + fi + jq -er .access_token < "$RESPONSE" + rm -f "$RESPONSE" +} + +# Directory where test_email_helper.sh and test_sms_helper.sh store the +# last TAN and the address it was sent to. Tests set +# TALER_MERCHANT_TEST_TAN_DIR before setup() so that the merchant passes +# it on to the helpers. +function tan_dir() +{ + echo "${TALER_MERCHANT_TEST_TAN_DIR:-/tmp}" +} + +# Have the merchant transmit challenge $1 and solve it with the TAN the +# helper received. $2 is the channel ("email" or "sms"), $3 the address +# the TAN must have been sent to. +function solve_challenge() +{ + local RESPONSE + local STATUS + local TAN + local ADDRESS + + RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" merchant-challenge-XXXXXX) + rm -f "$(tan_dir)/test-merchant-$2-tan.txt" \ + "$(tan_dir)/test-merchant-$2-address.txt" + STATUS=$(curl -s -X POST \ + -H "Content-Type: application/json" \ + "http://localhost:9966/challenge/$1" \ + -d '{}' \ + -w "%{http_code}" \ + -o "$RESPONSE") + if [ "$STATUS" != "200" ] + then + jq < "$RESPONSE" >&2 || true + exit_fail "Expected challenge transmission to return 200 OK. Got: $STATUS" + fi + TAN=$(head -n1 "$(tan_dir)/test-merchant-$2-tan.txt" | awk '{print $1}') + ADDRESS=$(cat "$(tan_dir)/test-merchant-$2-address.txt") + if [ "$ADDRESS" != "$3" ] + then + exit_fail "Expected $2 address '$3'. Got: $ADDRESS" + fi + STATUS=$(curl -s -X POST \ + -H "Content-Type: application/json" \ + "http://localhost:9966/challenge/$1/confirm" \ + -d '{"tan":"'"$TAN"'"}' \ + -w "%{http_code}" \ + -o "$RESPONSE") + if [ "$STATUS" != "204" ] + then + jq < "$RESPONSE" >&2 || true + exit_fail "Expected challenge confirmation to return 204 No Content. Got: $STATUS" + fi + rm -f "$RESPONSE" +} + +# Solve the challenges listed in the 202 response in file $1: all of them +# if the response says "combi_and", otherwise only the first. $2 and $3 +# are the e-mail address and the phone number the TANs must go to. +# Prints the comma-separated IDs of the solved challenges. +function solve_response_challenges() +{ + local IDS="" + local CHALLENGE_ID + local CHANNEL + local ADDRESS + local FILTER='.challenges[]' + + if [ "$(jq -r .combi_and < "$1")" != "true" ] + then + FILTER='.challenges[0]' + fi + while IFS=$'\t' read -r CHALLENGE_ID CHANNEL + do + case "$CHANNEL" in + email) + ADDRESS="$2" + ;; + sms) + ADDRESS="$3" + ;; + *) + exit_fail "Unexpected TAN channel: $CHANNEL" + ;; + esac + solve_challenge "$CHALLENGE_ID" "$CHANNEL" "$ADDRESS" + IDS="${IDS:+$IDS,}$CHALLENGE_ID" + done < <(jq -r "$FILTER"' | [.challenge_id, .tan_channel] | @tsv' "$1") + echo "$IDS" +} + +# Log in to MFA-protected merchant instance $1 with password $2, solving +# the challenges the login asks for, and print the access token. $3 and +# $4 are the e-mail address and the phone number of the instance. +function merchant_login_mfa() +{ + local RESPONSE + local STATUS + local BASIC + local BODY='{"scope":"all","duration":{"d_us":86400000000}}' + local IDS + + RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" merchant-login-XXXXXX) + BASIC="Authorization: Basic $(printf '%s:%s' "$1" "$2" | base64 -w0)" + STATUS=$(curl -s -X POST \ + -H "Content-Type: application/json" \ + -H "$BASIC" \ + "$(merchant_instance_url "$1")private/token" \ + -d "$BODY" \ + -w "%{http_code}" \ + -o "$RESPONSE") + if [ "$STATUS" != "202" ] + then + jq < "$RESPONSE" >&2 || true + exit_fail "Expected 202 Accepted for the login to instance $1. Got: $STATUS" + fi + IDS=$(solve_response_challenges "$RESPONSE" "$3" "$4") + STATUS=$(curl -s -X POST \ + -H "Content-Type: application/json" \ + -H "$BASIC" \ + -H "Taler-Challenge-Ids: $IDS" \ + "$(merchant_instance_url "$1")private/token" \ + -d "$BODY" \ + -w "%{http_code}" \ + -o "$RESPONSE") + if [ "$STATUS" != "200" ] + then + jq < "$RESPONSE" >&2 || true + rm -f "$RESPONSE" + exit_fail "Expected 200 OK for the login to instance $1 with solved challenges. Got: $STATUS" + fi + jq -er .access_token < "$RESPONSE" + rm -f "$RESPONSE" +} + echo -n "Checking for curl ..." curl --version 2> /dev/null > /dev/null || exit_skip " no curl" echo " OK" diff --git a/src/testing/test_email_helper.sh b/src/testing/test_email_helper.sh @@ -1,5 +1,5 @@ #!/bin/sh # This file is in the public domain. -echo "$1" > /tmp/test-merchant-email-address.txt -cat - > /tmp/test-merchant-email-tan.txt +echo "$1" > "${TALER_MERCHANT_TEST_TAN_DIR:-/tmp}"/test-merchant-email-address.txt +cat - > "${TALER_MERCHANT_TEST_TAN_DIR:-/tmp}"/test-merchant-email-tan.txt exit 0 diff --git a/src/testing/test_kyc_api.c b/src/testing/test_kyc_api.c @@ -44,6 +44,11 @@ #define CONFIG_FILE "test_kyc_api.conf" /** + * Password of the merchant instances the test creates. + */ +#define INSTANCE_PASSWORD "instance-password" + +/** * Exchange base URL. Could also be taken from config. */ #define EXCHANGE_URL "http://localhost:8081/" @@ -534,11 +539,17 @@ run (void *cls, "start-oauth-service", "2005-00-00", 6666), - TALER_TESTING_cmd_merchant_post_instances ( + TALER_TESTING_cmd_merchant_post_instances_with_password ( "instance-create-default-setup", merchant_url, "admin", + INSTANCE_PASSWORD, MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_login ( + "login-admin", + merchant_url, + "admin", + INSTANCE_PASSWORD), TALER_TESTING_cmd_merchant_post_account ( "instance-create-default-account", merchant_url, diff --git a/src/testing/test_kyc_api.conf b/src/testing/test_kyc_api.conf @@ -22,6 +22,7 @@ HTTP_PORT = 8082 [merchant] PORT = 8080 SERVE = tcp +STRICT_PROTOCOL_V19 = YES DB = postgres BASE_URL = http://localhost:8080/ diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c @@ -68,6 +68,11 @@ static char *config_file; #define EXCHANGE_URL "http://localhost:8081/" /** + * Password of the merchant instances the test creates, except for i1a. + */ +#define INSTANCE_PASSWORD "instance-password" + +/** * Payto URI of the customer (payer). */ static struct TALER_FullPayto payer_payto; @@ -348,11 +353,17 @@ run (void *cls, struct TALER_TESTING_Interpreter *is) { struct TALER_TESTING_Command get_private_order_id[] = { - TALER_TESTING_cmd_merchant_post_instances ( + TALER_TESTING_cmd_merchant_post_instances_with_password ( "instance-create-admin", merchant_url, "admin", + INSTANCE_PASSWORD, MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_login ( + "login-admin", + merchant_url, + "admin", + INSTANCE_PASSWORD), TALER_TESTING_cmd_merchant_kyc_get ( "instance-create-kyc-no-accounts", merchant_url, @@ -1555,10 +1566,16 @@ run (void *cls, }; struct TALER_TESTING_Command auth[] = { - TALER_TESTING_cmd_merchant_post_instances ("instance-create-i1a", - merchant_url, - "i1a", - MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_post_instances_with_password ( + "instance-create-i1a", + merchant_url, + "i1a", + "my-first-secret", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_login ("login-i1a", + merchant_url, + "i1a", + "my-first-secret"), TALER_TESTING_cmd_merchant_post_account ( "instance-create-i1a-account", merchant_url_i1a, @@ -1583,6 +1600,12 @@ run (void *cls, merchant_url_i1a, MHD_HTTP_OK, NULL), + /* the management API needs the admin token, which i1a does not + accept */ + TALER_TESTING_cmd_merchant_login ("login-admin-for-i1a-auth", + merchant_url, + "admin", + INSTANCE_PASSWORD), TALER_TESTING_cmd_merchant_post_instance_auth ( "instance-create-i1a-auth-ok", merchant_url, @@ -1662,19 +1685,22 @@ run (void *cls, RFC_8959_PREFIX "my-other-secret", "my-secret", MHD_HTTP_NO_CONTENT), + /* strict mode refuses the "external" authentication method */ TALER_TESTING_cmd_merchant_post_instance_auth2 ( "instance-create-i1a-clear-auth", merchant_url_i1a, NULL, NULL, "my-other-secret", - MHD_HTTP_NO_CONTENT), - TALER_TESTING_cmd_set_authorization ("set-auth-none", - NULL), + MHD_HTTP_BAD_REQUEST), TALER_TESTING_cmd_merchant_purge_instance ("instance-delete-i1a", merchant_url_i1a, NULL, MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_login ("login-admin-after-auth", + merchant_url, + "admin", + INSTANCE_PASSWORD), TALER_TESTING_cmd_end () }; @@ -4270,21 +4296,28 @@ run (void *cls, merchant_url, MHD_HTTP_OK, NULL), - TALER_TESTING_cmd_merchant_post_instances ( + TALER_TESTING_cmd_merchant_post_instances_with_password ( "instance-create-default-setup", merchant_url, "admin", + INSTANCE_PASSWORD, MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_login ( + "login-admin-default-setup", + merchant_url, + "admin", + INSTANCE_PASSWORD), TALER_TESTING_cmd_merchant_post_account ( "instance-create-default-account", merchant_url, merchant_payto, NULL, NULL, MHD_HTTP_OK), - TALER_TESTING_cmd_merchant_post_instances ( + TALER_TESTING_cmd_merchant_post_instances_with_password ( "instance-create-i1", merchant_url, "i1", + INSTANCE_PASSWORD, MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_get_instances ( "instances-get-i1", @@ -4339,10 +4372,7 @@ run (void *cls, true, GNUNET_TIME_UNIT_ZERO, /* wire transfer */ GNUNET_TIME_UNIT_SECONDS, /* pay delay */ - // FIXME: change this back once - // we have a update auth test CMD - // RFC_8959_PREFIX "EXAMPLE", - NULL, + INSTANCE_PASSWORD, MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_patch_instance ( "instance-patch-ACL", @@ -4360,15 +4390,17 @@ run (void *cls, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2), /* small pay delay */ MHD_HTTP_NO_CONTENT), - TALER_TESTING_cmd_merchant_post_instances ( + TALER_TESTING_cmd_merchant_post_instances_with_password ( "instance-create-i2", merchant_url, "i2", + INSTANCE_PASSWORD, MHD_HTTP_NO_CONTENT), - TALER_TESTING_cmd_merchant_post_instances ( + TALER_TESTING_cmd_merchant_post_instances_with_password ( "instance-create-i2-idem", merchant_url, "i2", + INSTANCE_PASSWORD, MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_delete_instance ( "instance-delete-i2", @@ -4406,11 +4438,17 @@ run (void *cls, merchant_url, "admin", MHD_HTTP_NO_CONTENT), - TALER_TESTING_cmd_merchant_post_instances ( + TALER_TESTING_cmd_merchant_post_instances_with_password ( "instance-create-default-after-purge", merchant_url, "admin", + INSTANCE_PASSWORD, MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_login ( + "login-admin-after-purge", + merchant_url, + "admin", + INSTANCE_PASSWORD), TALER_TESTING_cmd_merchant_post_account ( "instance-create-default-account-after-purge", merchant_url, diff --git a/src/testing/test_merchant_api.conf b/src/testing/test_merchant_api.conf @@ -45,7 +45,7 @@ CURRENCY = EUR PORT = 8080 SERVE = tcp DB = postgres -STRICT_PROTOCOL_V19 = NO +STRICT_PROTOCOL_V19 = YES BASE_URL = http://localhost:8080/ [merchantdb-postgres] diff --git a/src/testing/test_merchant_api_twisted.c b/src/testing/test_merchant_api_twisted.c @@ -52,6 +52,11 @@ static char *config_file; #define EXCHANGE_ACCOUNT_NAME "2" /** + * Password of the merchant instances the test creates. + */ +#define INSTANCE_PASSWORD "instance-password" + +/** * Account number of the merchant at the bank. */ #define MERCHANT_ACCOUNT_NAME "3" @@ -331,10 +336,16 @@ run (void *cls, NULL, true, true), - TALER_TESTING_cmd_merchant_post_instances ("instance-create-admin", - twister_merchant_url, - "admin", - MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_post_instances_with_password ( + "instance-create-admin", + twister_merchant_url, + "admin", + INSTANCE_PASSWORD, + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_login ("login-admin", + twister_merchant_url, + "admin", + INSTANCE_PASSWORD), TALER_TESTING_cmd_merchant_post_account ( "instance-create-default-account", twister_merchant_url, diff --git a/src/testing/test_merchant_auth_legacy.conf b/src/testing/test_merchant_auth_legacy.conf @@ -0,0 +1,6 @@ +# This file is in the public domain. +@INLINE@ test_merchant_mfa.conf + +[merchant] +# Remove together with the password fallback of the bearer authentication. +STRICT_PROTOCOL_V19 = NO diff --git a/src/testing/test_merchant_auth_legacy.sh b/src/testing/test_merchant_auth_legacy.sh @@ -0,0 +1,125 @@ +#!/usr/bin/env bash +# This file is part of TALER +# Copyright (C) 2026 Taler Systems SA +# +# TALER is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3, or +# (at your option) any later version. +# +# TALER is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with TALER; see the file COPYING. If not, see +# <http://www.gnu.org/licenses/> +# +# Tests the deprecated "Bearer secret-token:$PASSWORD" authentication +# without STRICT_PROTOCOL_V19. Remove together with that fallback. +# +set -eu + +. setup.sh + +# The TAN helpers started by the merchant write into this directory. +TALER_MERCHANT_TEST_TAN_DIR=$(mktemp -d -p "${TMPDIR:-/tmp}" test_merchant_auth_legacy-tan-XXXXXX) +export TALER_MERCHANT_TEST_TAN_DIR + +# Launch system. +setup \ + -c "test_merchant_auth_legacy.conf" \ + -m +LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX) + + +echo -n "Configuring a merchant admin instance ..." +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + http://localhost:9966/management/instances \ + -d '{"auth":{"method":"token","password":"super_secret"},"id":"admin","name":"default","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ + -w "%{http_code}" -s \ + -o "$LAST_RESPONSE") +if [ "$STATUS" != "204" ] +then + jq < "$LAST_RESPONSE" + exit_fail "Expected 204 No Content. Got: $STATUS" +fi +echo " OK" + + +echo -n "Accept the password as bearer token without MFA ..." +STATUS=$(curl \ + -H 'Authorization: Bearer secret-token:super_secret' \ + http://localhost:9966/private/products \ + -w "%{http_code}" -s \ + -o "$LAST_RESPONSE") +if [ "$STATUS" != "200" ] +then + jq < "$LAST_RESPONSE" + exit_fail "Expected 200 OK. Got: $STATUS" +fi +echo " OK" + + +echo -n "Self-provision an instance with MFA ..." +INSTANCE_BODY='{"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}}' +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + http://localhost:9966/instances \ + -d "$INSTANCE_BODY" \ + -w "%{http_code}" -s \ + -o "$LAST_RESPONSE") +if [ "$STATUS" != "202" ] +then + jq < "$LAST_RESPONSE" + exit_fail "Expected 202 Accepted. Got: $STATUS" +fi +CHALLENGE_IDS=$(solve_response_challenges "$LAST_RESPONSE" \ + self@example.com +4171234) +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H "Taler-Challenge-Ids: $CHALLENGE_IDS" \ + http://localhost:9966/instances \ + -d "$INSTANCE_BODY" \ + -w "%{http_code}" -s \ + -o "$LAST_RESPONSE") +if [ "$STATUS" != "204" ] +then + jq < "$LAST_RESPONSE" + exit_fail "Expected 204 No Content. Got: $STATUS" +fi +echo " OK" + + +echo -n "Refuse the password as bearer token with MFA ..." +STATUS=$(curl \ + -H 'Authorization: Bearer secret-token:pass1234' \ + http://localhost:9966/instances/self/private/products \ + -w "%{http_code}" -s \ + -o "$LAST_RESPONSE") +if [ "$STATUS" != "401" ] || + [ "$(jq -r .code < "$LAST_RESPONSE")" != "2015" ] +then + jq < "$LAST_RESPONSE" + exit_fail "Expected 401 with code 2015. Got: $STATUS" +fi +echo " OK" + + +echo -n "Accept a login token with MFA ..." +SELF_TOKEN=$(merchant_login_mfa self pass1234 self@example.com +4171234) +STATUS=$(curl \ + -H "Authorization: Bearer $SELF_TOKEN" \ + http://localhost:9966/instances/self/private/products \ + -w "%{http_code}" -s \ + -o "$LAST_RESPONSE") +if [ "$STATUS" != "200" ] +then + jq < "$LAST_RESPONSE" + exit_fail "Expected 200 OK. Got: $STATUS" +fi +echo " OK" + + +echo "TEST PASSED" + +exit 0 diff --git a/src/testing/test_merchant_instance_auth.sh b/src/testing/test_merchant_instance_auth.sh @@ -68,6 +68,22 @@ TOKEN=$(jq -e -r .access_token < $LAST_RESPONSE) echo " OK" >&2 +echo -n "Refusing the password as bearer token in strict mode ..." >&2 + +STATUS=$(curl -H "Content-Type: application/json" \ + -H 'Authorization: Bearer secret-token:new_pw' \ + http://localhost:9966/private/products \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "401" ] || + [ "$(jq -r .code < "$LAST_RESPONSE")" != "2015" ] +then + jq < "$LAST_RESPONSE" >&2 + exit_fail "Expected 401 with code 2015. Got: $STATUS" +fi + +echo " OK" >&2 + echo -n "Setting up bank account..." >&2 STATUS=$(curl -H "Content-Type: application/json" -X POST \ diff --git a/src/testing/test_merchant_instance_creation.sh b/src/testing/test_merchant_instance_creation.sh @@ -43,7 +43,7 @@ echo -n "Configuring admin instance ..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -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}}' \ + -d '{"auth":{"method":"token","password":"super_secret"},"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}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "401" ] diff --git a/src/testing/test_merchant_instance_purge.sh b/src/testing/test_merchant_instance_purge.sh @@ -26,21 +26,22 @@ LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX) echo -n "Configuring admin instance ..." >&2 STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -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}}' \ + -d '{"auth":{"method":"token","password":"super_secret"},"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}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then exit_fail "Expected 204, instance created. got: $STATUS" fi +ADMIN_TOKEN=$(merchant_login admin super_secret) echo " OK" >&2 echo -n "Configuring merchant instance ..." >&2 STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/management/instances \ -d '{"auth":{"method":"token","password":"secret-token:other_secret"},"id":"test","name":"test","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ -w "%{http_code}" -s -o /dev/null) @@ -53,6 +54,7 @@ echo " OK" >&2 echo -n "Deleting instance ..." >&2 STATUS=$(curl -H "Content-Type: application/json" -X DELETE \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ "http://localhost:9966/management/instances/test" \ -w "%{http_code}" -s -o /dev/null) @@ -65,6 +67,7 @@ echo " OK" >&2 echo -n "Purging instance ..." >&2 STATUS=$(curl -H "Content-Type: application/json" -X DELETE \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ "http://localhost:9966/management/instances/test?purge=yes" \ -w "%{http_code}" -s -o /dev/null) diff --git a/src/testing/test_merchant_kyc.sh b/src/testing/test_merchant_kyc.sh @@ -33,9 +33,8 @@ echo -n "Configuring a merchant admin instance ..." STATUS=$(curl -H "Content-Type: application/json" \ -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ + -d '{"auth":{"method":"token","password":"super_secret"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ -w "%{http_code}" \ -s \ -o /dev/null) @@ -44,6 +43,7 @@ if [ "$STATUS" != "204" ] then exit_fail "Expected 204 ok, instance created. got: $STATUS" fi +ADMIN_TOKEN=$(merchant_login admin super_secret) echo " OK" @@ -51,7 +51,7 @@ echo -n "Creating account ..." STATUS=$(curl -H "Content-Type: application/json" \ -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/43?receiver-name=user43"}' \ -w "%{http_code}" \ @@ -69,7 +69,7 @@ echo -n "Creating conflicting account with different receiver name ..." STATUS=$(curl -H "Content-Type: application/json" \ -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/43?receiver-name=user44"}' \ -w "%{http_code}" \ @@ -87,7 +87,7 @@ echo -n "Creating a second account ..." STATUS=$(curl -H "Content-Type: application/json" \ -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/44?receiver-name=user44"}' \ -w "%{http_code}" \ @@ -104,6 +104,7 @@ echo " OK" echo -n "Check the (admin) instance exists ..." STATUS=$(curl -H "Content-Type: application/json" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -X GET \ http://localhost:9966/private/ \ -w "%{http_code}" \ @@ -125,6 +126,7 @@ RANDOM_IMG='data:image/png;base64,abcdefg' echo -n "Creating order without TOKEN..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"create_token":false,"order":{"amount":"TESTKUDOS:7","summary":"3","products":[{"description":"desct","image":"'"$RANDOM_IMG"'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \ -w "%{http_code}" \ -s \ @@ -167,6 +169,7 @@ echo "OK" echo -n "Getting information about KYC ..." STATUS=$(curl -H "Accept: application/json" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -X GET \ http://localhost:9966/private/kyc \ -w "%{http_code}" \ @@ -183,6 +186,7 @@ echo " OK" echo -n "Getting information about KYC in plaintext ..." STATUS=$(curl -H "Accept: text/plain" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -X GET \ http://localhost:9966/private/kyc \ -w "%{http_code}" \ @@ -217,6 +221,7 @@ echo " OK" echo -n "Requesting KYC wire transfer instructions ..." STATUS=$(curl -H "Accept: application/json" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -X POST \ "http://localhost:9966/private/accounts/$H_WIRE/kycauth" \ -d '{"exchange_url":"http://localhost:8081/"}' \ diff --git a/src/testing/test_merchant_mfa.conf b/src/testing/test_merchant_mfa.conf @@ -12,6 +12,7 @@ DISABLED = YES [merchant] PORT = 9966 SERVE = tcp +STRICT_PROTOCOL_V19 = YES DB = postgres HELPER_SMS = ./test_sms_helper.sh HELPER_EMAIL = ./test_email_helper.sh diff --git a/src/testing/test_merchant_mfa.sh b/src/testing/test_merchant_mfa.sh @@ -43,76 +43,21 @@ rm -f "$INVALID_CONFIG" "$INVALID_LOG" echo "OK" +# The TAN helpers started by the merchant write into this directory. +TALER_MERCHANT_TEST_TAN_DIR=$(mktemp -d -p "${TMPDIR:-/tmp}" test_merchant_mfa-tan-XXXXXX) +export TALER_MERCHANT_TEST_TAN_DIR + # Launch system. setup \ -c "test_merchant_mfa.conf" \ -m LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX) -solve_challenge() -{ - CHALLENGE_ID=$1 - CHANNEL=$2 - EXPECTED_ADDRESS=$3 - - rm -f "/tmp/test-merchant-$CHANNEL-tan.txt" \ - "/tmp/test-merchant-$CHANNEL-address.txt" - STATUS=$(curl -H "Content-Type: application/json" -X POST \ - "http://localhost:9966/challenge/$CHALLENGE_ID" \ - -d '{}' \ - -w "%{http_code}" -s \ - -o "$LAST_RESPONSE") - if [ "$STATUS" != "200" ] - then - jq < "$LAST_RESPONSE" - exit_fail "Expected challenge transmission to return 200 OK. Got: $STATUS" - fi - - TAN=$(head -n1 "/tmp/test-merchant-$CHANNEL-tan.txt" | awk '{print $1}') - ADDRESS=$(cat "/tmp/test-merchant-$CHANNEL-address.txt") - if [ "$ADDRESS" != "$EXPECTED_ADDRESS" ] - then - exit_fail "Expected $CHANNEL address '$EXPECTED_ADDRESS'. Got: $ADDRESS" - fi - - STATUS=$(curl -H "Content-Type: application/json" -X POST \ - "http://localhost:9966/challenge/$CHALLENGE_ID/confirm" \ - -d '{"tan":"'"$TAN"'"}' \ - -w "%{http_code}" -s \ - -o "$LAST_RESPONSE") - if [ "$STATUS" != "204" ] - then - jq < "$LAST_RESPONSE" - exit_fail "Expected challenge confirmation to return 204 No Content. Got: $STATUS" - fi -} - - -solve_response_challenges() -{ - RESPONSE=$1 - while IFS=$'\t' read -r CHALLENGE_ID CHANNEL - do - case "$CHANNEL" in - email) - solve_challenge "$CHALLENGE_ID" "$CHANNEL" "self@example.com" - ;; - sms) - solve_challenge "$CHALLENGE_ID" "$CHANNEL" "+4171234" - ;; - *) - exit_fail "Unexpected TAN channel: $CHANNEL" - ;; - esac - done < <(jq -r '.challenges[] | [.challenge_id, .tan_channel] | @tsv' "$RESPONSE") -} - echo -n "Configuring a merchant admin instance ..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -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}}' \ + -d '{"auth":{"method":"token","password":"super_secret"},"id":"admin","name":"default","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ -w "%{http_code}" -s \ -o "$LAST_RESPONSE") @@ -122,8 +67,9 @@ then exit_fail "Expected 204 ok, instance created. got: $STATUS" fi +ADMIN_TOKEN=$(merchant_login admin super_secret) STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/43?receiver-name=user43"}' \ -w "%{http_code}" -s \ @@ -170,8 +116,8 @@ then fi echo "OK" -TAN=$(cat /tmp/test-merchant-email-tan.txt | head -n1 | awk '{print $1}') -ADDR=$(cat /tmp/test-merchant-email-address.txt) +TAN=$(cat "$(tan_dir)/test-merchant-email-tan.txt" | head -n1 | awk '{print $1}') +ADDR=$(cat "$(tan_dir)/test-merchant-email-address.txt") if [ "$ADDR" != "self@example.com" ] then @@ -208,7 +154,7 @@ then fi echo "OK" -TAN=$(cat /tmp/test-merchant-sms-tan.txt | head -n1 | awk '{print $1}') +TAN=$(cat "$(tan_dir)/test-merchant-sms-tan.txt" | head -n1 | awk '{print $1}') echo -n "Sending challenge $C2 solution " @@ -233,7 +179,7 @@ STATUS=$(curl \ -H "Taler-Challenge-Ids: $C1,$C2" \ -X POST \ http://localhost:9966/instances \ - -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}}' \ + -d '{"auth":{"method":"token","password":"pass1234"},"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}}' \ -w "%{http_code}" -s \ -o "$LAST_RESPONSE") @@ -283,11 +229,16 @@ fi echo " OK" +echo -n "Log in to MFA-protected instance " +SELF_TOKEN=$(merchant_login_mfa self pass1234 self@example.com +4171234) +echo "OK" + + echo -n "Do NOT Trigger MFA to add first bank account " STATUS=$(curl \ -H "Content-Type: application/json" \ -X POST \ - -H 'Authorization: Bearer secret-token:pass1234' \ + -H "Authorization: Bearer $SELF_TOKEN" \ http://localhost:9966/instances/self/private/accounts \ -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/44?receiver-name=user44"}' \ -w "%{http_code}" -s \ @@ -306,7 +257,7 @@ echo -n "Trigger MFA to add 2nd bank account with 2-FA authorization " STATUS=$(curl \ -H "Content-Type: application/json" \ -X POST \ - -H 'Authorization: Bearer secret-token:pass1234' \ + -H "Authorization: Bearer $SELF_TOKEN" \ http://localhost:9966/instances/self/private/accounts \ -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/45?receiver-name=user45"}' \ -w "%{http_code}" -s \ @@ -324,7 +275,7 @@ echo " OK" C1=$(jq -r .challenges[0].challenge_id < "$LAST_RESPONSE") # Delete old TANs. -rm /tmp/test-merchant-*-tan.txt +rm -f "$(tan_dir)"/test-merchant-*-tan.txt echo -n "Requesting challenge $C1 " STATUS=$(curl -H "Content-Type: application/json" -X POST \ @@ -340,8 +291,8 @@ then fi echo "OK" -TAN=$(cat /tmp/test-merchant-email-tan.txt | head -n1 | awk '{print $1}') -ADDR=$(cat /tmp/test-merchant-email-address.txt) +TAN=$(cat "$(tan_dir)/test-merchant-email-tan.txt" | head -n1 | awk '{print $1}') +ADDR=$(cat "$(tan_dir)/test-merchant-email-address.txt") if [ "$ADDR" != "self@example.com" ] then @@ -370,7 +321,7 @@ STATUS=$(curl \ -X POST \ -H "Content-Type: application/json" \ -H "Taler-Challenge-Ids: $C1" \ - -H 'Authorization: Bearer secret-token:pass1234' \ + -H "Authorization: Bearer $SELF_TOKEN" \ http://localhost:9966/instances/self/private/accounts \ -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/45?receiver-name=user45"}' \ -w "%{http_code}" -s \ @@ -420,8 +371,8 @@ then fi echo "OK" -TAN=$(cat /tmp/test-merchant-email-tan.txt | head -n1 | awk '{print $1}') -ADDR=$(cat /tmp/test-merchant-email-address.txt) +TAN=$(cat "$(tan_dir)/test-merchant-email-tan.txt" | head -n1 | awk '{print $1}') +ADDR=$(cat "$(tan_dir)/test-merchant-email-address.txt") if [ "$ADDR" != "self@example.com" ] then @@ -447,7 +398,7 @@ echo -n "Reject password reset with only one mandatory challenge solved " STATUS=$(curl \ -X POST \ -H "Content-Type: application/json" \ - -H "Taler-Challenge-Ids: $C1" \ + -H "Taler-Challenge-Ids: $C1,$C2" \ http://localhost:9966/instances/self/forgot-password \ -d '{"method":"token","password":"amnesia"}' \ -w "%{http_code}" -s \ @@ -477,7 +428,7 @@ then fi echo "OK" -TAN=$(cat /tmp/test-merchant-sms-tan.txt | head -n1 | awk '{print $1}') +TAN=$(cat "$(tan_dir)/test-merchant-sms-tan.txt" | head -n1 | awk '{print $1}') echo -n "Sending challenge $C2 solution " @@ -534,7 +485,8 @@ fi cp "$LAST_RESPONSE" "$LAST_RESPONSE.challenges" RESET_CHALLENGE_IDS=$(jq -r '[.challenges[].challenge_id] | join(",")' \ < "$LAST_RESPONSE") -solve_response_challenges "$LAST_RESPONSE.challenges" +solve_response_challenges "$LAST_RESPONSE.challenges" \ + self@example.com +4171234 > /dev/null echo "OK" @@ -665,7 +617,8 @@ fi cp "$LAST_RESPONSE" "$LAST_RESPONSE.challenges" OTHER_CREATE_CHALLENGE_IDS=$(jq -r \ '[.challenges[].challenge_id] | join(",")' < "$LAST_RESPONSE") -solve_response_challenges "$LAST_RESPONSE.challenges" +solve_response_challenges "$LAST_RESPONSE.challenges" \ + self@example.com +4171234 > /dev/null STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H "Taler-Challenge-Ids: $OTHER_CREATE_CHALLENGE_IDS" \ @@ -684,7 +637,7 @@ echo "OK" echo -n "Solve token-creation challenge for first instance " TOKEN_BODY='{"scope":"spa","duration":{"d_us":600000000},"refreshable":true}' STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:recovered' \ + -H "Authorization: Basic $(printf %s self:recovered | base64 -w0)" \ http://localhost:9966/instances/self/private/token \ -d "$TOKEN_BODY" \ -w "%{http_code}" -s \ @@ -715,7 +668,7 @@ echo "OK" echo -n "Reject solved challenge at a different instance " STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:recovered' \ + -H "Authorization: Basic $(printf %s other:recovered | base64 -w0)" \ -H "Taler-Challenge-Ids: $INSTANCE_CHALLENGE_ID" \ http://localhost:9966/instances/other/private/token \ -d "$TOKEN_BODY" \ @@ -736,7 +689,7 @@ echo "OK" echo -n "Accept solved challenge at its original instance " STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:recovered' \ + -H "Authorization: Basic $(printf %s self:recovered | base64 -w0)" \ -H "Taler-Challenge-Ids: $INSTANCE_CHALLENGE_ID" \ http://localhost:9966/instances/self/private/token \ -d "$TOKEN_BODY" \ @@ -750,6 +703,39 @@ fi echo "OK" +echo -n "Start a password reset and leave it unfinished " +STATUS=$(curl \ + -X POST \ + -H "Content-Type: application/json" \ + http://localhost:9966/instances/self/forgot-password \ + -d '{"method":"token","password":"unfinished"}' \ + -w "%{http_code}" -s \ + -o "$LAST_RESPONSE") +if [ "$STATUS" != "202" ] +then + jq < "$LAST_RESPONSE" + exit_fail "Expected 202 Accepted. Got: $STATUS" +fi +echo "OK" + + +echo -n "Refuse the next password reset while the last one is unfinished " +STATUS=$(curl \ + -X POST \ + -H "Content-Type: application/json" \ + http://localhost:9966/instances/self/forgot-password \ + -d '{"method":"token","password":"unfinished"}' \ + -w "%{http_code}" -s \ + -o "$LAST_RESPONSE") +if [ "$STATUS" != "429" ] || + [ "$(jq -r .code < "$LAST_RESPONSE")" != "2130" ] +then + jq < "$LAST_RESPONSE" + exit_fail "Expected 429 with code 2130. Got: $STATUS" +fi +echo "OK" + + echo "TEST PASSED" exit 0 diff --git a/src/testing/test_merchant_order_autocleanup.sh b/src/testing/test_merchant_order_autocleanup.sh @@ -95,18 +95,18 @@ else fi STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ "http://localhost:9966/management/instances" \ - -d '{"auth":{"method":"external"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ + -d '{"auth":{"method":"token","password":"super_secret"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then exit_fail "Expected 204, instance created. got: $STATUS" fi +ADMIN_TOKEN=$(merchant_login admin super_secret) STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"'"$FORTYTHREE"'"}' \ -w "%{http_code}" -s -o /dev/null) @@ -121,6 +121,7 @@ IN_TEN_SECS=$(( NOW + 10 )) echo -n "Creating order to be claimed..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme","pay_deadline": {"t_s":'"$IN_TEN_SECS"'}}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -134,6 +135,7 @@ ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -157,6 +159,7 @@ taler-wallet-cli \ 2> wallet-claim1.err > wallet-claim1.log STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -180,6 +183,7 @@ sleep 8 echo -n "Trying to get the list of orders..." STATUS=$(curl "http://localhost:9966/private/orders" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -191,6 +195,7 @@ echo "ok" echo -n "Creating a new order that will trigger the db cleanup..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -204,6 +209,7 @@ ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -218,6 +224,7 @@ echo "Ok (order $ORDER_ID)" echo -n "Trying to get the list of orders (issue #7025)..." STATUS=$(curl "http://localhost:9966/private/orders" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -238,6 +245,7 @@ taler-wallet-cli \ 2> wallet-pay1.err > wallet-pay1.log STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -259,6 +267,7 @@ echo " OK (took $(( NOW2 - NOW)) secs )" echo -n "Trying to get the list of orders..." STATUS=$(curl "http://localhost:9966/private/orders" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -271,6 +280,7 @@ echo ok echo -n "Finally, create another order..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -284,6 +294,7 @@ ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -306,6 +317,7 @@ taler-wallet-cli \ 2> wallet-pay1.err > wallet-pay1.log STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -326,6 +338,7 @@ echo " OK (took $( echo -n $(($NOW2 - $NOW)) ) secs )" echo -n "Trying to get the list of orders..." STATUS=$(curl "http://localhost:9966/private/orders" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] diff --git a/src/testing/test_merchant_order_creation.sh b/src/testing/test_merchant_order_creation.sh @@ -113,15 +113,15 @@ fi echo -n "Configuring merchant instance ..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000000},"default_pay_delay":{"d_us": 60000000000}}' \ + -d '{"auth":{"method":"token","password":"super_secret"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000000},"default_pay_delay":{"d_us": 60000000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then exit_fail "Expected '204 No content' response. Got instead $STATUS" fi +ADMIN_TOKEN=$(merchant_login admin super_secret) echo "Ok" echo -n "Configuring merchant account ..." @@ -134,7 +134,7 @@ else fi # create with 2 bank account addresses STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"'"$FORTYTHREE"'"}' \ -w "%{http_code}" -s -o /dev/null) @@ -144,7 +144,7 @@ then exit_fail "Expected '200 OK' response. Got instead $STATUS" fi STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"payto://iban/SANDBOXX/DE270744?receiver-name=Forty+Four"}' \ -w "%{http_code}" -s -o /dev/null) @@ -159,6 +159,7 @@ echo "Ok" echo -n "Get accounts..." STATUS=$(curl http://localhost:9966/private/accounts \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") PAY_URI=$(jq -r .accounts[1].payto_uri < "$LAST_RESPONSE") H_WIRE=$(jq -r .accounts[1].h_wire < "$LAST_RESPONSE") @@ -172,7 +173,7 @@ echo "OK" # remove one account address echo -n "Deleting one account ..." STATUS=$(curl -H "Content-Type: application/json" -X PATCH \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ "http://localhost:9966/private/accounts/${H_WIRE}" \ -X DELETE \ -w "%{http_code}" -s -o /dev/null) @@ -191,6 +192,7 @@ RANDOM_IMG='data:image/png;base64,abcdefg' echo -n "Creating order without TOKEN..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"create_token":false,"refund_delay":{"d_us":0},"order":{"amount":"TESTKUDOS:7","summary":"3 <unsafe> & tea","products":[{"description":"desct","image":"'"$RANDOM_IMG"'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -244,6 +246,7 @@ echo "OK" echo -n "Creating order without TOKEN and fullfilment URL..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"create_token":false,"refund_delay":{"d_us":0},"order":{"fulfillment_url":"go_here_please", "amount":"TESTKUDOS:7","summary":"3","products":[{"description":"desct","image":"'"$RANDOM_IMG"'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -288,6 +291,7 @@ VALID_AFTER="{\"t_s\": $(date +%s)}" # now VALID_BEFORE="{\"t_s\": $(date +%s -d "+30 days")}" # 30 days from now DURATION="{\"d_us\": $(expr 30 \* 24 \* 60 \* 60 \* 1000000)}" # 30 days STATUS=$(curl 'http://localhost:9966/private/tokenfamilies' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d "{\"kind\": \"discount\", \"slug\":\"test-discount\", \"name\": \"Test discount\", \"description\": \"Less money $$\", \"description_i18n\": {\"en\": \"Less money $$\", \"es\": \"Menos dinero $$\"}, \"valid_after\": $VALID_AFTER, \"valid_before\": $VALID_BEFORE, \"duration\": $DURATION, \"validity_granularity\": $DURATION}" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "204" ] @@ -305,6 +309,7 @@ VALID_AFTER="{\"t_s\": $(date +%s)}" # now VALID_BEFORE="{\"t_s\": $(date +%s -d "+30 days")}" # 30 days from now DURATION="{\"d_us\": $(expr 30 \* 24 \* 60 \* 60 \* 1000000)}" # 30 days STATUS=$(curl 'http://localhost:9966/private/tokenfamilies' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d "{\"kind\": \"subscription\", \"slug\":\"test-subscription\", \"name\": \"Test subscription\", \"description\": \"Money per month\", \"description_i18n\": {\"en\": \"Money $$$ per month\", \"es\": \"Dinero $$$ al mes\"}, \"valid_after\": $VALID_AFTER, \"valid_before\": $VALID_BEFORE, \"duration\": $DURATION, \"validity_granularity\": $DURATION}" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "204" ] @@ -321,6 +326,7 @@ RANDOM_IMG='data:image/png;base64,abcdefg' echo -n "Creating discountable order..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"create_token":true,"refund_delay":{"d_us":0},"order":{"version":1,"summary":"Expensive purchase","products":[{"description":"Expensive steak","quantity":2,"unit":"pieces","price":"TESTKUDOS:100"}],"choices":[{"amount":"TESTKUDOS:100"},{"amount":"TESTKUDOS:10","inputs":[{"type":"token","token_family_slug":"test-discount","count":1}],"outputs":[]}]}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -414,6 +420,7 @@ echo "OK" echo -n "Creating order with non-inventory products..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"refund_delay":{"d_us":0},"order":{"amount":"TESTKUDOS:7","summary":"3","products":[{"description":"desct","image":"'"$RANDOM_IMG"'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -458,6 +465,7 @@ echo "OK" echo -n "Creating product..." STATUS=$(curl 'http://localhost:9966/private/products' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"product_id":"2","description":"product with id 2 and price :15","unit_price":["TESTKUDOS:15"],"unit_total_stock":"2","description_i18n":{},"unit":"u","image":"'$RANDOM_IMG'","taxes":[],"address":{},"next_restock":{"t_s":"never"}}' \ -w "%{http_code}" -s -o /dev/null) @@ -469,6 +477,7 @@ echo "OK" echo -n "Creating order with inventory products..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"refund_delay":{"d_us":0},"order":{"amount":"TESTKUDOS:7","summary":"3"},"inventory_products":[{"product_id":"2","unit_quantity":"1"}]}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -507,6 +516,7 @@ echo "OK" STATUS=$(curl 'http://localhost:9966/private/products' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"product_id":"1","description":"product with id 1 and price :15","unit_price":["USD:15"],"unit_total_stock":"1","description_i18n":{},"unit":"u","image":"","taxes":[],"address":{},"next_restock":{"t_s":"never"}}' \ -w "%{http_code}" -s -o /dev/null) @@ -521,6 +531,7 @@ fi echo -n "Creating order to be paid..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"refund_delay":{"d_us":0},"order":{"amount":"TESTKUDOS:1","summary":"payme"},"inventory_products":[{"product_id":"2","unit_quantity":"1"}]}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -534,6 +545,7 @@ ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -562,6 +574,7 @@ NOW2=$(date +%s) echo " OK (took $(( NOW2 - NOW )) secs )" STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -647,6 +660,7 @@ set +e echo -n "Notifying merchant of bogus wire transfer ..." STATUS=$(curl 'http://localhost:9966/private/transfers' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"credit_amount":"'"$CREDIT_AMOUNT"'1","wtid":"'"$WTID"'","payto_uri":"'"$TARGET_PAYTO"'","exchange_url":"'"$WURL"'"}' \ -m 3 \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -661,8 +675,9 @@ echo "OK" echo -n "Deleting bogus wire transfer ..." -TID=$(curl -s http://localhost:9966/private/transfers | jq -r .transfers[0].transfer_serial_id) +TID=$(curl -H "Authorization: Bearer $ADMIN_TOKEN" -s http://localhost:9966/private/transfers | jq -r .transfers[0].transfer_serial_id) STATUS=$(curl -H "Content-Type: application/json" -X DELETE \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ "http://localhost:9966/private/transfers/$TID" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -673,6 +688,7 @@ then fi STATUS=$(curl -H "Content-Type: application/json" -X DELETE \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ "http://localhost:9966/private/transfers/$TID" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "404" ] @@ -686,6 +702,7 @@ echo " OK" echo -n "Notifying merchant of correct wire transfer..." STATUS=$(curl 'http://localhost:9966/private/transfers' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"credit_amount":"'"$CREDIT_AMOUNT"'","wtid":"'"$WTID"'","payto_uri":"'"$TARGET_PAYTO"'","exchange_url":"'"$WURL"'"}' \ -m 3 \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -720,6 +737,7 @@ echo " OK" echo -n "Fetching wire transfers ..." STATUS=$(curl 'http://localhost:9966/private/transfers' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -740,6 +758,7 @@ echo "OK" echo -n "Checking order status ..." STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}?transfer=YES" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then @@ -793,6 +812,7 @@ echo " OK" echo -n "Getting information about kyc ..." STATUS=$(curl -H "Content-Type: application/json" -X GET \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/kyc \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "200" ] diff --git a/src/testing/test_merchant_order_refund.sh b/src/testing/test_merchant_order_refund.sh @@ -112,15 +112,15 @@ fi echo -n "Configuring merchant instance ..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000000},"default_pay_delay":{"d_us": 60000000000}}' \ + -d '{"auth":{"method":"token","password":"super_secret"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000000},"default_pay_delay":{"d_us": 60000000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then exit_fail "Expected '204 No content' response. Got instead $STATUS" fi +ADMIN_TOKEN=$(merchant_login admin super_secret) echo "Ok" echo -n "Configuring merchant account ..." @@ -133,7 +133,7 @@ else fi # create with 2 bank account addresses STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"'"$FORTYTHREE"'"}' \ -w "%{http_code}" -s -o /dev/null) @@ -152,6 +152,7 @@ echo "Ok" echo -n "Creating order to be paid..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"order":{"amount":"TESTKUDOS:5","summary":"payme","auto_refund":{"d_us":180000000}}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -165,6 +166,7 @@ ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") RESPONSE_HEADERS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{header_json}" \ -s \ -o "$LAST_RESPONSE") @@ -180,6 +182,7 @@ LP_START=$(date +%s) echo -n "Long-polling for order status change paid..." curl "http://localhost:9966/private/orders/${ORDER_ID}?timeout_ms=30000&lp_not_etag=${ETAG_NQ}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "If-none-match: $ETAG" \ -w "%{header_json}" \ -s \ @@ -209,6 +212,7 @@ PAYMENT_END=$(date +%s) echo " OK (payment took $(( PAYMENT_END - PAYMENT_START )) secs )" STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -239,6 +243,7 @@ echo " OK" echo -n "Sending refund for TESTKUDOS:1 ..." STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}/refund" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"refund":"TESTKUDOS:1","reason":"duplicated"}' \ -w "%{http_code}" \ -s \ @@ -283,6 +288,7 @@ echo " OK (refund1 took $(( REFUND_END - REFUND_START )) secs)" echo -n "Increasing refund for TESTKUDOS:3 ..." STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}/refund" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"refund":"TESTKUDOS:5","reason":"duplicated"}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") diff --git a/src/testing/test_merchant_product_creation.sh b/src/testing/test_merchant_product_creation.sh @@ -65,18 +65,18 @@ EXCHANGE_URL="http://localhost:8081/" echo -n "Configuring merchant instance ..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ "http://localhost:9966/management/instances" \ - -d '{"auth":{"method":"external"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ + -d '{"auth":{"method":"token","password":"super_secret"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then exit_fail "Expected 204 No content, instance created. Got $STATUS instead" fi +ADMIN_TOKEN=$(merchant_login admin super_secret) STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"'"$FORTYTHREE"'"}' \ -w "%{http_code}" -s -o /dev/null) @@ -94,6 +94,7 @@ MANAGED_PRODUCT_TEMPLATE='{"product_id":"3","product_name":"more stuff","descrip echo -n "Creating products..." STATUS=$(curl 'http://localhost:9966/private/products' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d "$INFINITE_PRODUCT_TEMPLATE" \ -w "%{http_code}" -s -o /dev/null) @@ -103,6 +104,7 @@ then fi STATUS=$(curl 'http://localhost:9966/private/products' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d "$MANAGED_PRODUCT_TEMPLATE" \ -w "%{http_code}" -s -o /dev/null) @@ -117,6 +119,7 @@ PRODUCT_DATA=$(echo "$INFINITE_PRODUCT_TEMPLATE" | jq 'del(.product_id) | . + {d echo -n "Updating infinite stock product..." STATUS=$(curl 'http://localhost:9966/private/products/2' -X PATCH \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d "$PRODUCT_DATA" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -127,6 +130,7 @@ then fi STATUS=$(curl 'http://localhost:9966/private/products/2' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") DESCRIPTION=$(jq -r .description < "$LAST_RESPONSE") @@ -143,6 +147,7 @@ MANAGED_PRODUCT_ID=$(echo "$MANAGED_PRODUCT_TEMPLATE" | jq -r '.product_id') echo -n "Locking inventory ..." STATUS=$(curl "http://localhost:9966/private/products/${MANAGED_PRODUCT_ID}/lock" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"lock_uuid":"luck","duration":{"d_us": 100000000},"unit_quantity":"10"}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -155,6 +160,7 @@ fi echo -n "." STATUS=$(curl "http://localhost:9966/private/products/${MANAGED_PRODUCT_ID}/lock" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"lock_uuid":"luck","duration":{"d_us": 100000000},"unit_quantity":"1"}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -167,6 +173,7 @@ echo " OK" echo -n "Creating order to be paid..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"},"inventory_products":[{"product_id":"'"${MANAGED_PRODUCT_ID}"'","unit_quantity":"1"}]}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -180,6 +187,7 @@ ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") #TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -192,6 +200,7 @@ PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE") echo -n "." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"},"inventory_products":[{"product_id":"'"${MANAGED_PRODUCT_ID}"'","unit_quantity":"1"}]}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -205,6 +214,7 @@ echo -n "." # Using the 'luck' inventory lock, order creation should work. STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"},"lock_uuids":["luck"],"inventory_products":[{"product_id":"'"$MANAGED_PRODUCT_ID"'","unit_quantity":"1"}]}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -266,6 +276,7 @@ echo " OK (took $(( NOW2 - NOW)) secs )" STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -288,6 +299,7 @@ echo -n "Updating product..." PRODUCT_DATA=$(echo "$MANAGED_PRODUCT_TEMPLATE" | jq 'del(.product_id) | . + {"total_stock": (.total_stock + 2) }') STATUS=$(curl 'http://localhost:9966/private/products/3' -X PATCH \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d "$PRODUCT_DATA" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -299,6 +311,7 @@ fi echo -n "Requesting inventory..." STATUS=$(curl 'http://localhost:9966/private/products?name_filter=more' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] diff --git a/src/testing/test_merchant_signup_email.sh b/src/testing/test_merchant_signup_email.sh @@ -49,7 +49,7 @@ taler-merchant-config \ echo -n "Configuring admin instance without e-mail address ..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"id":"admin","name":"default","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ + -d '{"auth":{"method":"token","password":"super_secret"},"id":"admin","name":"default","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "204" ] @@ -57,10 +57,12 @@ then jq < "$LAST_RESPONSE" exit_fail "Expected 204, instance created. got: $STATUS" fi +ADMIN_TOKEN=$(merchant_login admin super_secret) echo " OK" echo -n "Creating instance with e-mail address ..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/management/instances \ -d '{"auth":{"method":"token","password":"pass1234"},"id":"signup","name":"Signup & Sons","email":"'"$EMAIL"'","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") diff --git a/src/testing/test_merchant_statistics.sh b/src/testing/test_merchant_statistics.sh @@ -95,15 +95,15 @@ fi echo -n "Configuring merchant instance ..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000000},"default_pay_delay":{"d_us": 60000000000}}' \ + -d '{"auth":{"method":"token","password":"super_secret"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000000},"default_pay_delay":{"d_us": 60000000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then exit_fail "Expected '204 No content' response. Got instead $STATUS" fi +ADMIN_TOKEN=$(merchant_login admin super_secret) echo "Ok" echo -n "Configuring merchant account ..." @@ -117,7 +117,7 @@ fi # add bank account STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"'"$FORTYTHREE"'"}' \ -w "%{http_code}" -s -o /dev/null) @@ -131,7 +131,7 @@ echo "OK" echo -n "Adding same account again ..." # add same bank account again (check idempotency) STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"'"$FORTYTHREE"'"}' \ -w "%{http_code}" -s -o /dev/null) @@ -144,7 +144,7 @@ echo "OK" echo -n "Checking idempotency ..." curl -H "Content-Type: application/json" \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts > "$LAST_RESPONSE" 2> /dev/null NUM=$(jq '.accounts|length' < "$LAST_RESPONSE") @@ -158,6 +158,7 @@ echo " OK" echo -n "Creating order with non-existing POT..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"create_token":false,"refund_delay":{"d_us":0},"order":{"amount":"TESTKUDOS:7","summary":"3","order_default_money_pot":1}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -171,6 +172,7 @@ echo "OK" echo -n "Creating money pot..." STATUS=$(curl 'http://localhost:9966/private/pots' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"description":"First pot","pot_name":"pot1"}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -185,6 +187,7 @@ echo "OK" echo -n "Creating order with money pot..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"create_token":false,"refund_delay":{"d_us":0},"order":{"amount":"TESTKUDOS:7","summary":"3","order_default_money_pot":'"$MONEY_POT"'}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -229,6 +232,7 @@ echo " OK (took $(( NOW2 - NOW )) secs )" echo -n "Checking money pot..." STATUS=$(curl 'http://localhost:9966/private/pots' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -247,6 +251,7 @@ echo "OK" echo -n "Patching money pot ..." STATUS=$(curl "http://localhost:9966/private/pots/$MONEY_POT" -X PATCH \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"description":"Updated pot","expected_pot_totals":[],"new_pot_totals":["KUDOS:23"],"pot_name":"pot1p"}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -259,6 +264,7 @@ echo "OK" echo -n "Schedule periodic report..." STATUS=$(curl 'http://localhost:9966/private/reports' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"description":"My report","program_section":"file","mime_type":"application/pdf","data_source":"/private/statistics-report/transactions","target_address":"'"${TMPDIR:-/tmp}/last-report"'","report_frequency":{"d_us" : 50000000}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") diff --git a/src/testing/test_merchant_templates.sh b/src/testing/test_merchant_templates.sh @@ -94,15 +94,15 @@ fi echo -n "Configuring merchant instance ..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000000},"default_pay_delay":{"d_us": 60000000000}}' \ + -d '{"auth":{"method":"token","password":"super_secret"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000000},"default_pay_delay":{"d_us": 60000000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then exit_fail "Expected '204 No content' response. Got instead $STATUS" fi +ADMIN_TOKEN=$(merchant_login admin super_secret) echo "Ok" echo -n "Configuring merchant bank account ..." @@ -115,7 +115,7 @@ else fi # add bank account address STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"'"$FORTYTHREE"'"}' \ -w "%{http_code}" -s -o /dev/null) @@ -130,6 +130,7 @@ echo "Ok" echo -n "Creating Paivana template..." TID="paivana" STATUS=$(curl 'http://localhost:9966/private/templates' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"template_id":"paivana","template_description":"A Paivana template","template_contract":{"template_type":"paivana","summary":"The summary","choices":[{"amount":"TESTKUDOS:1"}]}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -178,6 +179,7 @@ echo "OK" echo -n "Fetching order details ..." STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}?session_id=${PAIVANA_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -219,6 +221,7 @@ echo " OK (took $(( NOW2 - NOW )) secs )" # Check payment status AND binding to session ID. STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}?session_id=${PAIVANA_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -241,6 +244,7 @@ fi echo -n "Rejecting amount limits without a currency ..." STATUS=$(curl 'http://localhost:9966/private/templates' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"template_id":"paivana-bad","template_description":"Limits but no currency","template_contract":{"template_type":"paivana","summary":"The summary","min_amount":"TESTKUDOS:0.5","choices":[{"amount":"TESTKUDOS:1"}]}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -253,6 +257,7 @@ echo " OK" echo -n "Rejecting amount limits in different currencies ..." STATUS=$(curl 'http://localhost:9966/private/templates' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"template_id":"paivana-bad","template_description":"Limits in different currencies","template_contract":{"template_type":"paivana","summary":"The summary","min_amount":"TESTKUDOS:1","max_amount":"EUR:2","choices":[{"amount":"TESTKUDOS:1"}]}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -265,6 +270,7 @@ echo " OK" echo -n "Rejecting min_amount above max_amount ..." STATUS=$(curl 'http://localhost:9966/private/templates' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"template_id":"paivana-bad","template_description":"Limits inverted","template_contract":{"template_type":"paivana","summary":"The summary","currency":"TESTKUDOS","min_amount":"TESTKUDOS:5","max_amount":"TESTKUDOS:1","choices":[{"amount":"TESTKUDOS:1"}]}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -290,6 +296,7 @@ echo " OK" echo -n "Creating Paivana template with an editable amount..." ETID="paivana-editable" STATUS=$(curl 'http://localhost:9966/private/templates' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"template_id":"paivana-editable","template_description":"A Paivana template with an editable amount","template_contract":{"template_type":"paivana","summary":"The summary","currency":"TESTKUDOS","min_amount":"TESTKUDOS:0.5","max_amount":"TESTKUDOS:10","choices":[{"amount":"TESTKUDOS:2","editable_amount":true}]},"editable_defaults":{"amount":"TESTKUDOS:2"}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -388,6 +395,7 @@ fi EORDER_ID=$(jq -r .order_id < "$LAST_RESPONSE") STATUS=$(curl "http://localhost:9966/private/orders/${EORDER_ID}?session_id=${EPAIVANA_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -418,6 +426,7 @@ fi CORDER_ID=$(jq -r .order_id < "$LAST_RESPONSE") STATUS=$(curl "http://localhost:9966/private/orders/${CORDER_ID}?session_id=${CPAIVANA_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] diff --git a/src/testing/test_merchant_transfer_tracking.sh b/src/testing/test_merchant_transfer_tracking.sh @@ -119,18 +119,18 @@ fi # create with 2 address STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ + -d '{"auth":{"method":"token","password":"super_secret"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then exit_fail "Expected 204, instance created. got: $STATUS" fi +ADMIN_TOKEN=$(merchant_login admin super_secret) STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"'"$TOR_PAYTO"'"}' \ -w "%{http_code}" -s -o /dev/null) @@ -140,7 +140,7 @@ then exit_fail "Expected 200 OK. Got: $STATUS" fi STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"'"$GNUNET_PAYTO"'"}' \ -w "%{http_code}" -s -o /dev/null) @@ -156,17 +156,18 @@ echo -n "Configuring merchant test instance ..." # create with 2 address STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"id":"test","name":"test","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ + -d '{"auth":{"method":"token","password":"super_secret"},"id":"test","name":"test","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then exit_fail "Expected 204, instance created. got: $STATUS" fi +TOKEN_TEST=$(merchant_login test super_secret) STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $TOKEN_TEST" \ http://localhost:9966/instances/test/private/accounts \ -d '{"payto_uri":"'"$SURVEY_PAYTO"'","credit_facade_url":"http://localhost:8082/accounts/survey/taler-revenue/","credit_facade_credentials":{"type":"basic","username":"survey","password":"x"}}' \ -w "%{http_code}" -s -o /dev/null) @@ -179,6 +180,7 @@ fi # CREATE ORDER AND SELL IT echo -n "Creating order to be paid..." STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \ + -H "Authorization: Bearer $TOKEN_TEST" \ -d '{"refund_delay":{"d_us":0}, "order":{"amount":"TESTKUDOS:1","summary":"payme"}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -204,6 +206,7 @@ check_order_listing() { local num status=$(curl "http://localhost:9966/instances/test/private/orders?limit=20&$args" \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" \ -s \ -o "$LAST_RESPONSE") @@ -230,6 +233,7 @@ echo " OK" echo -n "Checking unwired value in order listing..." STATUS=$(curl 'http://localhost:9966/instances/test/private/orders?limit=20' \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then @@ -266,6 +270,7 @@ then # Check max-age argument echo -n "Checking order list generation with max-age..." STATUS=$(curl 'http://localhost:9966/instances/test/private/orders?max_age=3600000' \ + -H "Authorization: Bearer $TOKEN_TEST" \ -H 'Accept: application/pdf' \ -w "%{http_code}" \ -s \ @@ -285,6 +290,7 @@ fi echo -n "Checking order status before claiming it..." STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -307,6 +313,7 @@ NOW2=$(date +%s) echo " OK (took $(( NOW2 - NOW )) secs)" STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -371,6 +378,7 @@ echo -n "Notifying merchant of correct wire transfer, but on wrong instance..." #issue 6912 #here we are notifying the transfer into a wrong instance (admin) and the payto_uri of the admin instance STATUS=$(curl 'http://localhost:9966/private/transfers' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d "{\"credit_amount\":\"$CREDIT_AMOUNT\",\"wtid\":\"$WTID\",\"payto_uri\":\"$TOR_PAYTO\",\"exchange_url\":\"$WURL\"}" \ -m 3 \ -w "%{http_code}" \ @@ -388,6 +396,7 @@ echo " OK" echo -n "Fetching wire transfers of ADMIN instance ..." STATUS=$(curl 'http://localhost:9966/private/transfers' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" \ -s \ -o "$LAST_RESPONSE") @@ -418,6 +427,7 @@ echo "OK" echo -n "Fetching wire transfers of 'test' instance ..." STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" \ -s \ -o "$LAST_RESPONSE") @@ -440,6 +450,7 @@ echo "OK" echo -n "Checking order status ..." STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}?transfer=YES" \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -488,6 +499,7 @@ echo "OK" echo -n "Fetching wire transfers of TEST instance ..." STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" \ -s \ -o "$LAST_RESPONSE") @@ -510,6 +522,7 @@ echo "OK" echo -n "Checking order status ..." STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -530,6 +543,7 @@ echo " OK" echo -n "Checking wired value and filter in order listing..." STATUS=$(curl 'http://localhost:9966/instances/test/private/orders?limit=20&wired=YES' \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then @@ -553,6 +567,7 @@ echo "================== 2nd order ====================== " # CREATE ORDER AND SELL IT echo -n "Creating 2nd order to be paid..." STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \ + -H "Authorization: Bearer $TOKEN_TEST" \ -d '{"refund_delay":{"d_us":0}, "order":{"amount":"TESTKUDOS:2","summary":"payme"}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -566,6 +581,7 @@ ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") #TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -588,6 +604,7 @@ NOW2=$(date +%s) echo " OK (took $(( NOW2 - NOW )) secs)" STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -690,6 +707,7 @@ echo "OK" echo -n "Fetching wire transfers of TEST instance ..." STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" \ -s \ -o "$LAST_RESPONSE") @@ -712,6 +730,7 @@ echo "OK" echo -n "Checking order status ..." STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -735,6 +754,7 @@ echo "================== 3rd order ====================== " # CREATE ORDER AND SELL IT echo -n "Creating 3rd order to be paid..." STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \ + -H "Authorization: Bearer $TOKEN_TEST" \ -d '{"refund_delay":{"d_us":0}, "order":{"amount":"TESTKUDOS:3","summary":"payme"}}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") @@ -748,6 +768,7 @@ ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") #TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -770,6 +791,7 @@ NOW2=$(date +%s) echo " OK (took $(( NOW2 - NOW )) secs)" STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -830,6 +852,7 @@ echo " DONE" echo -n "Fetching wire transfers of TEST instance ..." STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" \ -s \ -o "$LAST_RESPONSE") @@ -860,6 +883,7 @@ echo "OK" echo -n "Checking order status ..." STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -882,6 +906,7 @@ echo " OK" echo -n "Checking reconciliation details ..." STATUS=$(curl "http://localhost:9966/instances/test/private/incoming/${EXPECTED_TRANSFER_SERIAL}" \ + -H "Authorization: Bearer $TOKEN_TEST" \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -907,6 +932,7 @@ then echo -n "Fetch order list as PDF..." STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \ + -H "Authorization: Bearer $TOKEN_TEST" \ -H "Accept: application/pdf" \ -w "%{http_code}" \ -s \ @@ -926,6 +952,7 @@ fi echo -n "Fetch order list as CSV..." STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \ + -H "Authorization: Bearer $TOKEN_TEST" \ -H "Accept: text/csv" \ -w "%{http_code}" \ -s \ @@ -942,6 +969,7 @@ echo "OK" echo -n "Fetch order list as XLS..." STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \ + -H "Authorization: Bearer $TOKEN_TEST" \ -H "Accept: application/vnd.ms-excel" \ -w "%{http_code}" \ -s \ diff --git a/src/testing/test_merchant_wirewatch.sh b/src/testing/test_merchant_wirewatch.sh @@ -214,20 +214,20 @@ else GNUNET_PAYTO=$(get_payto_uri gnunet x) fi STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ + -d '{"auth":{"method":"token","password":"super_secret"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then exit_fail "Expected 204 no content. Got: $STATUS" fi +ADMIN_TOKEN=$(merchant_login admin super_secret) echo "OK" echo -n "Configuring bank account..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ http://localhost:9966/private/accounts \ -d '{"payto_uri":"'"$GNUNET_PAYTO"'","credit_facade_url":"'"${FACADE_URL}"'","credit_facade_credentials":{"type":"basic","username":"'"$FACADE_USERNAME"'","password":"'"$FACADE_PASSWORD"'"}}' \ -w "%{http_code}" -s -o /dev/null) @@ -242,6 +242,7 @@ echo "OK" # CREATE ORDER AND SELL IT echo -n "Creating order to be paid..." STATUS=$(curl 'http://localhost:9966/private/orders' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{"refund_delay":{"d_us":0},"order":{"amount":"TESTKUDOS:1","summary":"payme"}}' \ -w "%{http_code}" \ -s \ @@ -254,6 +255,7 @@ fi ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" \ -s \ -o "$LAST_RESPONSE") @@ -276,6 +278,7 @@ NOW2=$(date +%s) echo "OK. Took $(( NOW2 - NOW))s." STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" \ -s \ -o "$LAST_RESPONSE") @@ -350,6 +353,7 @@ echo " OK" echo -n "Fetching wire transfers of ADMIN instance ..." STATUS=$(curl 'http://localhost:9966/private/transfers' \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" \ -s \ -o "$LAST_RESPONSE") @@ -373,6 +377,7 @@ echo " OK" echo -n "Checking order status ..." STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}?transfer=YES" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ -w "%{http_code}" \ -s \ -o "$LAST_RESPONSE") diff --git a/src/testing/test_reconciliation.c b/src/testing/test_reconciliation.c @@ -66,6 +66,11 @@ static char *config_file; #define EXCHANGE_URL "http://localhost:8081/" /** + * Password of the merchant instances the test creates. + */ +#define INSTANCE_PASSWORD "instance-password" + +/** * Payto URI of the customer (payer). */ static struct TALER_FullPayto payer_payto; @@ -293,11 +298,17 @@ run (void *cls, merchant_url, MHD_HTTP_OK, NULL), - TALER_TESTING_cmd_merchant_post_instances ( + TALER_TESTING_cmd_merchant_post_instances_with_password ( "instance-create-default-setup", merchant_url, "admin", + INSTANCE_PASSWORD, MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_login ( + "login-admin", + merchant_url, + "admin", + INSTANCE_PASSWORD), // FIXME: setup full account for taler-merchant-wirewatch TALER_TESTING_cmd_merchant_post_account ( "instance-create-default-account", @@ -305,10 +316,11 @@ run (void *cls, merchant_payto, NULL, NULL, MHD_HTTP_OK), - TALER_TESTING_cmd_merchant_post_instances ( + TALER_TESTING_cmd_merchant_post_instances_with_password ( "instance-create-i1", merchant_url, "i1", + INSTANCE_PASSWORD, MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_batch ("pay", pay), diff --git a/src/testing/test_sms_helper.sh b/src/testing/test_sms_helper.sh @@ -1,5 +1,5 @@ #!/bin/sh # This file is in the public domain. -echo "$1" > /tmp/test-merchant-sms-address.txt -cat - > /tmp/test-merchant-sms-tan.txt +echo "$1" > "${TALER_MERCHANT_TEST_TAN_DIR:-/tmp}"/test-merchant-sms-address.txt +cat - > "${TALER_MERCHANT_TEST_TAN_DIR:-/tmp}"/test-merchant-sms-tan.txt exit 0 diff --git a/src/testing/test_template.conf b/src/testing/test_template.conf @@ -37,6 +37,7 @@ BINARY = taler-merchant-report-generator-file [merchant] SERVE = tcp PORT = 9966 +STRICT_PROTOCOL_V19 = YES PAYMENT_TARGET_TYPES = * CURRENCY = TESTKUDOS BASE_URL = http://localhost:9966/ diff --git a/src/testing/testing_api_cmd_instance_token.c b/src/testing/testing_api_cmd_instance_token.c @@ -428,4 +428,171 @@ TALER_TESTING_cmd_merchant_post_instance_token (const char *label, } +/** + * State of a login batch, owned by its last command. + */ +struct LoginState +{ + /** + * "Basic" authorization header value with the instance password. + */ + char *basic_auth; + + /** + * Label of the command that sets @e basic_auth. + */ + char *set_basic_label; + + /** + * Label of the command that requests the login token. + */ + char *token_label; + + /** + * Label of the command that drops the Authorization header. + */ + char *unset_label; + + /** + * Label of the command that installs the login token. + */ + char *set_token_label; + + /** + * State of the command that requests the login token. Referenced + * directly: commands in nested batches cannot be found by label. + */ + const struct TokenInstanceState *tis; +}; + + +/** + * Send the login token with all further requests. + * + * @param cls a `struct LoginState` + * @param cmd command being run now + * @param is interpreter state + */ +static void +login_set_token_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + const struct LoginState *ls = cls; + struct GNUNET_CURL_Context *cctx; + char *authorization; + + (void) cmd; + if (NULL == ls->tis->token) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + cctx = TALER_TESTING_interpreter_get_context (is); + GNUNET_assert (NULL != cctx); + GNUNET_asprintf (&authorization, + "%s: Bearer %s", + MHD_HTTP_HEADER_AUTHORIZATION, + ls->tis->token); + GNUNET_assert (GNUNET_OK == + GNUNET_CURL_append_header (cctx, + authorization)); + GNUNET_free (authorization); + TALER_TESTING_interpreter_next (is); +} + + +/** + * Free the state of a login batch. + * + * @param cls a `struct LoginState` + * @param cmd command being cleaned up + */ +static void +login_set_token_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct LoginState *ls = cls; + + (void) cmd; + GNUNET_free (ls->basic_auth); + GNUNET_free (ls->set_basic_label); + GNUNET_free (ls->token_label); + GNUNET_free (ls->unset_label); + GNUNET_free (ls->set_token_label); + GNUNET_free (ls); +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_login (const char *label, + const char *merchant_url, + const char *instance_id, + const char *password) +{ + struct LoginState *ls; + struct TALER_TESTING_Command token_cmd; + + ls = GNUNET_new (struct LoginState); + { + char *userpass; + char *b64; + + GNUNET_asprintf (&userpass, + "%s:%s", + instance_id, + password); + GNUNET_STRINGS_base64_encode (userpass, + strlen (userpass), + &b64); + GNUNET_asprintf (&ls->basic_auth, + "Basic %s", + b64); + GNUNET_free (b64); + GNUNET_free (userpass); + } + GNUNET_asprintf (&ls->set_basic_label, + "%s-set-basic-auth", + label); + GNUNET_asprintf (&ls->token_label, + "%s-token", + label); + GNUNET_asprintf (&ls->unset_label, + "%s-unset-basic-auth", + label); + GNUNET_asprintf (&ls->set_token_label, + "%s-set-token", + label); + token_cmd = TALER_TESTING_cmd_merchant_post_instance_token ( + ls->token_label, + merchant_url, + instance_id, + "all", + GNUNET_TIME_UNIT_DAYS, + false, + MHD_HTTP_OK); + ls->tis = token_cmd.cls; + { + struct TALER_TESTING_Command batch[] = { + TALER_TESTING_cmd_set_authorization (ls->set_basic_label, + ls->basic_auth), + token_cmd, + TALER_TESTING_cmd_set_authorization (ls->unset_label, + NULL), + { + .cls = ls, + .label = ls->set_token_label, + .run = &login_set_token_run, + .cleanup = &login_set_token_cleanup + }, + TALER_TESTING_cmd_end () + }; + + return TALER_TESTING_cmd_batch (label, + batch); + } +} + + /* end of testing_api_cmd_token_instance.c */ diff --git a/src/testing/testing_api_cmd_post_instances.c b/src/testing/testing_api_cmd_post_instances.c @@ -323,4 +323,28 @@ TALER_TESTING_cmd_merchant_post_instances ( } +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_post_instances_with_password ( + const char *label, + const char *merchant_url, + const char *instance_id, + const char *password, + unsigned int http_status) +{ + return TALER_TESTING_cmd_merchant_post_instances2 ( + label, + merchant_url, + instance_id, + instance_id, + json_pack ("{s:s}", "city", "shopcity"), + json_pack ("{s:s}", "city", "lawyercity"), + true, + GNUNET_TIME_UNIT_ZERO, /* no wire transfer delay */ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, + 2), /* small pay delay */ + password, + http_status); +} + + /* end of testing_api_cmd_post_instance.c */