/** * This file is part of TALER * Copyright (C) 2014-2023 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 * */ /** * @file test_merchant_api_twisted.c * @brief testcase to test exchange's HTTP API interface * @author Sree Harsha Totakura * @author Christian Grothoff * @author Marcello Stanisci * @author Florian Dold */ #include "platform.h" #include #include #include #include #include #include #include #include #include #include #include "taler_merchant_testing_lib.h" #include #include /** * Configuration file we use. One (big) configuration is used * for the various components for this test. */ static char *config_file; /** * Account number of the exchange at the bank. */ #define EXCHANGE_ACCOUNT_NAME "2" /** * Account number of the merchant at the bank. */ #define MERCHANT_ACCOUNT_NAME "3" /** * Account number of some user. */ #define USER_ACCOUNT_NAME "62" /** * Configuration file for the proxy between merchant and * exchange. Not used directly here in the code (instead * used in the merchant config), but kept around for consistency. */ #define PROXY_EXCHANGE_config_file \ "test_merchant_api_proxy_exchange.conf" /** * Configuration file for the proxy between "lib" and merchant. */ #define PROXY_MERCHANT_config_file \ "test_merchant_api_proxy_merchant.conf" /** * Exchange base URL. Could also be taken from config. */ #define EXCHANGE_URL "http://localhost:8081/" /** * Twister URL that proxies the exchange. */ static char *twister_exchange_url; /** * Twister URL that proxies the merchant. */ static char *twister_merchant_url; /** * Twister URL that proxies the merchant. */ static char *twister_merchant_url_instance_nonexistent; /** * Twister URL that proxies the merchant. */ static char *twister_merchant_url_instance_tor; /** * Merchant base URL. */ static const char *merchant_url; /** * Twister process that proxies the exchange. */ static struct GNUNET_OS_Process *twisterexchanged; /** * Twister process that proxies the merchant. */ static struct GNUNET_OS_Process *twistermerchantd; static struct TALER_FullPayto payer_payto; static struct TALER_FullPayto exchange_payto; static struct TALER_FullPayto merchant_payto; static struct TALER_TESTING_Credentials cred; /** * User name. Never checked by fakebank. */ #define USER_LOGIN_NAME "user42" /** * User password. Never checked by fakebank. */ #define USER_LOGIN_PASS "pass42" /** * Execute the taler-exchange-wirewatch command with * our configuration file. * * @param label label to use for the command. */ static struct TALER_TESTING_Command CMD_EXEC_WIREWATCH (const char *label) { return TALER_TESTING_cmd_exec_wirewatch (label, config_file); } /** * Execute the taler-exchange-aggregator, closer and transfer commands with * our configuration file. * * @param label label to use for the command. */ #define CMD_EXEC_AGGREGATOR(label) \ TALER_TESTING_cmd_exec_aggregator (label "-aggregator", config_file), \ TALER_TESTING_cmd_exec_transfer (label "-transfer", config_file) /** * Run wire transfer of funds from some user's account to the * exchange. * * @param label label to use for the command. * @param amount amount to transfer, i.e. "EUR:1" * @param url exchange_url */ static struct TALER_TESTING_Command CMD_TRANSFER_TO_EXCHANGE (const char *label, const char *amount) { return TALER_TESTING_cmd_admin_add_incoming (label, amount, &cred.ba, payer_payto); } /** * Main function that will tell the interpreter what commands to * run. * * @param cls closure */ static void run (void *cls, struct TALER_TESTING_Interpreter *is) { /****** Covering /pay *******/ struct TALER_TESTING_Command pay[] = { /** * Move money to the exchange's bank account. */ CMD_TRANSFER_TO_EXCHANGE ("create-reserve-abort-1", "EUR:1.01"), /** * Make a reserve exist, according to the previous transfer. */ CMD_EXEC_WIREWATCH ("wirewatch-abort-1"), TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-abort-1", "EUR:1.01", payer_payto, exchange_payto, "create-reserve-abort-1"), TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-abort-1", "create-reserve-abort-1", "EUR:1", 0, MHD_HTTP_OK), TALER_TESTING_cmd_status ("withdraw-status-abort-1", "create-reserve-abort-1", "EUR:0", MHD_HTTP_OK), TALER_TESTING_cmd_merchant_post_orders ("create-proposal-abort-1", cred.cfg, twister_merchant_url, MHD_HTTP_OK, "abort-one", GNUNET_TIME_UNIT_ZERO_TS, GNUNET_TIME_UNIT_FOREVER_TS, "EUR:3.0"), /* Will only pay _half_ the supposed price, * so we'll then have the right to abort. */ TALER_TESTING_cmd_merchant_pay_order ("deposit-simple-for-abort", twister_merchant_url, MHD_HTTP_BAD_REQUEST, "create-proposal-abort-1", "withdraw-coin-abort-1", "EUR:1.01", "EUR:1.00", NULL), // no sense now TALER_TESTING_cmd_delete_object ("hack-abort-1", PROXY_MERCHANT_config_file, "merchant_pub"), TALER_TESTING_cmd_merchant_order_abort ("pay-abort-1", twister_merchant_url, "deposit-simple-for-abort", MHD_HTTP_OK), TALER_TESTING_cmd_delete_object ("hack-abort-2", PROXY_MERCHANT_config_file, "refund_permissions.0.rtransaction_id"), TALER_TESTING_cmd_merchant_order_abort ("pay-abort-2", twister_merchant_url, "deposit-simple-for-abort", MHD_HTTP_OK), TALER_TESTING_cmd_modify_object_dl ("hack-abort-3", PROXY_MERCHANT_config_file, "refund_permissions.0.coin_pub", /* dummy coin. */ "8YX10E41ZWHX0X2RK4XFAXB2D3M05M1HNG14ZFZZB8M7SA4QCKCG"), TALER_TESTING_cmd_merchant_order_abort ("pay-abort-3", twister_merchant_url, "deposit-simple-for-abort", MHD_HTTP_OK), TALER_TESTING_cmd_flip_download ("hack-abort-4", PROXY_MERCHANT_config_file, "refund_permissions.0.merchant_sig"), TALER_TESTING_cmd_merchant_order_abort ("pay-abort-4", twister_merchant_url, "deposit-simple-for-abort", MHD_HTTP_OK), /* just malforming the response. */ TALER_TESTING_cmd_malform_response ("malform-abortion", PROXY_MERCHANT_config_file), TALER_TESTING_cmd_merchant_order_abort ("pay-abort-5", twister_merchant_url, "deposit-simple-for-abort", 0), CMD_TRANSFER_TO_EXCHANGE ("create-reserve-double-spend", "EUR:1.01"), CMD_EXEC_WIREWATCH ("wirewatch-double-spend"), TALER_TESTING_cmd_merchant_post_orders ("create-proposal-double-spend", cred.cfg, twister_merchant_url, MHD_HTTP_OK, "DS-1", GNUNET_TIME_UNIT_ZERO_TS, GNUNET_TIME_UNIT_FOREVER_TS, "EUR:1.0"), TALER_TESTING_cmd_merchant_post_orders ("create-proposal-double-spend-1", cred.cfg, twister_merchant_url, MHD_HTTP_OK, "DS-2", GNUNET_TIME_UNIT_ZERO_TS, GNUNET_TIME_UNIT_FOREVER_TS, "EUR:3.0"), TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-double-spend", "create-reserve-double-spend", "EUR:1", 0, MHD_HTTP_OK), TALER_TESTING_cmd_merchant_pay_order ("deposit-simple-ok", twister_merchant_url, MHD_HTTP_OK, "create-proposal-double-spend", "withdraw-coin-double-spend", "EUR:1.01", "EUR:1.00", NULL), // no sense now TALER_TESTING_cmd_flip_download ("hack-coin-history", PROXY_MERCHANT_config_file, "history.0.coin_sig"), /* Coin history check will fail, * due to coin's bad signature. */ TALER_TESTING_cmd_merchant_pay_order ("deposit-simple-fail", twister_merchant_url, MHD_HTTP_CONFLICT, "create-proposal-double-spend-1", "withdraw-coin-double-spend", "EUR:1.01", "EUR:1.00", NULL), // no sense now /* max uint64 number: 9223372036854775807; try to overflow! */ TALER_TESTING_cmd_end () }; struct TALER_TESTING_Command commands[] = { /* general setup */ TALER_TESTING_cmd_run_fakebank ("run-fakebank", cred.cfg, "exchange-account-exchange"), TALER_TESTING_cmd_system_start ("start-taler", config_file, "-ema", "-u", "exchange-account-exchange", NULL), TALER_TESTING_cmd_get_exchange ("get-exchange", cred.cfg, NULL, true, true), TALER_TESTING_cmd_merchant_post_instances ("instance-create-default", twister_merchant_url, "default", MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_post_account ( "instance-create-default-account", twister_merchant_url, merchant_payto, NULL, NULL, MHD_HTTP_OK), TALER_TESTING_cmd_batch ("pay", pay), /* Malform the response from the exchange. */ /** * Move money to the exchange's bank account. */ CMD_TRANSFER_TO_EXCHANGE ("create-reserve-1", "EUR:10.02"), /** * Make a reserve exist, * according to the previous * transfer. */ CMD_EXEC_WIREWATCH ("wirewatch-1"), TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-2", "EUR:10.02", payer_payto, exchange_payto, "create-reserve-1"), TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1", "create-reserve-1", "EUR:5", 0, MHD_HTTP_OK), TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2", "create-reserve-1", "EUR:5", 0, MHD_HTTP_OK), TALER_TESTING_cmd_merchant_post_orders_no_claim ( "create-proposal-1", merchant_url, MHD_HTTP_OK, "1", GNUNET_TIME_UNIT_ZERO_TS, GNUNET_TIME_UNIT_FOREVER_TS, "EUR:6.0"), TALER_TESTING_cmd_flip_upload ("hack-claim-token", PROXY_MERCHANT_config_file, "token"), TALER_TESTING_cmd_merchant_claim_order ( "claim-1-incorrect-claim-token", twister_merchant_url, MHD_HTTP_NOT_FOUND, "create-proposal-1", NULL), TALER_TESTING_cmd_merchant_post_orders ("create-proposal-2", cred.cfg, merchant_url, MHD_HTTP_OK, "2", GNUNET_TIME_UNIT_ZERO_TS, GNUNET_TIME_UNIT_FOREVER_TS, "EUR:6.0"), TALER_TESTING_cmd_merchant_pay_order ("deposit-2", merchant_url, MHD_HTTP_BAD_REQUEST, "create-proposal-2", "withdraw-coin-1", "EUR:5", "EUR:4.99", NULL), TALER_TESTING_cmd_malform_response ("malform-abort-merchant-exchange", PROXY_EXCHANGE_config_file), TALER_TESTING_cmd_merchant_order_abort ("pay-abort-1", merchant_url, "deposit-2", MHD_HTTP_BAD_GATEWAY), TALER_TESTING_cmd_end () }; TALER_TESTING_run (is, commands); } /** * Kill, wait, and destroy convenience function. * * @param process process to purge. */ static void purge_process (struct GNUNET_OS_Process *process) { GNUNET_OS_process_kill (process, SIGINT); GNUNET_OS_process_wait (process); GNUNET_OS_process_destroy (process); } int main (int argc, char *const *argv) { int ret; { char *cipher; cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]); GNUNET_assert (NULL != cipher); GNUNET_asprintf (&config_file, "test_merchant_api_twisted-%s.conf", cipher); GNUNET_free (cipher); } payer_payto.full_payto = (char *) "payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME "?receiver-name=" USER_ACCOUNT_NAME; exchange_payto.full_payto = (char *) "payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME "?receiver-name=" EXCHANGE_ACCOUNT_NAME; merchant_payto.full_payto = (char *) "payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME "?receiver-name=" MERCHANT_ACCOUNT_NAME; merchant_url = "http://localhost:8080/"; if (NULL == (twister_exchange_url = TALER_TWISTER_prepare_twister ( PROXY_EXCHANGE_config_file))) return 77; if (NULL == (twister_merchant_url = TALER_TWISTER_prepare_twister ( PROXY_MERCHANT_config_file))) return 77; twister_merchant_url_instance_nonexistent = TALER_url_join ( twister_merchant_url, "instances/foo/", NULL); twister_merchant_url_instance_tor = TALER_url_join ( twister_merchant_url, "instances/tor/", NULL); if (NULL == (twisterexchanged = TALER_TWISTER_run_twister (PROXY_EXCHANGE_config_file))) return 77; if (NULL == (twistermerchantd = TALER_TWISTER_run_twister (PROXY_MERCHANT_config_file))) return 77; ret = TALER_TESTING_main (argv, "INFO", config_file, "exchange-account-exchange", TALER_TESTING_BS_FAKEBANK, &cred, &run, NULL); purge_process (twisterexchanged); purge_process (twistermerchantd); return ret; } /* end of test_merchant_api_twisted.c */