/** * This file is part of TALER * Copyright (C) 2014-2018 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 exchange/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 "taler_merchant_testing_lib.h" #include #include /** * Configuration file we use. One (big) configuration is used * for the various components for this test. */ #define CONFIG_FILE "test_merchant_api_twisted.conf" /** * 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" #define PAYTO_I1 "payto://x-taler-bank/localhost/3" /** * 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 char *merchant_url; /** * Merchant process. */ static struct GNUNET_OS_Process *merchantd; /** * 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 char *payer_payto; static char *exchange_payto; static char *merchant_payto; static struct TALER_TESTING_BankConfiguration bc; static struct TALER_TESTING_ExchangeConfiguration ec; /** * 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, &bc.exchange_auth, 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", 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", twister_merchant_url, MHD_HTTP_OK, "abort-one", GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_FOREVER_ABS, "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_NOT_ACCEPTABLE, "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", twister_merchant_url, MHD_HTTP_OK, "DS-1", GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_FOREVER_ABS, "EUR:1.0"), TALER_TESTING_cmd_merchant_post_orders ("create-proposal-double-spend-1", twister_merchant_url, MHD_HTTP_OK, "DS-2", GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_FOREVER_ABS, "EUR:3.0"), TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-double-spend", "create-reserve-double-spend", "EUR:1", 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[] = { TALER_TESTING_cmd_merchant_post_instances ("instance-create-default", twister_merchant_url, "default", PAYTO_I1, "EUR", MHD_HTTP_NO_CONTENT), 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", MHD_HTTP_OK), TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2", "create-reserve-1", "EUR:5", MHD_HTTP_OK), TALER_TESTING_cmd_merchant_post_orders_no_claim ( "create-proposal-1", merchant_url, MHD_HTTP_OK, "1", GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_FOREVER_ABS, "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", merchant_url, MHD_HTTP_OK, "2", GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_FOREVER_ABS, "EUR:6.0"), TALER_TESTING_cmd_merchant_pay_order ("deposit-2", merchant_url, MHD_HTTP_NOT_ACCEPTABLE, "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_INTERNAL_SERVER_ERROR), TALER_TESTING_cmd_end () }; TALER_TESTING_run_with_fakebank (is, commands, bc.exchange_auth.wire_gateway_url); } /** * 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) { unsigned int ret; /* These environment variables get in the way... */ unsetenv ("XDG_DATA_HOME"); unsetenv ("XDG_CONFIG_HOME"); GNUNET_log_setup ("test-merchant-api-twisted", "DEBUG", NULL); if (GNUNET_OK != TALER_TESTING_prepare_fakebank (CONFIG_FILE, "exchange-account-exchange", &bc)) return 77; payer_payto = ("payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME); exchange_payto = ("payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME); merchant_payto = ("payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME); if (NULL == (merchant_url = TALER_TESTING_prepare_merchant (CONFIG_FILE))) return 77; 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); TALER_TESTING_cleanup_files (CONFIG_FILE); switch (TALER_TESTING_prepare_exchange (CONFIG_FILE, GNUNET_YES, &ec)) { case GNUNET_SYSERR: GNUNET_break (0); return 1; case GNUNET_NO: return 77; case GNUNET_OK: if (NULL == (merchantd = TALER_TESTING_run_merchant (CONFIG_FILE, merchant_url))) // 1 is fine; after all this is merchant test cases. return 1; 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; /* Run the exchange and schedule 'run()' */ ret = TALER_TESTING_setup_with_exchange (&run, NULL, CONFIG_FILE); purge_process (merchantd); purge_process (twisterexchanged); purge_process (twistermerchantd); GNUNET_free (merchant_url); GNUNET_free (twister_exchange_url); GNUNET_free (twister_merchant_url); if (GNUNET_OK != ret) return 1; break; default: GNUNET_break (0); return 1; } return 0; } /* end of test_merchant_api_twisted.c */