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