merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit da2e3961570f9f4da8bd20ddb8d5c581131412f4
parent 985e44ce78eaaf3f2076f87ca7f6481af5608b2e
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun,  8 Sep 2024 10:08:22 +0200

allow other processes to immediately trigger KYC check

Diffstat:
Msrc/backend/taler-merchant-kyccheck.c | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/include/taler_merchantdb_plugin.h | 5+++++
2 files changed, 136 insertions(+), 2 deletions(-)

diff --git a/src/backend/taler-merchant-kyccheck.c b/src/backend/taler-merchant-kyccheck.c @@ -281,6 +281,13 @@ static struct GNUNET_DB_EventHandler *eh_accounts; static struct GNUNET_DB_EventHandler *eh_keys; /** + * Event handler to learn that there was a KYC + * rule triggered and we need to check the KYC + * status for an account. + */ +static struct GNUNET_DB_EventHandler *eh_rule; + +/** * Main task to discover (new) accounts. */ static struct GNUNET_SCHEDULER_Task *account_task; @@ -739,8 +746,12 @@ start_inquiry (struct Exchange *e, switch (i->last_http_status) { case MHD_HTTP_OK: - /* KYC is OK, only check again if triggered */ - i->due = GNUNET_TIME_UNIT_FOREVER_ABS; + /* KYC is OK, but we could have missed some triggers, + so let's check, but slowly within the next minute + so that we do not overdo it if this process happens + to be restarted a lot. */ + i->due = GNUNET_TIME_relative_to_absolute ( + GNUNET_TIME_randomize (GNUNET_TIME_UNIT_MINUTES)); break; case MHD_HTTP_ACCEPTED: /* KYC required, due immediately */ @@ -1072,6 +1083,106 @@ keys_changed (void *cls, /** + * Function called when a KYC rule was triggered by + * a transaction and we need to get the latest KYC + * status immediately. + * + * @param cls closure (NULL) + * @param extra additional event data provided + * @param extra_size number of bytes in @a extra + */ +static void +rule_triggered (void *cls, + const void *extra, + size_t extra_size) +{ + const char *text = extra; + const char *space; + struct TALER_MerchantWireHashP h_wire; + const char *exchange_url; + + (void) cls; + if ( (NULL == extra) || + (0 == extra_size) ) + { + GNUNET_break (0); + return; + } + if ('\0' != text[extra_size - 1]) + { + GNUNET_break (0); + return; + } + space = memchr (extra, + ' ', + extra_size); + if (NULL == space) + { + GNUNET_break (0); + return; + } + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (extra, + space - text, + &h_wire, + sizeof (h_wire))) + { + GNUNET_break (0); + return; + } + exchange_url = &space[1]; + if (! TALER_is_web_url (exchange_url)) + { + GNUNET_break (0); + return; + } + + for (struct Account *a = a_head; + NULL != a; + a = a->next) + { + if (0 != + GNUNET_memcmp (&h_wire, + &a->h_wire)) + continue; + for (struct Inquiry *i = a->i_head; + NULL != i; + i = i->next) + { + if (0 != strcmp (exchange_url, + i->e->keys->exchange_url)) + continue; + i->kyc_ok = false; + i->due = GNUNET_TIME_UNIT_ZERO_ABS; + if (NULL != i->task) + { + GNUNET_SCHEDULER_cancel (i->task); + i->task = NULL; + } + if (NULL != i->kyc) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "/kyc-check already running for %s\n", + text); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Starting %skyc-check for `%s' due to KYC rule trigger\n", + exchange_url, + i->a->merchant_account_uri); + i->task = GNUNET_SCHEDULER_add_at (i->due, + &inquiry_work, + i); + return; + } + } + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "KYC rule trigger notification `%s' matches none of our accounts\n", + text); +} + + +/** * Function called on each configuration section. Finds sections * about exchanges, parses the entries. * @@ -1164,6 +1275,11 @@ shutdown_task (void *cls) db_plugin->event_listen_cancel (eh_keys); eh_keys = NULL; } + if (NULL != eh_rule) + { + db_plugin->event_listen_cancel (eh_rule); + eh_rule = NULL; + } TALER_MERCHANTDB_plugin_unload (db_plugin); db_plugin = NULL; cfg = NULL; @@ -1241,6 +1357,19 @@ run (void *cls, &keys_changed, NULL); } + { + struct GNUNET_DB_EventHeaderP es = { + .size = htons (sizeof (es)), + .type = htons (TALER_DBEVENT_MERCHANT_EXCHANGE_KYC_RULE_TRIGGERED) + }; + + eh_rule + = db_plugin->event_listen (db_plugin->cls, + &es, + GNUNET_TIME_UNIT_FOREVER_REL, + &rule_triggered, + NULL); + } GNUNET_CONFIGURATION_iterate_sections (cfg, &accept_exchanges, NULL); diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h @@ -77,6 +77,11 @@ struct TALER_MerchantAuthenticationSaltP }; +/** + * Format of the data hashed to generate the notification + * string whenever the KYC status for an account has + * changed. + */ struct TALER_MERCHANTDB_MerchantKycStatusChangeEventP { /**