diff options
Diffstat (limited to 'src/lib/merchant_api_get_kyc.c')
-rw-r--r-- | src/lib/merchant_api_get_kyc.c | 188 |
1 files changed, 110 insertions, 78 deletions
diff --git a/src/lib/merchant_api_get_kyc.c b/src/lib/merchant_api_get_kyc.c index bc688eed..d2a819ea 100644 --- a/src/lib/merchant_api_get_kyc.c +++ b/src/lib/merchant_api_get_kyc.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2021 Taler Systems SA + Copyright (C) 2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -32,6 +32,11 @@ /** + * Maximum length of the KYC arrays supported. + */ +#define MAX_KYC 1024 + +/** * Handle for a GET /kyc operation. */ struct TALER_MERCHANT_KycGetHandle @@ -76,70 +81,91 @@ struct TALER_MERCHANT_KycGetHandle static enum GNUNET_GenericReturnValue parse_kyc (struct TALER_MERCHANT_KycGetHandle *kyc, struct TALER_MERCHANT_KycResponse *kr, - json_t *pends, - json_t *touts) + const json_t *pends, + const json_t *touts) { - unsigned int num_pends = json_array_size (pends); - unsigned int num_touts = json_array_size (touts); - struct TALER_MERCHANT_AccountKycRedirectDetail pending_kycs[GNUNET_NZL ( - num_pends)]; - struct TALER_MERCHANT_ExchangeKycFailureDetail timeout_kycs[GNUNET_NZL ( - num_touts)]; - - for (unsigned int i = 0; i<num_pends; i++) + unsigned int num_pends = (unsigned int) json_array_size (pends); + unsigned int num_touts = (unsigned int) json_array_size (touts); + + if ( (json_array_size (pends) != (size_t) num_pends) || + (num_pends > MAX_KYC) ) { - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("kyc_url", - &pending_kycs[i].kyc_url), - GNUNET_JSON_spec_string ("exchange_url", - &pending_kycs[i].exchange_url), - GNUNET_JSON_spec_string ("payto_uri", - &pending_kycs[i].payto_uri), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json_array_get (pends, - i), - spec, - NULL, NULL)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } + GNUNET_break (0); + return GNUNET_SYSERR; + } + if ( (json_array_size (touts) != (size_t) num_touts) || + (num_touts > MAX_KYC) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; } - for (unsigned int i = 0; i<num_touts; i++) + { - uint32_t hs; - uint32_t ec; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("exchange_url", - &timeout_kycs[i].exchange_url), - GNUNET_JSON_spec_uint32 ("exchange_code", - &ec), - GNUNET_JSON_spec_uint32 ("exchange_http_status", - &hs), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json_array_get (touts, - i), - spec, - NULL, NULL)) + struct TALER_MERCHANT_AccountKycRedirectDetail pending_kycs[ + GNUNET_NZL (num_pends)]; + struct TALER_MERCHANT_ExchangeKycFailureDetail timeout_kycs[ + GNUNET_NZL (num_touts)]; + + memset (pending_kycs, + 0, + sizeof (pending_kycs)); + for (unsigned int i = 0; i<num_pends; i++) + { + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_mark_optional ( + TALER_JSON_spec_web_url ("kyc_url", + &pending_kycs[i].kyc_url), + NULL), + TALER_JSON_spec_aml_decision ("aml_status", + &pending_kycs[i].aml_status), + TALER_JSON_spec_web_url ("exchange_url", + &pending_kycs[i].exchange_url), + TALER_JSON_spec_payto_uri ("payto_uri", + &pending_kycs[i].payto_uri), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (json_array_get (pends, + i), + spec, + NULL, NULL)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + for (unsigned int i = 0; i<num_touts; i++) { - GNUNET_break (0); - return GNUNET_SYSERR; + uint32_t hs; + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_web_url ("exchange_url", + &timeout_kycs[i].exchange_url), + TALER_JSON_spec_ec ("exchange_code", + &timeout_kycs[i].exchange_code), + GNUNET_JSON_spec_uint32 ("exchange_http_status", + &hs), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (json_array_get (touts, + i), + spec, + NULL, NULL)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + timeout_kycs[i].exchange_http_status = (unsigned int) hs; } - timeout_kycs[i].exchange_http_status = (unsigned int) hs; - timeout_kycs[i].exchange_code = (enum TALER_ErrorCode) ec; + kr->details.kyc_status.pending_kycs = pending_kycs; + kr->details.kyc_status.timeout_kycs = timeout_kycs; + kr->details.kyc_status.pending_kycs_length = num_pends; + kr->details.kyc_status.timeout_kycs_length = num_touts; + kyc->cb (kyc->cb_cls, + kr); } - kr->details.kyc_status.pending_kycs = pending_kycs; - kr->details.kyc_status.timeout_kycs = timeout_kycs; - kr->details.kyc_status.pending_kycs_length = num_pends; - kr->details.kyc_status.timeout_kycs_length = num_touts; - kyc->cb (kyc->cb_cls, - kr); return GNUNET_OK; } @@ -176,13 +202,13 @@ handle_get_kyc_finished (void *cls, case MHD_HTTP_BAD_GATEWAY: case MHD_HTTP_GATEWAY_TIMEOUT: { - json_t *pends; - json_t *touts; + const json_t *pends; + const json_t *touts; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_json ("pending_kycs", - &pends), - GNUNET_JSON_spec_json ("timeout_kycs", - &touts), + GNUNET_JSON_spec_array_const ("pending_kycs", + &pends), + GNUNET_JSON_spec_array_const ("timeout_kycs", + &touts), GNUNET_JSON_spec_end () }; @@ -195,20 +221,17 @@ handle_get_kyc_finished (void *cls, kr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } - if ( (! json_is_array (pends)) || - (! json_is_array (touts)) || - (GNUNET_OK != - parse_kyc (kyc, - &kr, - pends, - touts)) ) + if (GNUNET_OK != + parse_kyc (kyc, + &kr, + pends, + touts)) { kr.hr.http_status = 0; kr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } /* parse_kyc called the continuation already */ - GNUNET_JSON_parse_free (spec); TALER_MERCHANT_kyc_get_cancel (kyc); return; } @@ -260,17 +283,19 @@ kyc_get (struct GNUNET_CURL_Context *ctx, struct TALER_MERCHANT_KycGetHandle *kyc; CURL *eh; char timeout_ms[32]; + unsigned int tms; kyc = GNUNET_new (struct TALER_MERCHANT_KycGetHandle); kyc->ctx = ctx; kyc->cb = cb; kyc->cb_cls = cb_cls; + tms = (unsigned int) (timeout.rel_value_us + / GNUNET_TIME_UNIT_MILLISECONDS. + rel_value_us); GNUNET_snprintf (timeout_ms, sizeof (timeout_ms), - "%llu", - (unsigned long long) (timeout.rel_value_us - / GNUNET_TIME_UNIT_MILLISECONDS. - rel_value_us)); + "%u", + tms); kyc->url = TALER_url_join (url, "kyc", "h_wire", @@ -298,6 +323,13 @@ kyc_get (struct GNUNET_CURL_Context *ctx, "Requesting URL '%s'\n", kyc->url); eh = TALER_MERCHANT_curl_easy_get_ (kyc->url); + if (0 != tms) + { + GNUNET_break (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_TIMEOUT_MS, + (long) (tms + 100L))); + } kyc->job = GNUNET_CURL_job_add (ctx, eh, &handle_get_kyc_finished, @@ -321,7 +353,7 @@ TALER_MERCHANT_kyc_get (struct GNUNET_CURL_Context *ctx, "%sprivate/", backend_url); return kyc_get (ctx, - url, + url, /* consumed! */ h_wire, exchange_url, timeout, @@ -347,7 +379,7 @@ TALER_MERCHANT_management_kyc_get (struct GNUNET_CURL_Context *ctx, backend_url, instance_id); return kyc_get (ctx, - url, + url, /* consumed! */ h_wire, exchange_url, timeout, |