Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2026 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file exchangedb/test_legitimization_processes.c
18 : * @brief tests for the exchangedb functions whose primary table is
19 : * `legitimization_processes`
20 : * @author Christian Grothoff
21 : *
22 : * Covers #TALER_EXCHANGEDB_insert_legitimization_process(),
23 : * #TALER_EXCHANGEDB_update_legitimization_process_by_row(),
24 : * #TALER_EXCHANGEDB_do_reserve_legitimization_process(),
25 : * #TALER_EXCHANGEDB_update_legitimization_process_start(),
26 : * #TALER_EXCHANGEDB_insert_kyc_failure(),
27 : * #TALER_EXCHANGEDB_insert_aml_program_failure(),
28 : * #TALER_EXCHANGEDB_get_legitimization_process_by_account(),
29 : * #TALER_EXCHANGEDB_get_pending_legitimization_process(),
30 : * #TALER_EXCHANGEDB_get_kyc_provider_account() and
31 : * #TALER_EXCHANGEDB_iterate_kyc_references().
32 : *
33 : * A row of `legitimization_processes` is one run of one KYC provider
34 : * against one account, working on one measure of a
35 : * `legitimization_measures` set. The checks therefore create an account
36 : * and a measure set first, and then walk a process from "started" through
37 : * "redirect known" to "finished".
38 : */
39 : #include "test_common.h"
40 : #include "exchange-database/update_legitimization_process_start.h"
41 : #include "exchange-database/do_reserve_legitimization_process.h"
42 : #include "exchange-database/do_trigger_kyc_rule_for_account.h"
43 : #include "exchange-database/get_kyc_provider_account.h"
44 : #include "exchange-database/get_legitimization_process_by_account.h"
45 : #include "exchange-database/get_pending_legitimization_process.h"
46 : #include "exchange-database/insert_aml_program_failure.h"
47 : #include "exchange-database/insert_kyc_failure.h"
48 : #include "exchange-database/insert_legitimization_process.h"
49 : #include "exchange-database/iterate_kyc_references.h"
50 : #include "exchange-database/update_legitimization_process_by_row.h"
51 :
52 :
53 : /**
54 : * Account the checks run processes against.
55 : */
56 : static struct TDB_Account account;
57 :
58 :
59 : /**
60 : * Measure set the processes work on.
61 : */
62 : static uint64_t measure_row;
63 :
64 :
65 : /**
66 : * Row of the process check_start() created.
67 : */
68 : static uint64_t process_row;
69 :
70 :
71 : /**
72 : * Closure for #reference_cb().
73 : */
74 : struct ReferenceContext
75 : {
76 : /**
77 : * How many references did the callback see?
78 : */
79 : unsigned int total;
80 :
81 : /**
82 : * Provider we are looking for, NULL to match nothing.
83 : */
84 : const char *provider;
85 :
86 : /**
87 : * How many times did we see it?
88 : */
89 : unsigned int matched;
90 :
91 : /**
92 : * Provider account id reported for it, owned by this struct.
93 : */
94 : char *user_id;
95 :
96 : /**
97 : * Provider legitimization id reported for it, owned by this struct.
98 : */
99 : char *legi_id;
100 : };
101 :
102 :
103 : /**
104 : * Callback for #TALER_EXCHANGEDB_iterate_kyc_references().
105 : *
106 : * @param cls a `struct ReferenceContext *`
107 : * @param kyc_provider_name provider that ran the process
108 : * @param provider_user_id account id at the provider
109 : * @param legi_id legitimization id at the provider
110 : */
111 : static void
112 5 : reference_cb (void *cls,
113 : const char *kyc_provider_name,
114 : const char *provider_user_id,
115 : const char *legi_id)
116 : {
117 5 : struct ReferenceContext *ctx = cls;
118 :
119 5 : ctx->total++;
120 5 : if ( (NULL != ctx->provider) &&
121 5 : (0 == strcmp (kyc_provider_name,
122 : ctx->provider)) )
123 : {
124 2 : ctx->matched++;
125 2 : GNUNET_free (ctx->user_id);
126 2 : GNUNET_free (ctx->legi_id);
127 2 : ctx->user_id = (NULL == provider_user_id)
128 : ? NULL
129 2 : : GNUNET_strdup (provider_user_id);
130 2 : ctx->legi_id = (NULL == legi_id)
131 : ? NULL
132 2 : : GNUNET_strdup (legi_id);
133 : }
134 5 : }
135 :
136 :
137 : /**
138 : * Put a measure on our account, creating the account on the way.
139 : *
140 : * @param pg the database context
141 : */
142 : static void
143 1 : setup_account (struct TALER_EXCHANGEDB_PostgresContext *pg)
144 : {
145 : json_t *jmeasures;
146 1 : uint64_t row = 0;
147 : bool bad_kyc_auth;
148 :
149 1 : if (0 != measure_row)
150 0 : return;
151 1 : TDB_account (pg,
152 : 10,
153 : &account);
154 1 : jmeasures = GNUNET_JSON_PACK (
155 : GNUNET_JSON_pack_array_steal (
156 : "measures",
157 : json_pack ("[{s:s,s:s,s:s}]",
158 : "check_name",
159 : "verify-id",
160 : "prog_name",
161 : "skip",
162 : "context",
163 : "none")),
164 : GNUNET_JSON_pack_bool ("is_and_combinator",
165 : true));
166 1 : GNUNET_assert (NULL != jmeasures);
167 1 : GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
168 : TALER_EXCHANGEDB_do_trigger_kyc_rule_for_account (
169 : pg,
170 : account.payto,
171 : &account.h_normalized,
172 : NULL,
173 : NULL,
174 : jmeasures,
175 : 1,
176 : &row,
177 : &bad_kyc_auth));
178 1 : json_decref (jmeasures);
179 1 : GNUNET_assert (0 != row);
180 1 : measure_row = row;
181 : }
182 :
183 :
184 : /**
185 : * Nothing is known while the table is empty.
186 : *
187 : * @param pg the database context
188 : * @return 0 on success
189 : */
190 : static int
191 1 : check_empty (struct TALER_EXCHANGEDB_PostgresContext *pg)
192 : {
193 : struct TALER_NormalizedPaytoHashP h_payto;
194 : struct GNUNET_TIME_Absolute expiration;
195 1 : struct ReferenceContext ctx = { 0 };
196 1 : char *provider_account_id = NULL;
197 1 : char *provider_legitimization_id = NULL;
198 1 : char *redirect_url = NULL;
199 : uint64_t row;
200 : bool is_wallet;
201 :
202 1 : setup_account (pg);
203 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
204 : TALER_EXCHANGEDB_get_legitimization_process_by_account (
205 : pg,
206 : "test-provider",
207 : &account.h_normalized,
208 : &row,
209 : &expiration,
210 : &provider_account_id,
211 : &provider_legitimization_id,
212 : &is_wallet));
213 1 : FAILIF (NULL != provider_account_id);
214 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
215 : TALER_EXCHANGEDB_get_pending_legitimization_process (
216 : pg,
217 : &account.h_normalized,
218 : "test-provider",
219 : &redirect_url));
220 1 : FAILIF (NULL != redirect_url);
221 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
222 : TALER_EXCHANGEDB_get_kyc_provider_account (pg,
223 : "test-provider",
224 : "legi-1",
225 : &h_payto,
226 : &is_wallet,
227 : &row));
228 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
229 : TALER_EXCHANGEDB_iterate_kyc_references (pg,
230 : &account.h_normalized,
231 : &reference_cb,
232 : &ctx));
233 1 : FAILIF (0 != ctx.total);
234 1 : return 0;
235 : }
236 :
237 :
238 : /**
239 : * Starting a process records it and makes it findable by provider and by
240 : * the provider's own identifiers.
241 : *
242 : * @param pg the database context
243 : * @return 0 on success
244 : */
245 : static int
246 1 : check_start (struct TALER_EXCHANGEDB_PostgresContext *pg)
247 : {
248 : struct TALER_NormalizedPaytoHashP h_payto;
249 : struct GNUNET_TIME_Absolute expiration;
250 : struct ReferenceContext ctx;
251 1 : char *provider_account_id = NULL;
252 1 : char *provider_legitimization_id = NULL;
253 1 : uint64_t row = 0;
254 1 : bool is_wallet = true;
255 :
256 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
257 : TALER_EXCHANGEDB_insert_legitimization_process (
258 : pg,
259 : &account.h_normalized,
260 : 0,
261 : measure_row,
262 : "test-provider",
263 : "provider-account-1",
264 : "legi-1",
265 : &process_row));
266 1 : FAILIF (0 == process_row);
267 1 : FAILIF (1 != TDB_count (pg,
268 : "FROM legitimization_processes"));
269 :
270 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
271 : TALER_EXCHANGEDB_get_legitimization_process_by_account (
272 : pg,
273 : "test-provider",
274 : &account.h_normalized,
275 : &row,
276 : &expiration,
277 : &provider_account_id,
278 : &provider_legitimization_id,
279 : &is_wallet));
280 1 : FAILIF (row != process_row);
281 1 : FAILIF_C (0 != strcmp (provider_account_id,
282 : "provider-account-1"),
283 : GNUNET_free (provider_account_id);
284 : GNUNET_free (provider_legitimization_id));
285 1 : FAILIF_C (0 != strcmp (provider_legitimization_id,
286 : "legi-1"),
287 : GNUNET_free (provider_account_id);
288 : GNUNET_free (provider_legitimization_id));
289 1 : GNUNET_free (provider_account_id);
290 1 : GNUNET_free (provider_legitimization_id);
291 1 : FAILIF (is_wallet);
292 :
293 : /* another provider has no process on this account */
294 1 : provider_account_id = NULL;
295 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
296 : TALER_EXCHANGEDB_get_legitimization_process_by_account (
297 : pg,
298 : "other-provider",
299 : &account.h_normalized,
300 : &row,
301 : &expiration,
302 : &provider_account_id,
303 : &provider_legitimization_id,
304 : &is_wallet));
305 :
306 : /* the provider's own identifier resolves back to the account */
307 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
308 : TALER_EXCHANGEDB_get_kyc_provider_account (pg,
309 : "test-provider",
310 : "legi-1",
311 : &h_payto,
312 : &is_wallet,
313 : &row));
314 1 : FAILIF (0 != GNUNET_memcmp (&h_payto,
315 : &account.h_normalized));
316 1 : FAILIF (row != process_row);
317 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
318 : TALER_EXCHANGEDB_get_kyc_provider_account (pg,
319 : "test-provider",
320 : "legi-does-not-exist",
321 : &h_payto,
322 : &is_wallet,
323 : &row));
324 :
325 1 : memset (&ctx,
326 : 0,
327 : sizeof (ctx));
328 1 : ctx.provider = "test-provider";
329 1 : FAILIF (0 >=
330 : TALER_EXCHANGEDB_iterate_kyc_references (pg,
331 : &account.h_normalized,
332 : &reference_cb,
333 : &ctx));
334 1 : FAILIF_C (1 != ctx.matched,
335 : GNUNET_free (ctx.user_id); GNUNET_free (ctx.legi_id));
336 1 : FAILIF_C (0 != strcmp (ctx.user_id,
337 : "provider-account-1"),
338 : GNUNET_free (ctx.user_id); GNUNET_free (ctx.legi_id));
339 1 : GNUNET_free (ctx.user_id);
340 1 : GNUNET_free (ctx.legi_id);
341 1 : return 0;
342 : }
343 :
344 :
345 : /**
346 : * Updating a process records the redirect URL and can mark it finished.
347 : *
348 : * @param pg the database context
349 : * @return 0 on success
350 : */
351 : static int
352 1 : check_update (struct TALER_EXCHANGEDB_PostgresContext *pg)
353 : {
354 : struct GNUNET_TIME_Absolute expiration
355 1 : = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS);
356 1 : char *redirect_url = NULL;
357 :
358 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
359 : TALER_EXCHANGEDB_update_legitimization_process_by_row (
360 : pg,
361 : process_row,
362 : "test-provider",
363 : &account.h_normalized,
364 : "provider-account-1",
365 : "legi-1",
366 : "https://kyc.example/start",
367 : expiration,
368 : TALER_EC_NONE,
369 : NULL,
370 : false));
371 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
372 : TALER_EXCHANGEDB_get_pending_legitimization_process (
373 : pg,
374 : &account.h_normalized,
375 : "test-provider",
376 : &redirect_url));
377 1 : FAILIF (NULL == redirect_url);
378 1 : FAILIF_C (0 != strcmp (redirect_url,
379 : "https://kyc.example/start"),
380 : GNUNET_free (redirect_url));
381 1 : GNUNET_free (redirect_url);
382 :
383 : /* a row that does not exist is not created */
384 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
385 : TALER_EXCHANGEDB_update_legitimization_process_by_row (
386 : pg,
387 : process_row + 1000,
388 : "test-provider",
389 : &account.h_normalized,
390 : "provider-account-1",
391 : "legi-1",
392 : "https://kyc.example/start",
393 : expiration,
394 : TALER_EC_NONE,
395 : NULL,
396 : false));
397 1 : FAILIF (1 != TDB_count (pg,
398 : "FROM legitimization_processes"));
399 :
400 : /* marking it finished takes it out of the pending view */
401 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
402 : TALER_EXCHANGEDB_update_legitimization_process_by_row (
403 : pg,
404 : process_row,
405 : "test-provider",
406 : &account.h_normalized,
407 : "provider-account-1",
408 : "legi-1",
409 : "https://kyc.example/start",
410 : expiration,
411 : TALER_EC_NONE,
412 : NULL,
413 : true));
414 1 : redirect_url = NULL;
415 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
416 : TALER_EXCHANGEDB_get_pending_legitimization_process (
417 : pg,
418 : &account.h_normalized,
419 : "test-provider",
420 : &redirect_url));
421 1 : FAILIF (NULL != redirect_url);
422 1 : return 0;
423 : }
424 :
425 :
426 : /**
427 : * A failed KYC check marks the process finished with an error.
428 : *
429 : * @param pg the database context
430 : * @return 0 on success
431 : */
432 : static int
433 1 : check_kyc_failure (struct TALER_EXCHANGEDB_PostgresContext *pg)
434 : {
435 1 : uint64_t row = 0;
436 :
437 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
438 : TALER_EXCHANGEDB_insert_legitimization_process (
439 : pg,
440 : &account.h_normalized,
441 : 1,
442 : measure_row,
443 : "failing-provider",
444 : "provider-account-2",
445 : "legi-2",
446 : &row));
447 1 : FAILIF (2 != TDB_count (pg,
448 : "FROM legitimization_processes"));
449 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
450 : TALER_EXCHANGEDB_insert_kyc_failure (
451 : pg,
452 : row,
453 : &account.h_normalized,
454 : "failing-provider",
455 : "provider-account-2",
456 : "legi-2",
457 : "the provider said no",
458 : TALER_EC_EXCHANGE_KYC_GENERIC_PROVIDER_UNEXPECTED_REPLY));
459 1 : FAILIF (1 != TDB_count (pg,
460 : "FROM legitimization_processes"
461 : " WHERE finished"
462 : " AND error_code=%u",
463 : (unsigned int)
464 : TALER_EC_EXCHANGE_KYC_GENERIC_PROVIDER_UNEXPECTED_REPLY));
465 : /* a row that does not exist is not created */
466 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
467 : TALER_EXCHANGEDB_insert_kyc_failure (
468 : pg,
469 : row + 1000,
470 : &account.h_normalized,
471 : "failing-provider",
472 : "provider-account-2",
473 : "legi-2",
474 : "the provider said no",
475 : TALER_EC_EXCHANGE_KYC_GENERIC_PROVIDER_UNEXPECTED_REPLY));
476 1 : FAILIF (2 != TDB_count (pg,
477 : "FROM legitimization_processes"));
478 1 : return 0;
479 : }
480 :
481 :
482 : /**
483 : * A failed AML program marks its process finished with an error too.
484 : *
485 : * @param pg the database context
486 : * @return 0 on success
487 : */
488 : static int
489 1 : check_aml_program_failure (struct TALER_EXCHANGEDB_PostgresContext *pg)
490 : {
491 1 : uint64_t row = 0;
492 :
493 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
494 : TALER_EXCHANGEDB_insert_legitimization_process (
495 : pg,
496 : &account.h_normalized,
497 : 2,
498 : measure_row,
499 : "aml-provider",
500 : "provider-account-3",
501 : "legi-3",
502 : &row));
503 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
504 : TALER_EXCHANGEDB_insert_aml_program_failure (
505 : pg,
506 : row,
507 : &account.h_normalized,
508 : "the AML program crashed",
509 : TALER_EC_EXCHANGE_KYC_AML_PROGRAM_FAILURE));
510 1 : FAILIF (1 != TDB_count (pg,
511 : "FROM legitimization_processes"
512 : " WHERE finished"
513 : " AND error_code=%u",
514 : (unsigned int)
515 : TALER_EC_EXCHANGE_KYC_AML_PROGRAM_FAILURE));
516 : /* Unlike insert_kyc_failure(), a row that does not exist is *created*
517 : here rather than ignored -- the stored procedure would rather keep a
518 : record of the failed AML program than lose it. */
519 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
520 : TALER_EXCHANGEDB_insert_aml_program_failure (
521 : pg,
522 : row + 1000,
523 : &account.h_normalized,
524 : "the AML program crashed",
525 : TALER_EC_EXCHANGE_KYC_AML_PROGRAM_FAILURE));
526 1 : FAILIF (4 != TDB_count (pg,
527 : "FROM legitimization_processes"));
528 1 : return 0;
529 : }
530 :
531 :
532 : /**
533 : * The reference listing reports every provider that worked on the
534 : * account.
535 : *
536 : * @param pg the database context
537 : * @return 0 on success
538 : */
539 : static int
540 1 : check_references (struct TALER_EXCHANGEDB_PostgresContext *pg)
541 : {
542 : struct ReferenceContext ctx;
543 :
544 1 : memset (&ctx,
545 : 0,
546 : sizeof (ctx));
547 1 : ctx.provider = "aml-provider";
548 1 : FAILIF (0 >=
549 : TALER_EXCHANGEDB_iterate_kyc_references (pg,
550 : &account.h_normalized,
551 : &reference_cb,
552 : &ctx));
553 1 : FAILIF_C (1 != ctx.matched,
554 : GNUNET_free (ctx.user_id); GNUNET_free (ctx.legi_id));
555 1 : FAILIF_C (4 != ctx.total,
556 : GNUNET_free (ctx.user_id); GNUNET_free (ctx.legi_id));
557 1 : GNUNET_free (ctx.user_id);
558 1 : GNUNET_free (ctx.legi_id);
559 :
560 : /* an account nobody checked has no references */
561 : {
562 : struct TALER_NormalizedPaytoHashP other;
563 :
564 1 : TDB_FILL (other,
565 : 98);
566 1 : memset (&ctx,
567 : 0,
568 : sizeof (ctx));
569 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
570 : TALER_EXCHANGEDB_iterate_kyc_references (pg,
571 : &other,
572 : &reference_cb,
573 : &ctx));
574 1 : FAILIF (0 != ctx.total);
575 : }
576 1 : return 0;
577 : }
578 :
579 :
580 : /**
581 : * Process initiation is reserved atomically, completed only by the owner,
582 : * and restarted after its provider-side expiration.
583 : *
584 : * @param pg the database context
585 : * @return 0 on success
586 : */
587 : static int
588 1 : check_reservation (struct TALER_EXCHANGEDB_PostgresContext *pg)
589 : {
590 1 : const char *provider = "reservation-provider";
591 1 : struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
592 : struct GNUNET_TIME_Absolute lease_expiration
593 1 : = GNUNET_TIME_absolute_add (now,
594 : GNUNET_TIME_UNIT_MINUTES);
595 : struct GNUNET_TIME_Absolute process_expiration
596 1 : = GNUNET_TIME_absolute_add (now,
597 : GNUNET_TIME_UNIT_HOURS);
598 : struct GNUNET_TIME_Absolute start_time;
599 : struct GNUNET_TIME_Absolute other_start_time;
600 : struct GNUNET_TIME_Absolute restart_time;
601 : struct GNUNET_TIME_Absolute restart_lease;
602 : enum TALER_EXCHANGEDB_KycProcessReservationState state;
603 : uint64_t row;
604 : uint64_t other_row;
605 1 : char *redirect_url = NULL;
606 :
607 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
608 : TALER_EXCHANGEDB_do_reserve_legitimization_process (
609 : pg,
610 : &account.h_normalized,
611 : 3,
612 : measure_row,
613 : provider,
614 : now,
615 : lease_expiration,
616 : &row,
617 : &start_time,
618 : &redirect_url,
619 : &state));
620 1 : FAILIF (TALER_EXCHANGEDB_KPRS_OWNER != state);
621 1 : FAILIF (NULL != redirect_url);
622 :
623 : /* A concurrent request must wait for the reservation owner. */
624 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
625 : TALER_EXCHANGEDB_do_reserve_legitimization_process (
626 : pg,
627 : &account.h_normalized,
628 : 3,
629 : measure_row,
630 : provider,
631 : now,
632 : lease_expiration,
633 : &other_row,
634 : &other_start_time,
635 : &redirect_url,
636 : &state));
637 1 : FAILIF (TALER_EXCHANGEDB_KPRS_BUSY != state);
638 1 : FAILIF (row != other_row);
639 1 : FAILIF (start_time.abs_value_us != other_start_time.abs_value_us);
640 1 : FAILIF (NULL != redirect_url);
641 :
642 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
643 : TALER_EXCHANGEDB_update_legitimization_process_start (
644 : pg,
645 : row,
646 : start_time,
647 : provider,
648 : &account.h_normalized,
649 : "provider-account-reservation",
650 : "provider-process-reservation",
651 : "https://kyc.example/reserved",
652 : process_expiration,
653 : TALER_EC_NONE,
654 : NULL,
655 : false));
656 :
657 : /* Once initiation completed, all requests reuse its redirect. */
658 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
659 : TALER_EXCHANGEDB_do_reserve_legitimization_process (
660 : pg,
661 : &account.h_normalized,
662 : 3,
663 : measure_row,
664 : provider,
665 : now,
666 : lease_expiration,
667 : &other_row,
668 : &other_start_time,
669 : &redirect_url,
670 : &state));
671 1 : FAILIF (TALER_EXCHANGEDB_KPRS_READY != state);
672 1 : FAILIF (row != other_row);
673 1 : FAILIF (NULL == redirect_url);
674 1 : FAILIF_C (0 != strcmp (redirect_url,
675 : "https://kyc.example/reserved"),
676 : GNUNET_free (redirect_url));
677 1 : GNUNET_free (redirect_url);
678 1 : redirect_url = NULL;
679 :
680 : /* A callback from a superseded owner cannot overwrite the process. */
681 1 : other_start_time = GNUNET_TIME_absolute_add (
682 : start_time,
683 : GNUNET_TIME_UNIT_SECONDS);
684 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
685 : TALER_EXCHANGEDB_update_legitimization_process_start (
686 : pg,
687 : row,
688 : other_start_time,
689 : provider,
690 : &account.h_normalized,
691 : NULL,
692 : NULL,
693 : "https://kyc.example/late",
694 : process_expiration,
695 : TALER_EC_NONE,
696 : NULL,
697 : false));
698 :
699 : /* Expiration makes the next request the owner of a fresh start. */
700 1 : restart_time = GNUNET_TIME_absolute_add (
701 : process_expiration,
702 : GNUNET_TIME_UNIT_SECONDS);
703 1 : restart_lease = GNUNET_TIME_absolute_add (
704 : restart_time,
705 : GNUNET_TIME_UNIT_MINUTES);
706 1 : FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
707 : TALER_EXCHANGEDB_do_reserve_legitimization_process (
708 : pg,
709 : &account.h_normalized,
710 : 3,
711 : measure_row,
712 : provider,
713 : restart_time,
714 : restart_lease,
715 : &other_row,
716 : &other_start_time,
717 : &redirect_url,
718 : &state));
719 1 : FAILIF (TALER_EXCHANGEDB_KPRS_OWNER != state);
720 1 : FAILIF (row != other_row);
721 1 : FAILIF (start_time.abs_value_us == other_start_time.abs_value_us);
722 1 : FAILIF (NULL != redirect_url);
723 1 : return 0;
724 : }
725 :
726 :
727 : /**
728 : * The checks to run, in order.
729 : */
730 : static const struct TDB_Test tests[] = {
731 : { "legitimization-processes-empty",
732 : &check_empty },
733 : { "legitimization-processes-start",
734 : &check_start },
735 : { "legitimization-processes-update",
736 : &check_update },
737 : { "legitimization-processes-kyc-failure",
738 : &check_kyc_failure },
739 : { "legitimization-processes-aml-program-failure",
740 : &check_aml_program_failure },
741 : { "legitimization-processes-references",
742 : &check_references },
743 : { "legitimization-processes-reservation",
744 : &check_reservation },
745 : { NULL, NULL }
746 : };
747 :
748 :
749 : int
750 1 : main (int argc,
751 : char *const *argv)
752 : {
753 : int ret;
754 :
755 1 : ret = TDB_main (argc,
756 : argv,
757 : "test-legitimization-processes",
758 : "Tests for the exchangedb `legitimization_processes' table",
759 : tests);
760 1 : TDB_account_free (&account);
761 1 : return ret;
762 : }
763 :
764 :
765 : /* end of test_legitimization_processes.c */
|