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 (12509B)


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