test_merchant_api_twisted.c (19463B)
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 src/testing/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/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 * Password of the merchant instances the test creates. 56 */ 57 #define INSTANCE_PASSWORD "instance-password" 58 59 /** 60 * Account number of the merchant at the bank. 61 */ 62 #define MERCHANT_ACCOUNT_NAME "3" 63 64 /** 65 * Account number of some user. 66 */ 67 #define USER_ACCOUNT_NAME "62" 68 69 /** 70 * Configuration file for the proxy between merchant and 71 * exchange. Not used directly here in the code (instead 72 * used in the merchant config), but kept around for consistency. 73 */ 74 #define PROXY_EXCHANGE_config_file \ 75 "test_merchant_api_proxy_exchange.conf" 76 77 /** 78 * Configuration file for the proxy between "lib" and merchant. 79 */ 80 #define PROXY_MERCHANT_config_file \ 81 "test_merchant_api_proxy_merchant.conf" 82 83 /** 84 * Exchange base URL. Could also be taken from config. 85 */ 86 #define EXCHANGE_URL "http://localhost:8081/" 87 88 /** 89 * Twister URL that proxies the exchange. 90 */ 91 static char *twister_exchange_url; 92 93 /** 94 * Twister URL that proxies the merchant. 95 */ 96 static char *twister_merchant_url; 97 98 /** 99 * Twister URL that proxies the merchant. 100 */ 101 static char *twister_merchant_url_instance_nonexistent; 102 103 /** 104 * Twister URL that proxies the merchant. 105 */ 106 static char *twister_merchant_url_instance_tor; 107 108 /** 109 * Merchant base URL. 110 */ 111 static const char *merchant_url; 112 113 /** 114 * Twister process that proxies the exchange. 115 */ 116 static struct GNUNET_Process *twisterexchanged; 117 118 /** 119 * Twister process that proxies the merchant. 120 */ 121 static struct GNUNET_Process *twistermerchantd; 122 123 static struct TALER_FullPayto payer_payto; 124 static struct TALER_FullPayto exchange_payto; 125 static struct TALER_FullPayto merchant_payto; 126 127 static struct TALER_TESTING_Credentials cred; 128 129 /** 130 * User name. Never checked by fakebank. 131 */ 132 #define USER_LOGIN_NAME "user42" 133 134 /** 135 * User password. Never checked by fakebank. 136 */ 137 #define USER_LOGIN_PASS "pass42" 138 139 /** 140 * Execute the taler-exchange-wirewatch command with 141 * our configuration file. 142 * 143 * @param label label to use for the command. 144 */ 145 static struct TALER_TESTING_Command 146 CMD_EXEC_WIREWATCH (const char *label) 147 { 148 return TALER_TESTING_cmd_exec_wirewatch (label, config_file); 149 } 150 151 152 /** 153 * Execute the taler-exchange-aggregator, closer and transfer commands with 154 * our configuration file. 155 * 156 * @param label label to use for the command. 157 */ 158 #define CMD_EXEC_AGGREGATOR(label) \ 159 TALER_TESTING_cmd_exec_aggregator (label "-aggregator", config_file), \ 160 TALER_TESTING_cmd_exec_transfer (label "-transfer", config_file) 161 162 163 /** 164 * Run wire transfer of funds from some user's account to the 165 * exchange. 166 * 167 * @param label label to use for the command. 168 * @param amount amount to transfer, i.e. "EUR:1" 169 * @param url exchange_url 170 */ 171 static struct TALER_TESTING_Command 172 CMD_TRANSFER_TO_EXCHANGE (const char *label, 173 const char *amount) 174 { 175 return TALER_TESTING_cmd_admin_add_incoming (label, 176 amount, 177 &cred.ba, 178 payer_payto); 179 } 180 181 182 /** 183 * Main function that will tell the interpreter what commands to 184 * run. 185 * 186 * @param cls closure 187 */ 188 static void 189 run (void *cls, 190 struct TALER_TESTING_Interpreter *is) 191 { 192 /****** Covering /pay *******/ 193 struct TALER_TESTING_Command pay[] = { 194 /** 195 * Move money to the exchange's bank account. 196 */ 197 CMD_TRANSFER_TO_EXCHANGE ("create-reserve-abort-1", 198 "EUR:1.01"), 199 200 /** 201 * Make a reserve exist, according to the previous transfer. 202 */ 203 CMD_EXEC_WIREWATCH ("wirewatch-abort-1"), 204 TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-abort-1", 205 "EUR:1.01", 206 payer_payto, 207 exchange_payto, 208 "create-reserve-abort-1"), 209 TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-abort-1", 210 "create-reserve-abort-1", 211 "EUR:1", 212 0, 213 MHD_HTTP_OK), 214 TALER_TESTING_cmd_status ("withdraw-status-abort-1", 215 "create-reserve-abort-1", 216 "EUR:0", 217 MHD_HTTP_OK), 218 TALER_TESTING_cmd_merchant_post_orders ("create-proposal-abort-1", 219 cred.cfg, 220 twister_merchant_url, 221 MHD_HTTP_OK, 222 "abort-one", 223 GNUNET_TIME_UNIT_ZERO_TS, 224 GNUNET_TIME_UNIT_FOREVER_TS, 225 "EUR:3.0"), 226 /* Will only pay _half_ the supposed price, 227 * so we'll then have the right to abort. */ 228 TALER_TESTING_cmd_merchant_pay_order ("deposit-simple-for-abort", 229 twister_merchant_url, 230 MHD_HTTP_BAD_REQUEST, 231 "create-proposal-abort-1", 232 "withdraw-coin-abort-1", 233 "EUR:1.01", 234 "EUR:1.00", 235 NULL), // no sense now 236 TALER_TESTING_cmd_delete_object ("hack-abort-1", 237 PROXY_MERCHANT_config_file, 238 "merchant_pub"), 239 TALER_TESTING_cmd_merchant_order_abort ("pay-abort-1", 240 twister_merchant_url, 241 "deposit-simple-for-abort", 242 MHD_HTTP_OK), 243 TALER_TESTING_cmd_delete_object ("hack-abort-2", 244 PROXY_MERCHANT_config_file, 245 "refund_permissions.0.rtransaction_id"), 246 TALER_TESTING_cmd_merchant_order_abort ("pay-abort-2", 247 twister_merchant_url, 248 "deposit-simple-for-abort", 249 MHD_HTTP_OK), 250 TALER_TESTING_cmd_modify_object_dl ("hack-abort-3", 251 PROXY_MERCHANT_config_file, 252 "refund_permissions.0.coin_pub", 253 /* dummy coin. */ 254 "8YX10E41ZWHX0X2RK4XFAXB2D3M05M1HNG14ZFZZB8M7SA4QCKCG"), 255 TALER_TESTING_cmd_merchant_order_abort ("pay-abort-3", 256 twister_merchant_url, 257 "deposit-simple-for-abort", 258 MHD_HTTP_OK), 259 TALER_TESTING_cmd_flip_download ("hack-abort-4", 260 PROXY_MERCHANT_config_file, 261 "refund_permissions.0.merchant_sig"), 262 TALER_TESTING_cmd_merchant_order_abort ("pay-abort-4", 263 twister_merchant_url, 264 "deposit-simple-for-abort", 265 MHD_HTTP_OK), 266 /* just malforming the response. */ 267 TALER_TESTING_cmd_malform_response ("malform-abortion", 268 PROXY_MERCHANT_config_file), 269 TALER_TESTING_cmd_merchant_order_abort ("pay-abort-5", 270 twister_merchant_url, 271 "deposit-simple-for-abort", 272 0), 273 CMD_TRANSFER_TO_EXCHANGE ("create-reserve-double-spend", 274 "EUR:1.01"), 275 CMD_EXEC_WIREWATCH ("wirewatch-double-spend"), 276 TALER_TESTING_cmd_merchant_post_orders ("create-proposal-double-spend", 277 cred.cfg, 278 twister_merchant_url, 279 MHD_HTTP_OK, 280 "DS-1", 281 GNUNET_TIME_UNIT_ZERO_TS, 282 GNUNET_TIME_UNIT_FOREVER_TS, 283 "EUR:1.0"), 284 TALER_TESTING_cmd_merchant_post_orders ("create-proposal-double-spend-1", 285 cred.cfg, 286 twister_merchant_url, 287 MHD_HTTP_OK, 288 "DS-2", 289 GNUNET_TIME_UNIT_ZERO_TS, 290 GNUNET_TIME_UNIT_FOREVER_TS, 291 "EUR:3.0"), 292 293 TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-double-spend", 294 "create-reserve-double-spend", 295 "EUR:1", 296 0, 297 MHD_HTTP_OK), 298 TALER_TESTING_cmd_merchant_pay_order ("deposit-simple-ok", 299 twister_merchant_url, 300 MHD_HTTP_OK, 301 "create-proposal-double-spend", 302 "withdraw-coin-double-spend", 303 "EUR:1.01", 304 "EUR:1.00", 305 NULL), // no sense now 306 TALER_TESTING_cmd_flip_download ("hack-coin-history", 307 PROXY_MERCHANT_config_file, 308 "history.0.coin_sig"), 309 /* Coin history check will fail, 310 * due to coin's bad signature. */ 311 TALER_TESTING_cmd_merchant_pay_order ("deposit-simple-fail", 312 twister_merchant_url, 313 MHD_HTTP_CONFLICT, 314 "create-proposal-double-spend-1", 315 "withdraw-coin-double-spend", 316 "EUR:1.01", 317 "EUR:1.00", 318 NULL), // no sense now 319 /* max uint64 number: 9223372036854775807; try to overflow! */ 320 TALER_TESTING_cmd_end () 321 }; 322 323 struct TALER_TESTING_Command commands[] = { 324 /* general setup */ 325 TALER_TESTING_cmd_run_fakebank ("run-fakebank", 326 cred.cfg, 327 "exchange-account-exchange"), 328 TALER_TESTING_cmd_system_start ("start-taler", 329 config_file, 330 "-ema", 331 "-u", "exchange-account-exchange", 332 "-r", "merchant-exchange-test", 333 NULL), 334 TALER_TESTING_cmd_get_exchange ("get-exchange", 335 cred.cfg, 336 NULL, 337 true, 338 true), 339 TALER_TESTING_cmd_merchant_post_instances_with_password ( 340 "instance-create-admin", 341 twister_merchant_url, 342 "admin", 343 INSTANCE_PASSWORD, 344 MHD_HTTP_NO_CONTENT), 345 TALER_TESTING_cmd_merchant_login ("login-admin", 346 twister_merchant_url, 347 "admin", 348 INSTANCE_PASSWORD), 349 TALER_TESTING_cmd_merchant_post_account ( 350 "instance-create-default-account", 351 twister_merchant_url, 352 merchant_payto, 353 NULL, NULL, 354 MHD_HTTP_OK), 355 TALER_TESTING_cmd_batch ("pay", 356 pay), 357 /* Malform the response from the exchange. */ 358 /** 359 * Move money to the exchange's bank account. 360 */ 361 CMD_TRANSFER_TO_EXCHANGE ("create-reserve-1", 362 "EUR:10.02"), 363 /** 364 * Make a reserve exist, 365 * according to the previous 366 * transfer. 367 */ 368 CMD_EXEC_WIREWATCH ("wirewatch-1"), 369 TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-2", 370 "EUR:10.02", 371 payer_payto, 372 exchange_payto, 373 "create-reserve-1"), 374 TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1", 375 "create-reserve-1", 376 "EUR:5", 377 0, 378 MHD_HTTP_OK), 379 TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2", 380 "create-reserve-1", 381 "EUR:5", 382 0, 383 MHD_HTTP_OK), 384 385 TALER_TESTING_cmd_merchant_post_orders_no_claim ( 386 "create-proposal-1", 387 merchant_url, 388 MHD_HTTP_OK, 389 "1", 390 GNUNET_TIME_UNIT_ZERO_TS, 391 GNUNET_TIME_UNIT_FOREVER_TS, 392 "EUR:6.0"), 393 TALER_TESTING_cmd_flip_upload ("hack-claim-token", 394 PROXY_MERCHANT_config_file, 395 "token"), 396 TALER_TESTING_cmd_merchant_claim_order ( 397 "claim-1-incorrect-claim-token", 398 twister_merchant_url, 399 MHD_HTTP_NOT_FOUND, 400 "create-proposal-1", 401 NULL), 402 TALER_TESTING_cmd_merchant_post_orders ("create-proposal-2", 403 cred.cfg, 404 merchant_url, 405 MHD_HTTP_OK, 406 "2", 407 GNUNET_TIME_UNIT_ZERO_TS, 408 GNUNET_TIME_UNIT_FOREVER_TS, 409 "EUR:6.0"), 410 TALER_TESTING_cmd_merchant_pay_order ("deposit-2", 411 merchant_url, 412 MHD_HTTP_BAD_REQUEST, 413 "create-proposal-2", 414 "withdraw-coin-1", 415 "EUR:5", 416 "EUR:4.99", 417 NULL), 418 TALER_TESTING_cmd_merchant_order_abort ("pay-abort-1", 419 merchant_url, 420 "deposit-2", 421 MHD_HTTP_OK), 422 TALER_TESTING_cmd_end () 423 }; 424 425 TALER_TESTING_run (is, 426 commands); 427 } 428 429 430 /** 431 * Kill, wait, and destroy convenience function. 432 * 433 * @param process process to purge. 434 */ 435 static void 436 purge_process (struct GNUNET_Process *process) 437 { 438 GNUNET_break (GNUNET_OK == 439 GNUNET_process_kill (process, 440 SIGINT)); 441 GNUNET_break (GNUNET_OK == 442 GNUNET_process_wait (process, 443 true, 444 NULL, 445 NULL)); 446 GNUNET_process_destroy (process); 447 } 448 449 450 int 451 main (int argc, 452 char *const *argv) 453 { 454 int ret; 455 456 { 457 char *cipher; 458 459 cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]); 460 GNUNET_assert (NULL != cipher); 461 GNUNET_asprintf (&config_file, 462 "test_merchant_api_twisted-%s.conf", 463 cipher); 464 GNUNET_free (cipher); 465 } 466 payer_payto.full_payto = 467 (char *) "payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME 468 "?receiver-name=" USER_ACCOUNT_NAME; 469 exchange_payto.full_payto = 470 (char *) "payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME 471 "?receiver-name=" EXCHANGE_ACCOUNT_NAME; 472 merchant_payto.full_payto = 473 (char *) "payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME 474 "?receiver-name=" MERCHANT_ACCOUNT_NAME; 475 merchant_url = "http://localhost:8080/"; 476 if (NULL == (twister_exchange_url = TALER_TWISTER_prepare_twister ( 477 PROXY_EXCHANGE_config_file))) 478 return 77; 479 480 if (NULL == (twister_merchant_url = TALER_TWISTER_prepare_twister ( 481 PROXY_MERCHANT_config_file))) 482 return 77; 483 twister_merchant_url_instance_nonexistent = TALER_url_join ( 484 twister_merchant_url, "instances/foo/", NULL); 485 twister_merchant_url_instance_tor = TALER_url_join ( 486 twister_merchant_url, "instances/tor/", NULL); 487 if (NULL == (twisterexchanged = TALER_TWISTER_run_twister 488 (PROXY_EXCHANGE_config_file))) 489 { 490 GNUNET_break (0); 491 return 77; 492 } 493 if (NULL == (twistermerchantd = TALER_TWISTER_run_twister 494 (PROXY_MERCHANT_config_file))) 495 { 496 GNUNET_break (0); 497 return 77; 498 } 499 ret = TALER_TESTING_main (argv, 500 "INFO", 501 config_file, 502 "exchange-account-exchange", 503 TALER_TESTING_BS_FAKEBANK, 504 &cred, 505 &run, 506 NULL); 507 purge_process (twisterexchanged); 508 purge_process (twistermerchantd); 509 return ret; 510 } 511 512 513 /* end of test_merchant_api_twisted.c */