test_merchant_api_twisted.c (18923B)
1 /** 2 * This file is part of TALER 3 * Copyright (C) 2014-2023 Taler Systems SA 4 * 5 * TALER is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 3, or 8 * (at your option) any later version. 9 * 10 * TALER is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public 16 * License along with TALER; see the file COPYING. If not, see 17 * <http://www.gnu.org/licenses/> 18 */ 19 /** 20 * @file test_merchant_api_twisted.c 21 * @brief testcase to test exchange's HTTP API interface 22 * @author Sree Harsha Totakura <sreeharsha@totakura.in> 23 * @author Christian Grothoff 24 * @author Marcello Stanisci 25 * @author Florian Dold <dold@taler.net> 26 */ 27 28 #include "platform.h" 29 #include <taler/taler_util.h> 30 #include <taler/taler_signatures.h> 31 #include <taler/taler_exchange_service.h> 32 #include <taler/taler_json_lib.h> 33 #include <gnunet/gnunet_util_lib.h> 34 #include <gnunet/gnunet_testing_lib.h> 35 #include <microhttpd.h> 36 #include <taler/taler_bank_service.h> 37 #include <taler/taler_fakebank_lib.h> 38 #include <taler/taler_testing_lib.h> 39 #include "taler_merchant_testing_lib.h" 40 #include <taler/taler_twister_testing_lib.h> 41 #include <taler/taler_twister_service.h> 42 43 /** 44 * Configuration file we use. One (big) configuration is used 45 * for the various components for this test. 46 */ 47 static char *config_file; 48 49 /** 50 * Account number of the exchange at the bank. 51 */ 52 #define EXCHANGE_ACCOUNT_NAME "2" 53 54 /** 55 * Account number of the merchant at the bank. 56 */ 57 #define MERCHANT_ACCOUNT_NAME "3" 58 59 /** 60 * Account number of some user. 61 */ 62 #define USER_ACCOUNT_NAME "62" 63 64 /** 65 * Configuration file for the proxy between merchant and 66 * exchange. Not used directly here in the code (instead 67 * used in the merchant config), but kept around for consistency. 68 */ 69 #define PROXY_EXCHANGE_config_file \ 70 "test_merchant_api_proxy_exchange.conf" 71 72 /** 73 * Configuration file for the proxy between "lib" and merchant. 74 */ 75 #define PROXY_MERCHANT_config_file \ 76 "test_merchant_api_proxy_merchant.conf" 77 78 /** 79 * Exchange base URL. Could also be taken from config. 80 */ 81 #define EXCHANGE_URL "http://localhost:8081/" 82 83 /** 84 * Twister URL that proxies the exchange. 85 */ 86 static char *twister_exchange_url; 87 88 /** 89 * Twister URL that proxies the merchant. 90 */ 91 static char *twister_merchant_url; 92 93 /** 94 * Twister URL that proxies the merchant. 95 */ 96 static char *twister_merchant_url_instance_nonexistent; 97 98 /** 99 * Twister URL that proxies the merchant. 100 */ 101 static char *twister_merchant_url_instance_tor; 102 103 /** 104 * Merchant base URL. 105 */ 106 static const char *merchant_url; 107 108 /** 109 * Twister process that proxies the exchange. 110 */ 111 static struct GNUNET_OS_Process *twisterexchanged; 112 113 /** 114 * Twister process that proxies the merchant. 115 */ 116 static struct GNUNET_OS_Process *twistermerchantd; 117 118 static struct TALER_FullPayto payer_payto; 119 static struct TALER_FullPayto exchange_payto; 120 static struct TALER_FullPayto merchant_payto; 121 122 static struct TALER_TESTING_Credentials cred; 123 124 /** 125 * User name. Never checked by fakebank. 126 */ 127 #define USER_LOGIN_NAME "user42" 128 129 /** 130 * User password. Never checked by fakebank. 131 */ 132 #define USER_LOGIN_PASS "pass42" 133 134 /** 135 * Execute the taler-exchange-wirewatch command with 136 * our configuration file. 137 * 138 * @param label label to use for the command. 139 */ 140 static struct TALER_TESTING_Command 141 CMD_EXEC_WIREWATCH (const char *label) 142 { 143 return TALER_TESTING_cmd_exec_wirewatch (label, config_file); 144 } 145 146 147 /** 148 * Execute the taler-exchange-aggregator, closer and transfer commands with 149 * our configuration file. 150 * 151 * @param label label to use for the command. 152 */ 153 #define CMD_EXEC_AGGREGATOR(label) \ 154 TALER_TESTING_cmd_exec_aggregator (label "-aggregator", config_file), \ 155 TALER_TESTING_cmd_exec_transfer (label "-transfer", config_file) 156 157 158 /** 159 * Run wire transfer of funds from some user's account to the 160 * exchange. 161 * 162 * @param label label to use for the command. 163 * @param amount amount to transfer, i.e. "EUR:1" 164 * @param url exchange_url 165 */ 166 static struct TALER_TESTING_Command 167 CMD_TRANSFER_TO_EXCHANGE (const char *label, 168 const char *amount) 169 { 170 return TALER_TESTING_cmd_admin_add_incoming (label, 171 amount, 172 &cred.ba, 173 payer_payto); 174 } 175 176 177 /** 178 * Main function that will tell the interpreter what commands to 179 * run. 180 * 181 * @param cls closure 182 */ 183 static void 184 run (void *cls, 185 struct TALER_TESTING_Interpreter *is) 186 { 187 /****** Covering /pay *******/ 188 struct TALER_TESTING_Command pay[] = { 189 /** 190 * Move money to the exchange's bank account. 191 */ 192 CMD_TRANSFER_TO_EXCHANGE ("create-reserve-abort-1", 193 "EUR:1.01"), 194 195 /** 196 * Make a reserve exist, according to the previous transfer. 197 */ 198 CMD_EXEC_WIREWATCH ("wirewatch-abort-1"), 199 TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-abort-1", 200 "EUR:1.01", 201 payer_payto, 202 exchange_payto, 203 "create-reserve-abort-1"), 204 TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-abort-1", 205 "create-reserve-abort-1", 206 "EUR:1", 207 0, 208 MHD_HTTP_OK), 209 TALER_TESTING_cmd_status ("withdraw-status-abort-1", 210 "create-reserve-abort-1", 211 "EUR:0", 212 MHD_HTTP_OK), 213 TALER_TESTING_cmd_merchant_post_orders ("create-proposal-abort-1", 214 cred.cfg, 215 twister_merchant_url, 216 MHD_HTTP_OK, 217 "abort-one", 218 GNUNET_TIME_UNIT_ZERO_TS, 219 GNUNET_TIME_UNIT_FOREVER_TS, 220 "EUR:3.0"), 221 /* Will only pay _half_ the supposed price, 222 * so we'll then have the right to abort. */ 223 TALER_TESTING_cmd_merchant_pay_order ("deposit-simple-for-abort", 224 twister_merchant_url, 225 MHD_HTTP_BAD_REQUEST, 226 "create-proposal-abort-1", 227 "withdraw-coin-abort-1", 228 "EUR:1.01", 229 "EUR:1.00", 230 NULL), // no sense now 231 TALER_TESTING_cmd_delete_object ("hack-abort-1", 232 PROXY_MERCHANT_config_file, 233 "merchant_pub"), 234 TALER_TESTING_cmd_merchant_order_abort ("pay-abort-1", 235 twister_merchant_url, 236 "deposit-simple-for-abort", 237 MHD_HTTP_OK), 238 TALER_TESTING_cmd_delete_object ("hack-abort-2", 239 PROXY_MERCHANT_config_file, 240 "refund_permissions.0.rtransaction_id"), 241 TALER_TESTING_cmd_merchant_order_abort ("pay-abort-2", 242 twister_merchant_url, 243 "deposit-simple-for-abort", 244 MHD_HTTP_OK), 245 TALER_TESTING_cmd_modify_object_dl ("hack-abort-3", 246 PROXY_MERCHANT_config_file, 247 "refund_permissions.0.coin_pub", 248 /* dummy coin. */ 249 "8YX10E41ZWHX0X2RK4XFAXB2D3M05M1HNG14ZFZZB8M7SA4QCKCG"), 250 TALER_TESTING_cmd_merchant_order_abort ("pay-abort-3", 251 twister_merchant_url, 252 "deposit-simple-for-abort", 253 MHD_HTTP_OK), 254 TALER_TESTING_cmd_flip_download ("hack-abort-4", 255 PROXY_MERCHANT_config_file, 256 "refund_permissions.0.merchant_sig"), 257 TALER_TESTING_cmd_merchant_order_abort ("pay-abort-4", 258 twister_merchant_url, 259 "deposit-simple-for-abort", 260 MHD_HTTP_OK), 261 /* just malforming the response. */ 262 TALER_TESTING_cmd_malform_response ("malform-abortion", 263 PROXY_MERCHANT_config_file), 264 TALER_TESTING_cmd_merchant_order_abort ("pay-abort-5", 265 twister_merchant_url, 266 "deposit-simple-for-abort", 267 0), 268 CMD_TRANSFER_TO_EXCHANGE ("create-reserve-double-spend", 269 "EUR:1.01"), 270 CMD_EXEC_WIREWATCH ("wirewatch-double-spend"), 271 TALER_TESTING_cmd_merchant_post_orders ("create-proposal-double-spend", 272 cred.cfg, 273 twister_merchant_url, 274 MHD_HTTP_OK, 275 "DS-1", 276 GNUNET_TIME_UNIT_ZERO_TS, 277 GNUNET_TIME_UNIT_FOREVER_TS, 278 "EUR:1.0"), 279 TALER_TESTING_cmd_merchant_post_orders ("create-proposal-double-spend-1", 280 cred.cfg, 281 twister_merchant_url, 282 MHD_HTTP_OK, 283 "DS-2", 284 GNUNET_TIME_UNIT_ZERO_TS, 285 GNUNET_TIME_UNIT_FOREVER_TS, 286 "EUR:3.0"), 287 288 TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-double-spend", 289 "create-reserve-double-spend", 290 "EUR:1", 291 0, 292 MHD_HTTP_OK), 293 TALER_TESTING_cmd_merchant_pay_order ("deposit-simple-ok", 294 twister_merchant_url, 295 MHD_HTTP_OK, 296 "create-proposal-double-spend", 297 "withdraw-coin-double-spend", 298 "EUR:1.01", 299 "EUR:1.00", 300 NULL), // no sense now 301 TALER_TESTING_cmd_flip_download ("hack-coin-history", 302 PROXY_MERCHANT_config_file, 303 "history.0.coin_sig"), 304 /* Coin history check will fail, 305 * due to coin's bad signature. */ 306 TALER_TESTING_cmd_merchant_pay_order ("deposit-simple-fail", 307 twister_merchant_url, 308 MHD_HTTP_CONFLICT, 309 "create-proposal-double-spend-1", 310 "withdraw-coin-double-spend", 311 "EUR:1.01", 312 "EUR:1.00", 313 NULL), // no sense now 314 /* max uint64 number: 9223372036854775807; try to overflow! */ 315 TALER_TESTING_cmd_end () 316 }; 317 318 struct TALER_TESTING_Command commands[] = { 319 /* general setup */ 320 TALER_TESTING_cmd_run_fakebank ("run-fakebank", 321 cred.cfg, 322 "exchange-account-exchange"), 323 TALER_TESTING_cmd_system_start ("start-taler", 324 config_file, 325 "-ema", 326 "-u", "exchange-account-exchange", 327 "-r", "merchant-exchange-test", 328 NULL), 329 TALER_TESTING_cmd_get_exchange ("get-exchange", 330 cred.cfg, 331 NULL, 332 true, 333 true), 334 TALER_TESTING_cmd_merchant_post_instances ("instance-create-admin", 335 twister_merchant_url, 336 "admin", 337 MHD_HTTP_NO_CONTENT), 338 TALER_TESTING_cmd_merchant_post_account ( 339 "instance-create-default-account", 340 twister_merchant_url, 341 merchant_payto, 342 NULL, NULL, 343 MHD_HTTP_OK), 344 TALER_TESTING_cmd_batch ("pay", 345 pay), 346 /* Malform the response from the exchange. */ 347 /** 348 * Move money to the exchange's bank account. 349 */ 350 CMD_TRANSFER_TO_EXCHANGE ("create-reserve-1", 351 "EUR:10.02"), 352 /** 353 * Make a reserve exist, 354 * according to the previous 355 * transfer. 356 */ 357 CMD_EXEC_WIREWATCH ("wirewatch-1"), 358 TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-2", 359 "EUR:10.02", 360 payer_payto, 361 exchange_payto, 362 "create-reserve-1"), 363 TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1", 364 "create-reserve-1", 365 "EUR:5", 366 0, 367 MHD_HTTP_OK), 368 TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2", 369 "create-reserve-1", 370 "EUR:5", 371 0, 372 MHD_HTTP_OK), 373 374 TALER_TESTING_cmd_merchant_post_orders_no_claim ( 375 "create-proposal-1", 376 merchant_url, 377 MHD_HTTP_OK, 378 "1", 379 GNUNET_TIME_UNIT_ZERO_TS, 380 GNUNET_TIME_UNIT_FOREVER_TS, 381 "EUR:6.0"), 382 TALER_TESTING_cmd_flip_upload ("hack-claim-token", 383 PROXY_MERCHANT_config_file, 384 "token"), 385 TALER_TESTING_cmd_merchant_claim_order ( 386 "claim-1-incorrect-claim-token", 387 twister_merchant_url, 388 MHD_HTTP_NOT_FOUND, 389 "create-proposal-1", 390 NULL), 391 TALER_TESTING_cmd_merchant_post_orders ("create-proposal-2", 392 cred.cfg, 393 merchant_url, 394 MHD_HTTP_OK, 395 "2", 396 GNUNET_TIME_UNIT_ZERO_TS, 397 GNUNET_TIME_UNIT_FOREVER_TS, 398 "EUR:6.0"), 399 TALER_TESTING_cmd_merchant_pay_order ("deposit-2", 400 merchant_url, 401 MHD_HTTP_BAD_REQUEST, 402 "create-proposal-2", 403 "withdraw-coin-1", 404 "EUR:5", 405 "EUR:4.99", 406 NULL), 407 TALER_TESTING_cmd_merchant_order_abort ("pay-abort-1", 408 merchant_url, 409 "deposit-2", 410 MHD_HTTP_OK), 411 TALER_TESTING_cmd_end () 412 }; 413 414 TALER_TESTING_run (is, 415 commands); 416 } 417 418 419 /** 420 * Kill, wait, and destroy convenience function. 421 * 422 * @param process process to purge. 423 */ 424 static void 425 purge_process (struct GNUNET_OS_Process *process) 426 { 427 GNUNET_OS_process_kill (process, 428 SIGINT); 429 GNUNET_OS_process_wait (process); 430 GNUNET_OS_process_destroy (process); 431 } 432 433 434 int 435 main (int argc, 436 char *const *argv) 437 { 438 int ret; 439 440 { 441 char *cipher; 442 443 cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]); 444 GNUNET_assert (NULL != cipher); 445 GNUNET_asprintf (&config_file, 446 "test_merchant_api_twisted-%s.conf", 447 cipher); 448 GNUNET_free (cipher); 449 } 450 payer_payto.full_payto = 451 (char *) "payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME 452 "?receiver-name=" USER_ACCOUNT_NAME; 453 exchange_payto.full_payto = 454 (char *) "payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME 455 "?receiver-name=" EXCHANGE_ACCOUNT_NAME; 456 merchant_payto.full_payto = 457 (char *) "payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME 458 "?receiver-name=" MERCHANT_ACCOUNT_NAME; 459 merchant_url = "http://localhost:8080/"; 460 if (NULL == (twister_exchange_url = TALER_TWISTER_prepare_twister ( 461 PROXY_EXCHANGE_config_file))) 462 return 77; 463 464 if (NULL == (twister_merchant_url = TALER_TWISTER_prepare_twister ( 465 PROXY_MERCHANT_config_file))) 466 return 77; 467 twister_merchant_url_instance_nonexistent = TALER_url_join ( 468 twister_merchant_url, "instances/foo/", NULL); 469 twister_merchant_url_instance_tor = TALER_url_join ( 470 twister_merchant_url, "instances/tor/", NULL); 471 if (NULL == (twisterexchanged = TALER_TWISTER_run_twister 472 (PROXY_EXCHANGE_config_file))) 473 return 77; 474 if (NULL == (twistermerchantd = TALER_TWISTER_run_twister 475 (PROXY_MERCHANT_config_file))) 476 return 77; 477 ret = TALER_TESTING_main (argv, 478 "INFO", 479 config_file, 480 "exchange-account-exchange", 481 TALER_TESTING_BS_FAKEBANK, 482 &cred, 483 &run, 484 NULL); 485 purge_process (twisterexchanged); 486 purge_process (twistermerchantd); 487 return ret; 488 } 489 490 491 /* end of test_merchant_api_twisted.c */