diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_kyc-webhook.c')
-rw-r--r-- | src/exchange/taler-exchange-httpd_kyc-webhook.c | 144 |
1 files changed, 108 insertions, 36 deletions
diff --git a/src/exchange/taler-exchange-httpd_kyc-webhook.c b/src/exchange/taler-exchange-httpd_kyc-webhook.c index 73038c139..b92b43e69 100644 --- a/src/exchange/taler-exchange-httpd_kyc-webhook.c +++ b/src/exchange/taler-exchange-httpd_kyc-webhook.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -24,9 +24,11 @@ #include <jansson.h> #include <microhttpd.h> #include <pthread.h> +#include "taler_attributes.h" #include "taler_json_lib.h" #include "taler_mhd_lib.h" #include "taler_kyclogic_lib.h" +#include "taler-exchange-httpd_common_kyc.h" #include "taler-exchange-httpd_kyc-webhook.h" #include "taler-exchange-httpd_responses.h" @@ -53,6 +55,11 @@ struct KycWebhookContext struct TEH_RequestContext *rc; /** + * Handle for the KYC-AML trigger interaction. + */ + struct TEH_KycAmlTrigger *kat; + + /** * Plugin responsible for the webhook. */ struct TALER_KYCLOGIC_Plugin *plugin; @@ -140,8 +147,29 @@ TEH_kyc_webhook_cleanup (void) /** - * Function called with the result of a webhook - * operation. + * Function called after the KYC-AML trigger is done. + * + * @param cls closure with a `struct KycWebhookContext *` + * @param http_status final HTTP status to return + * @param[in] response final HTTP ro return + */ +static void +kyc_aml_webhook_finished ( + void *cls, + unsigned int http_status, + struct MHD_Response *response) +{ + struct KycWebhookContext *kwh = cls; + + kwh->kat = NULL; + kwh->response = response; + kwh->response_code = http_status; + kwh_resume (kwh); +} + + +/** + * Function called with the result of a KYC webhook operation. * * Note that the "decref" for the @a response * will be done by the plugin. @@ -154,6 +182,7 @@ TEH_kyc_webhook_cleanup (void) * @param provider_legitimization_id set to legitimization process ID at the provider, or NULL if not supported or unknown * @param status KYC status * @param expiration until when is the KYC check valid + * @param attributes user attributes returned by the provider * @param http_status HTTP status code of @a response * @param[in] response to return to the HTTP client */ @@ -167,6 +196,7 @@ webhook_finished_cb ( const char *provider_legitimization_id, enum TALER_KYCLOGIC_KycStatus status, struct GNUNET_TIME_Absolute expiration, + const json_t *attributes, unsigned int http_status, struct MHD_Response *response) { @@ -176,26 +206,53 @@ webhook_finished_cb ( switch (status) { case TALER_KYCLOGIC_STATUS_SUCCESS: - /* _successfully_ resumed case */ + kwh->kat = TEH_kyc_finished ( + &kwh->rc->async_scope_id, + process_row, + account_id, + provider_section, + provider_user_id, + provider_legitimization_id, + expiration, + attributes, + http_status, + response, + &kyc_aml_webhook_finished, + kwh); + if (NULL == kwh->kat) + { + if (NULL != response) + MHD_destroy_response (response); + http_status = MHD_HTTP_INTERNAL_SERVER_ERROR; + response = TALER_MHD_make_error ( + TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION, + "[exchange] AML_KYC_TRIGGER"); + break; + } + return; + case TALER_KYCLOGIC_STATUS_FAILED: + case TALER_KYCLOGIC_STATUS_PROVIDER_FAILED: + case TALER_KYCLOGIC_STATUS_USER_ABORTED: + case TALER_KYCLOGIC_STATUS_ABORTED: + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "KYC process %s/%s (Row #%llu) failed: %d\n", + provider_user_id, + provider_legitimization_id, + (unsigned long long) process_row, + status); + if (! TEH_kyc_failed (process_row, + account_id, + provider_section, + provider_user_id, + provider_legitimization_id)) { - enum GNUNET_DB_QueryStatus qs; - - qs = TEH_plugin->update_kyc_process_by_row (TEH_plugin->cls, - process_row, - provider_section, - account_id, - provider_user_id, - provider_legitimization_id, - expiration); - if (qs < 0) - { - GNUNET_break (0); - kwh->response = TALER_MHD_make_error (TALER_EC_GENERIC_DB_STORE_FAILED, - "set_kyc_ok"); - kwh->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; - kwh_resume (kwh); - return; - } + GNUNET_break (0); + if (NULL != response) + MHD_destroy_response (response); + http_status = MHD_HTTP_INTERNAL_SERVER_ERROR; + response = TALER_MHD_make_error ( + TALER_EC_GENERIC_DB_STORE_FAILED, + "insert_kyc_failure"); } break; default: @@ -204,12 +261,13 @@ webhook_finished_cb ( provider_user_id, provider_legitimization_id, (unsigned long long) process_row, - status); + (int) status); break; } - kwh->response = response; - kwh->response_code = http_status; - kwh_resume (kwh); + GNUNET_break (NULL == kwh->kat); + kyc_aml_webhook_finished (kwh, + http_status, + response); } @@ -228,6 +286,11 @@ clean_kwh (struct TEH_RequestContext *rc) kwh->plugin->webhook_cancel (kwh->wh); kwh->wh = NULL; } + if (NULL != kwh->kat) + { + TEH_kyc_finished_cancel (kwh->kat); + kwh->kat = NULL; + } if (NULL != kwh->response) { MHD_destroy_response (kwh->response); @@ -262,11 +325,12 @@ handler_kyc_webhook_generic ( rc->rh_ctx = kwh; rc->rh_cleaner = &clean_kwh; - if (GNUNET_OK != - TALER_KYCLOGIC_lookup_logic (args[0], - &kwh->plugin, - &kwh->pd, - &kwh->provider_section)) + if ( (NULL == args[0]) || + (GNUNET_OK != + TALER_KYCLOGIC_lookup_logic (args[0], + &kwh->plugin, + &kwh->pd, + &kwh->provider_section)) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "KYC logic `%s' unknown (check KYC provider configuration)\n", @@ -274,8 +338,12 @@ handler_kyc_webhook_generic ( return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_NOT_FOUND, TALER_EC_EXCHANGE_KYC_GENERIC_LOGIC_UNKNOWN, - "$NAME"); + args[0]); } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "KYC logic `%s' mapped to section %s\n", + args[0], + kwh->provider_section); kwh->wh = kwh->plugin->webhook (kwh->plugin->cls, kwh->pd, TEH_plugin->kyc_provider_account_lookup, @@ -301,13 +369,17 @@ handler_kyc_webhook_generic ( MHD_suspend_connection (rc->connection); return MHD_YES; } + GNUNET_break (GNUNET_NO == kwh->suspended); if (NULL != kwh->response) { - /* handle _failed_ resumed cases */ - return MHD_queue_response (rc->connection, - kwh->response_code, - kwh->response); + MHD_RESULT res; + + res = MHD_queue_response (rc->connection, + kwh->response_code, + kwh->response); + GNUNET_break (MHD_YES == res); + return res; } /* We resumed, but got no response? This should |