exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

test_exchange_api_age_restriction.c (12388B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 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 testing/test_exchange_api_age_restriction.c
     21  * @brief testcase to test exchange's age-restrictrition related HTTP API interfaces
     22  * @author Özgür Kesim
     23  */
     24 #include "taler/taler_util.h"
     25 #include "taler/taler_json_lib.h"
     26 #include <gnunet/gnunet_util_lib.h>
     27 #include <gnunet/gnunet_testing_lib.h>
     28 #include <microhttpd.h>
     29 #include "taler/taler_bank_service.h"
     30 #include "taler/taler_testing_lib.h"
     31 
     32 /**
     33  * Configuration file we use.  One (big) configuration is used
     34  * for the various components for this test.
     35  */
     36 static char *config_file;
     37 
     38 /**
     39  * Our credentials.
     40  */
     41 static struct TALER_TESTING_Credentials cred;
     42 
     43 /**
     44  * Some tests behave differently when using CS as we cannot
     45  * reuse the coin private key for different denominations
     46  * due to the derivation of it with the /csr values. Hence
     47  * some tests behave differently in CS mode, hence this
     48  * flag.
     49  */
     50 static bool uses_cs;
     51 
     52 /**
     53  * Execute the taler-exchange-wirewatch command with
     54  * our configuration file.
     55  *
     56  * @param label label to use for the command.
     57  */
     58 #define CMD_EXEC_WIREWATCH(label) \
     59         TALER_TESTING_cmd_exec_wirewatch2 (label, config_file, \
     60                                            "exchange-account-2")
     61 
     62 /**
     63  * Execute the taler-exchange-aggregator, closer and transfer commands with
     64  * our configuration file.
     65  *
     66  * @param label label to use for the command.
     67  */
     68 #define CMD_EXEC_AGGREGATOR(label) \
     69         TALER_TESTING_cmd_sleep ("sleep-before-aggregator", 2), \
     70         TALER_TESTING_cmd_exec_aggregator (label "-aggregator", config_file), \
     71         TALER_TESTING_cmd_exec_transfer (label "-transfer", config_file)
     72 
     73 
     74 /**
     75  * Run wire transfer of funds from some user's account to the
     76  * exchange.
     77  *
     78  * @param label label to use for the command.
     79  * @param amount amount to transfer, i.e. "EUR:1"
     80  */
     81 #define CMD_TRANSFER_TO_EXCHANGE(label,amount) \
     82         TALER_TESTING_cmd_admin_add_incoming (label, amount, \
     83                                               &cred.ba,                \
     84                                               cred.user42_payto)
     85 
     86 /**
     87  * Main function that will tell the interpreter what commands to
     88  * run.
     89  *
     90  * @param cls closure
     91  * @param is interpreter we use to run commands
     92  */
     93 static void
     94 run (void *cls,
     95      struct TALER_TESTING_Interpreter *is)
     96 {
     97   /**
     98    * Test withdrawal with age restriction.  Success is expected (because the
     99    * amount is below the kyc threshold ), so it MUST be
    100    * called age restriction is activated in the exchange!
    101    *
    102    * FIXME: create a test that tries to withdraw coins with age restriction but
    103    * (expectedly) fails because the exchange doesn't support age restrictions.
    104    */
    105   struct TALER_TESTING_Command withdraw_age[] = {
    106     /**
    107      * Move money to the exchange's bank account.
    108      */
    109     CMD_TRANSFER_TO_EXCHANGE (
    110       "create-reserve-age",
    111       "EUR:6.01"),
    112     TALER_TESTING_cmd_check_bank_admin_transfer (
    113       "check-create-reserve-age",
    114       "EUR:6.01",
    115       cred.user42_payto,
    116       cred.exchange_payto,
    117       "create-reserve-age"),
    118     /**
    119      * Make a reserve exist, according to the previous
    120      * transfer.
    121      */
    122     CMD_EXEC_WIREWATCH ("wirewatch-age"),
    123     /**
    124      * Withdraw EUR:5.
    125      */
    126     TALER_TESTING_cmd_withdraw_amount (
    127       "withdraw-coin-age-1",
    128       "create-reserve-age",
    129       "EUR:5",
    130       13,
    131       MHD_HTTP_OK),
    132     /**
    133      * Idempotent withdrawal.
    134      */
    135     TALER_TESTING_cmd_withdraw_amount_reuse_all_secrets (
    136       "withdraw-coin-age-idem-1",
    137       "create-reserve-age",
    138       "EUR:5",
    139       13,
    140       "withdraw-coin-age-1",
    141       MHD_HTTP_OK),
    142 
    143     TALER_TESTING_cmd_end ()
    144   };
    145 
    146   struct TALER_TESTING_Command spend_age[] = {
    147     /**
    148      * Spend the coin.
    149      */
    150     TALER_TESTING_cmd_set_var (
    151       "account-priv",
    152       TALER_TESTING_cmd_deposit (
    153         "deposit-simple-age-fail-kyc",
    154         "withdraw-coin-age-1",
    155         0,
    156         cred.user42_payto,
    157         "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
    158         GNUNET_TIME_UNIT_ZERO,
    159         "EUR:4.99",
    160         MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)),
    161     TALER_TESTING_cmd_admin_add_kycauth (
    162       "kyc-auth-transfer",
    163       "EUR:0.01",
    164       &cred.ba,
    165       cred.user42_payto,
    166       "deposit-simple-age-fail-kyc"),
    167     TALER_TESTING_cmd_admin_add_kycauth (
    168       "kyc-auth-transfer",
    169       "EUR:0.01",
    170       &cred.ba,
    171       cred.user43_payto,
    172       "deposit-simple-age-fail-kyc"),
    173     CMD_EXEC_WIREWATCH (
    174       "import-kyc-account-withdraw"),
    175     TALER_TESTING_cmd_deposit (
    176       "deposit-simple-age",
    177       "withdraw-coin-age-1",
    178       0,
    179       cred.user42_payto,
    180       "{\"items\":[{\"name\":\"ice cream\",\"value\":2}]}",
    181       GNUNET_TIME_UNIT_ZERO,
    182       "EUR:4.99",
    183       MHD_HTTP_OK),
    184     TALER_TESTING_cmd_deposit_replay (
    185       "deposit-simple-replay-age",
    186       "deposit-simple-age",
    187       MHD_HTTP_OK),
    188     TALER_TESTING_cmd_end ()
    189   };
    190 
    191   struct TALER_TESTING_Command refresh_age[] = {
    192     /* Fill reserve with EUR:5, 1ct is for fees. */
    193     CMD_TRANSFER_TO_EXCHANGE (
    194       "refresh-create-reserve-age-1",
    195       "EUR:6.01"),
    196     TALER_TESTING_cmd_check_bank_admin_transfer (
    197       "ck-refresh-create-reserve-age-1",
    198       "EUR:6.01",
    199       cred.user42_payto,
    200       cred.exchange_payto,
    201       "refresh-create-reserve-age-1"),
    202     /**
    203      * Make previous command effective.
    204      */
    205     CMD_EXEC_WIREWATCH ("wirewatch-age-2"),
    206     /**
    207      * Withdraw EUR:5 with age restriction for age 13.
    208      */
    209     TALER_TESTING_cmd_withdraw_amount (
    210       "refresh-withdraw-coin-age-1",
    211       "refresh-create-reserve-age-1",
    212       "EUR:5",
    213       13,
    214       MHD_HTTP_OK),
    215     /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin
    216      * (in full) (merchant would receive EUR:0.99 due to 1 ct
    217      * deposit fee)
    218      */
    219     TALER_TESTING_cmd_deposit (
    220       "refresh-deposit-partial-age",
    221       "refresh-withdraw-coin-age-1",
    222       0,
    223       cred.user42_payto,
    224       "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:3\"}]}",
    225       GNUNET_TIME_UNIT_ZERO,
    226       "EUR:1",
    227       MHD_HTTP_OK),
    228     /**
    229      * Melt the rest of the coin's value
    230      * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */
    231     TALER_TESTING_cmd_melt_double (
    232       "refresh-melt-age-1",
    233       "refresh-withdraw-coin-age-1",
    234       MHD_HTTP_OK,
    235       NULL),
    236     /**
    237      * Complete (successful) melt operation, and
    238      * withdraw the coins
    239      */
    240     TALER_TESTING_cmd_melt_reveal (
    241       "refresh-reveal-age-1",
    242       "refresh-melt-age-1",
    243       MHD_HTTP_OK),
    244     /**
    245      * Do it again to check idempotency
    246      */
    247     TALER_TESTING_cmd_melt_reveal (
    248       "refresh-reveal-age-1-idempotency",
    249       "refresh-melt-age-1",
    250       MHD_HTTP_OK),
    251     /**
    252      * Try to spend a refreshed EUR:1 coin
    253      */
    254     TALER_TESTING_cmd_deposit (
    255       "refresh-deposit-refreshed-age-1a",
    256       "refresh-reveal-age-1-idempotency",
    257       0,
    258       cred.user42_payto,
    259       "{\"items\":[{\"name\":\"ice cream\",\"value\":4}]}",
    260       GNUNET_TIME_UNIT_ZERO,
    261       "EUR:1",
    262       MHD_HTTP_OK),
    263     /**
    264      * Try to spend a refreshed EUR:0.1 coin
    265      */
    266     TALER_TESTING_cmd_deposit (
    267       "refresh-deposit-refreshed-age-1b",
    268       "refresh-reveal-age-1",
    269       3,
    270       cred.user43_payto,
    271       "{\"items\":[{\"name\":\"ice cream\",\"value\":5}]}",
    272       GNUNET_TIME_UNIT_ZERO,
    273       "EUR:0.1",
    274       MHD_HTTP_OK),
    275     /* Test running a failing melt operation (same operation
    276      * again must fail) */
    277     TALER_TESTING_cmd_melt (
    278       "refresh-melt-failing-age",
    279       "refresh-withdraw-coin-age-1",
    280       MHD_HTTP_CONFLICT,
    281       NULL),
    282     /* Test running a failing melt operation (on a coin that
    283        was itself revealed and subsequently deposited) */
    284     TALER_TESTING_cmd_melt (
    285       "refresh-melt-failing-age-2",
    286       "refresh-reveal-age-1",
    287       MHD_HTTP_CONFLICT,
    288       NULL),
    289     TALER_TESTING_cmd_end ()
    290   };
    291 
    292   /**
    293    * Test with age-withdraw, after kyc process has set a birthdate
    294    */
    295   struct TALER_TESTING_Command age_withdraw[] = {
    296     CMD_TRANSFER_TO_EXCHANGE (
    297       "create-reserve-kyc-1",
    298       "EUR:30.02"),
    299     TALER_TESTING_cmd_check_bank_admin_transfer (
    300       "check-create-reserve-kyc-1",
    301       "EUR:30.02",
    302       cred.user42_payto,
    303       cred.exchange_payto,
    304       "create-reserve-kyc-1"),
    305     CMD_EXEC_WIREWATCH ("wirewatch-age-withdraw-1"),
    306     TALER_TESTING_cmd_withdraw_amount (
    307       "withdraw-coin-1-lacking-kyc",
    308       "create-reserve-kyc-1",
    309       "EUR:10",
    310       0,    /* age restriction off */
    311       MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS),
    312     TALER_TESTING_cmd_admin_add_kycauth (
    313       "setup-account-key",
    314       "EUR:0.01",
    315       &cred.ba,
    316       cred.user42_payto,
    317       NULL /* create new key */),
    318     CMD_EXEC_WIREWATCH (
    319       "import-kyc-account"),
    320     TALER_TESTING_cmd_check_kyc_get (
    321       "check-kyc-withdraw",
    322       "withdraw-coin-1-lacking-kyc",
    323       "setup-account-key",
    324       TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER,
    325       MHD_HTTP_ACCEPTED),
    326     TALER_TESTING_cmd_get_kyc_info (
    327       "get-kyc-info",
    328       "check-kyc-withdraw",
    329       MHD_HTTP_OK),
    330     TALER_TESTING_cmd_post_kyc_start (
    331       "start-kyc-process",
    332       "get-kyc-info",
    333       0,
    334       MHD_HTTP_OK),
    335     TALER_TESTING_cmd_proof_kyc_oauth2 (
    336       "proof-withdraw-kyc",
    337       "withdraw-coin-1-lacking-kyc",
    338       "test-oauth2",
    339       "pass",
    340       MHD_HTTP_SEE_OTHER),
    341     TALER_TESTING_cmd_withdraw_amount (
    342       "withdraw-coin-1-with-kyc",
    343       "create-reserve-kyc-1",
    344       "EUR:10",
    345       0,   /* age restriction off */
    346       MHD_HTTP_CONFLICT),
    347     TALER_TESTING_cmd_withdraw_with_age_proof (
    348       "age-withdraw-coin-1-too-low",
    349       "create-reserve-kyc-1",
    350       18,      /* Too high */
    351       MHD_HTTP_CONFLICT,
    352       "EUR:10",
    353       NULL),
    354     TALER_TESTING_cmd_withdraw_with_age_proof (
    355       "age-withdraw-coins-1",
    356       "create-reserve-kyc-1",
    357       8,
    358       MHD_HTTP_CREATED,
    359       "EUR:10",
    360       "EUR:10",
    361       "EUR:5",
    362       NULL),
    363     TALER_TESTING_cmd_withdraw_reveal_age_proof (
    364       "age-withdraw-coins-reveal-1",
    365       "age-withdraw-coins-1",
    366       MHD_HTTP_OK),
    367     TALER_TESTING_cmd_end (),
    368   };
    369 
    370   {
    371     struct TALER_TESTING_Command commands[] = {
    372       TALER_TESTING_cmd_run_fakebank (
    373         "run-fakebank",
    374         cred.cfg,
    375         "exchange-account-2"),
    376       TALER_TESTING_cmd_system_start (
    377         "start-taler",
    378         config_file,
    379         "-e",
    380         NULL),
    381       TALER_TESTING_cmd_get_exchange (
    382         "get-exchange",
    383         cred.cfg,
    384         NULL,
    385         true,
    386         true),
    387       TALER_TESTING_cmd_oauth_with_birthdate (
    388         "oauth-service-with-birthdate",
    389         "2015-00-00",    /* enough for a while */
    390         6666),
    391       TALER_TESTING_cmd_batch ("withdraw-age",
    392                                withdraw_age),
    393       TALER_TESTING_cmd_batch ("spend-age",
    394                                spend_age),
    395       TALER_TESTING_cmd_batch ("refresh-age",
    396                                refresh_age),
    397       TALER_TESTING_cmd_batch ("age-withdraw",
    398                                age_withdraw),
    399       /* End the suite. */
    400       TALER_TESTING_cmd_end ()
    401     };
    402 
    403     (void) cls;
    404     TALER_TESTING_run (is,
    405                        commands);
    406   }
    407 }
    408 
    409 
    410 int
    411 main (int argc,
    412       char *const *argv)
    413 {
    414   (void) argc;
    415   {
    416     char *cipher;
    417 
    418     cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]);
    419     GNUNET_assert (NULL != cipher);
    420     uses_cs = (0 == strcmp (cipher,
    421                             "cs"));
    422     GNUNET_asprintf (
    423       &config_file,
    424       "test_exchange_api_age_restriction-%s.conf",
    425       cipher);
    426     GNUNET_free (cipher);
    427   }
    428   return TALER_TESTING_main (
    429     argv,
    430     "INFO",
    431     config_file,
    432     "exchange-account-2",
    433     TALER_TESTING_BS_FAKEBANK,
    434     &cred,
    435     &run,
    436     NULL);
    437 }
    438 
    439 
    440 /* end of test_exchange_api_age_restriction.c */