merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

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 */