merchant

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

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