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/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 2 : 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 2 : CMD_TRANSFER_TO_EXCHANGE (
110 : "create-reserve-age",
111 : "EUR:6.01"),
112 2 : 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 2 : CMD_EXEC_WIREWATCH ("wirewatch-age"),
123 : /**
124 : * Withdraw EUR:5.
125 : */
126 2 : 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 2 : 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 2 : TALER_TESTING_cmd_end ()
144 : };
145 :
146 : struct TALER_TESTING_Command spend_age[] = {
147 : /**
148 : * Spend the coin.
149 : */
150 2 : 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 2 : GNUNET_TIME_UNIT_ZERO,
159 : "EUR:4.99",
160 : MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)),
161 2 : 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 2 : 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 2 : CMD_EXEC_WIREWATCH (
174 : "import-kyc-account-withdraw"),
175 2 : 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 2 : GNUNET_TIME_UNIT_ZERO,
182 : "EUR:4.99",
183 : MHD_HTTP_OK),
184 2 : TALER_TESTING_cmd_deposit_replay (
185 : "deposit-simple-replay-age",
186 : "deposit-simple-age",
187 : MHD_HTTP_OK),
188 2 : TALER_TESTING_cmd_end ()
189 : };
190 :
191 : struct TALER_TESTING_Command refresh_age[] = {
192 : /* Fill reserve with EUR:5, 1ct is for fees. */
193 2 : CMD_TRANSFER_TO_EXCHANGE (
194 : "refresh-create-reserve-age-1",
195 : "EUR:6.01"),
196 2 : 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 2 : CMD_EXEC_WIREWATCH ("wirewatch-age-2"),
206 : /**
207 : * Withdraw EUR:5 with age restriction for age 13.
208 : */
209 2 : 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 2 : 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 2 : 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 2 : 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 2 : 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 2 : 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 2 : 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 2 : GNUNET_TIME_UNIT_ZERO,
261 : "EUR:1",
262 : MHD_HTTP_OK),
263 : /**
264 : * Try to spend a refreshed EUR:0.1 coin
265 : */
266 2 : 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 2 : 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 2 : 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 2 : TALER_TESTING_cmd_melt (
285 : "refresh-melt-failing-age-2",
286 : "refresh-reveal-age-1",
287 : MHD_HTTP_CONFLICT,
288 : NULL),
289 2 : 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 2 : CMD_TRANSFER_TO_EXCHANGE (
297 : "create-reserve-kyc-1",
298 : "EUR:30.02"),
299 2 : 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 2 : CMD_EXEC_WIREWATCH ("wirewatch-age-withdraw-1"),
306 2 : 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 2 : 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 2 : CMD_EXEC_WIREWATCH (
319 : "import-kyc-account"),
320 2 : 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 2 : TALER_TESTING_cmd_get_kyc_info (
327 : "get-kyc-info",
328 : "check-kyc-withdraw",
329 : MHD_HTTP_OK),
330 2 : TALER_TESTING_cmd_post_kyc_start (
331 : "start-kyc-process",
332 : "get-kyc-info",
333 : 0,
334 : MHD_HTTP_OK),
335 2 : 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 2 : 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 2 : 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 2 : 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 2 : TALER_TESTING_cmd_withdraw_reveal_age_proof (
364 : "age-withdraw-coins-reveal-1",
365 : "age-withdraw-coins-1",
366 : MHD_HTTP_OK),
367 2 : TALER_TESTING_cmd_end (),
368 : };
369 :
370 : {
371 : struct TALER_TESTING_Command commands[] = {
372 2 : TALER_TESTING_cmd_run_fakebank (
373 : "run-fakebank",
374 2 : cred.cfg,
375 : "exchange-account-2"),
376 2 : TALER_TESTING_cmd_system_start (
377 : "start-taler",
378 : config_file,
379 : "-e",
380 : NULL),
381 2 : TALER_TESTING_cmd_get_exchange (
382 : "get-exchange",
383 2 : cred.cfg,
384 : NULL,
385 : true,
386 : true),
387 2 : TALER_TESTING_cmd_oauth_with_birthdate (
388 : "oauth-service-with-birthdate",
389 : "2015-00-00", /* enough for a while */
390 : 6666),
391 2 : TALER_TESTING_cmd_batch ("withdraw-age",
392 : withdraw_age),
393 2 : TALER_TESTING_cmd_batch ("spend-age",
394 : spend_age),
395 2 : TALER_TESTING_cmd_batch ("refresh-age",
396 : refresh_age),
397 2 : TALER_TESTING_cmd_batch ("age-withdraw",
398 : age_withdraw),
399 : /* End the suite. */
400 2 : TALER_TESTING_cmd_end ()
401 : };
402 :
403 : (void) cls;
404 2 : TALER_TESTING_run (is,
405 : commands);
406 : }
407 2 : }
408 :
409 :
410 : int
411 2 : main (int argc,
412 : char *const *argv)
413 : {
414 : (void) argc;
415 : {
416 : char *cipher;
417 :
418 2 : cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]);
419 2 : GNUNET_assert (NULL != cipher);
420 2 : uses_cs = (0 == strcmp (cipher,
421 2 : "cs"));
422 2 : GNUNET_asprintf (
423 : &config_file,
424 : "test_exchange_api_age_restriction-%s.conf",
425 : cipher);
426 2 : GNUNET_free (cipher);
427 : }
428 2 : 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 */
|