LCOV - code coverage report
Current view: top level - testing - test_exchange_api_age_restriction.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 68 68
Test Date: 2025-12-26 23:00:34 Functions: 100.0 % 2 2

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

Generated by: LCOV version 2.0-1