diff options
author | Christian Grothoff <christian@grothoff.org> | 2024-07-07 11:59:57 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2024-07-29 12:18:44 +0200 |
commit | e7dabf1a7a6cf8f98beb51139332d5e58c8ad4b0 (patch) | |
tree | 1fb45bf7dba974f46108390e8ecd71647eaa8cd5 | |
parent | 58f4b09d0d182d3eeccd2cde2cd8bfdaae8ad317 (diff) |
start on kyc_start API
-rw-r--r-- | src/include/taler_exchange_service.h | 36 | ||||
-rw-r--r-- | src/lib/Makefile.am | 1 | ||||
-rw-r--r-- | src/lib/exchange_api_kyc_check.c | 25 | ||||
-rw-r--r-- | src/lib/exchange_api_kyc_proof.c | 2 | ||||
-rw-r--r-- | src/lib/exchange_api_kyc_start.c | 201 | ||||
-rw-r--r-- | src/lib/exchange_api_kyc_wallet.c | 21 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_kyc_check_get.c | 6 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_kyc_proof.c | 8 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_kyc_wallet_get.c | 6 |
9 files changed, 247 insertions, 59 deletions
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index f1cd77891..fd9cc1f7c 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -4301,14 +4301,9 @@ struct TALER_EXCHANGE_AccountKycStatus struct TALER_EXCHANGE_KycStatus { /** - * HTTP status code returned by the exchange. - */ - unsigned int http_status; - - /** - * Taler error code, if any. + * HTTP response data */ - enum TALER_ErrorCode ec; + struct TALER_EXCHANGE_HttpResponse hr; /** * Details depending on @e http_status. @@ -4565,14 +4560,9 @@ struct TALER_EXCHANGE_KycStartHandle; struct TALER_EXCHANGE_KycStartResponse { /** - * HTTP status code returned by the exchange. - */ - unsigned int http_status; - - /** - * Taler error code, if any. + * HTTP response data */ - enum TALER_ErrorCode ec; + struct TALER_EXCHANGE_HttpResponse hr; /** * Details depending on @e http_status. @@ -4610,9 +4600,8 @@ typedef void /** - * Run interaction with exchange to check KYC - * information for a merchant or wallet account - * identified via a @a token. + * Run interaction with exchange to check KYC information for a merchant or + * wallet account identified via a @a id. * * @param ctx CURL context * @param url exchange base URL @@ -4645,9 +4634,9 @@ TALER_EXCHANGE_kyc_start_cancel (struct TALER_EXCHANGE_KycStartHandle *ksh); struct TALER_EXCHANGE_KycProofResponse { /** - * HTTP status code returned by the exchange. + * HTTP response data */ - unsigned int http_status; + struct TALER_EXCHANGE_HttpResponse hr; union { @@ -4733,14 +4722,9 @@ struct TALER_EXCHANGE_WalletKycResponse { /** - * HTTP status code returned by the exchange. - */ - unsigned int http_status; - - /** - * Taler error code, if any. + * HTTP response data */ - enum TALER_ErrorCode ec; + struct TALER_EXCHANGE_HttpResponse hr; /** * Variants depending on @e http_status. diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 7c1afc696..4e834461c 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -40,6 +40,7 @@ libtalerexchange_la_SOURCES = \ exchange_api_get_kyc_statistics.c \ exchange_api_kyc_check.c \ exchange_api_kyc_info.c \ + exchange_api_kyc_start.c \ exchange_api_kyc_proof.c \ exchange_api_kyc_wallet.c \ exchange_api_link.c \ diff --git a/src/lib/exchange_api_kyc_check.c b/src/lib/exchange_api_kyc_check.c index ef9e83d59..4f1df077f 100644 --- a/src/lib/exchange_api_kyc_check.c +++ b/src/lib/exchange_api_kyc_check.c @@ -149,14 +149,15 @@ handle_kyc_check_finished (void *cls, struct TALER_EXCHANGE_KycCheckHandle *kch = cls; const json_t *j = response; struct TALER_EXCHANGE_KycStatus ks = { - .http_status = (unsigned int) response_code + .hr.reply = j, + .hr.http_status = (unsigned int) response_code }; kch->job = NULL; switch (response_code) { case 0: - ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + ks.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_OK: { @@ -167,8 +168,8 @@ handle_kyc_check_finished (void *cls, &ks.details.ok)) { GNUNET_break_op (0); - ks.http_status = 0; - ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + ks.hr.http_status = 0; + ks.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } TALER_EXCHANGE_kyc_check_cancel (kch); @@ -183,8 +184,8 @@ handle_kyc_check_finished (void *cls, &ks.details.accepted)) { GNUNET_break_op (0); - ks.http_status = 0; - ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + ks.hr.http_status = 0; + ks.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } TALER_EXCHANGE_kyc_check_cancel (kch); @@ -193,29 +194,29 @@ handle_kyc_check_finished (void *cls, case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - ks.ec = TALER_JSON_get_error_code (j); + ks.hr.ec = TALER_JSON_get_error_code (j); /* This should never happen, either us or the exchange is buggy (or API version conflict); just pass JSON reply to the application */ break; case MHD_HTTP_FORBIDDEN: - ks.ec = TALER_JSON_get_error_code (j); + ks.hr.ec = TALER_JSON_get_error_code (j); break; case MHD_HTTP_NOT_FOUND: - ks.ec = TALER_JSON_get_error_code (j); + ks.hr.ec = TALER_JSON_get_error_code (j); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: - ks.ec = TALER_JSON_get_error_code (j); + ks.hr.ec = TALER_JSON_get_error_code (j); /* Server had an internal issue; we should retry, but this API leaves this to the application */ break; default: /* unexpected response code */ GNUNET_break_op (0); - ks.ec = TALER_JSON_get_error_code (j); + ks.hr.ec = TALER_JSON_get_error_code (j); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange kyc_check\n", (unsigned int) response_code, - (int) ks.ec); + (int) ks.hr.ec); break; } kch->cb (kch->cb_cls, diff --git a/src/lib/exchange_api_kyc_proof.c b/src/lib/exchange_api_kyc_proof.c index e7cc9c4cf..8be30dbcf 100644 --- a/src/lib/exchange_api_kyc_proof.c +++ b/src/lib/exchange_api_kyc_proof.c @@ -81,7 +81,7 @@ handle_kyc_proof_finished (void *cls, { struct TALER_EXCHANGE_KycProofHandle *kph = cls; struct TALER_EXCHANGE_KycProofResponse kpr = { - .http_status = (unsigned int) response_code + .hr.http_status = (unsigned int) response_code }; (void) body; diff --git a/src/lib/exchange_api_kyc_start.c b/src/lib/exchange_api_kyc_start.c new file mode 100644 index 000000000..753916ae6 --- /dev/null +++ b/src/lib/exchange_api_kyc_start.c @@ -0,0 +1,201 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see + <http://www.gnu.org/licenses/> +*/ +/** + * @file lib/exchange_api_kyc_start.c + * @brief functions to start a KYC process + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_json_lib.h" +#include <gnunet/gnunet_curl_lib.h> +#include "taler_exchange_service.h" +#include "exchange_api_curl_defaults.h" +#include "taler_signatures.h" +#include "taler_curl_lib.h" +#include "taler_json_lib.h" + + +struct TALER_EXCHANGE_KycStartHandle +{ + + /** + * The url for this request. + */ + char *url; + + /** + * Minor context that holds body and headers. + */ + struct TALER_CURL_PostContext post_ctx; + + /** + * Handle for the request. + */ + struct GNUNET_CURL_Job *job; + + /** + * Function to call with the result. + */ + TALER_EXCHANGE_KycStartCallback cb; + + /** + * Closure for @a cb. + */ + void *cb_cls; + + /** + * Reference to the execution context. + */ + struct GNUNET_CURL_Context *ctx; +}; + + +/** + * Function called when we're done processing the + * HTTP POST /kyc-start/$ID request. + * + * @param cls the `struct TALER_EXCHANGE_KycStartHandle *` + * @param response_code HTTP response code, 0 on error + * @param response response body, NULL if not in JSON + */ +static void +handle_kyc_start_finished (void *cls, + long response_code, + const void *response) +{ + struct TALER_EXCHANGE_KycStartHandle *wh = cls; + const json_t *json = response; + struct TALER_EXCHANGE_KycStartResponse adr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json + }; + + wh->job = NULL; + switch (response_code) + { + case 0: + /* no reply */ + adr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + adr.hr.hint = "server offline?"; + break; + case MHD_HTTP_OK: + // FIXME! + break; + case MHD_HTTP_NOT_FOUND: + break; + default: + /* unexpected response code */ + GNUNET_break_op (0); + adr.hr.ec = TALER_JSON_get_error_code (json); + adr.hr.hint = TALER_JSON_get_error_hint (json); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u/%d for exchange AML decision\n", + (unsigned int) response_code, + (int) adr.hr.ec); + break; + } + if (NULL != wh->cb) + { + wh->cb (wh->cb_cls, + &adr); + wh->cb = NULL; + } + TALER_EXCHANGE_kyc_start_cancel (wh); +} + + +struct TALER_EXCHANGE_KycStartHandle * +TALER_EXCHANGE_kyc_start ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *id, + TALER_EXCHANGE_KycStartCallback cb, + void *cb_cls) +{ + struct TALER_EXCHANGE_KycStartHandle *wh; + CURL *eh; + json_t *body; + + wh = GNUNET_new (struct TALER_EXCHANGE_KycStartHandle); + wh->cb = cb; + wh->cb_cls = cb_cls; + wh->ctx = ctx; + { + char *path; + + GNUNET_asprintf (&path, + "kyc-start/%s", + id); + wh->url = TALER_url_join (url, + path, + NULL); + GNUNET_free (path); + } + if (NULL == wh->url) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not construct request URL.\n"); + GNUNET_free (wh); + return NULL; + } + body = json_object (); /* as per spec: empty! */ + GNUNET_assert (NULL != body); + eh = TALER_EXCHANGE_curl_easy_get_ (wh->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&wh->post_ctx, + eh, + body)) ) + { + GNUNET_break (0); + if (NULL != eh) + curl_easy_cleanup (eh); + json_decref (body); + GNUNET_free (wh->url); + return NULL; + } + json_decref (body); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Requesting URL '%s'\n", + wh->url); + wh->job = GNUNET_CURL_job_add2 (ctx, + eh, + wh->post_ctx.headers, + &handle_kyc_start_finished, + wh); + if (NULL == wh->job) + { + TALER_EXCHANGE_kyc_start_cancel (wh); + return NULL; + } + return wh; +} + + +void +TALER_EXCHANGE_kyc_start_cancel ( + struct TALER_EXCHANGE_KycStartHandle *wh) +{ + if (NULL != wh->job) + { + GNUNET_CURL_job_cancel (wh->job); + wh->job = NULL; + } + TALER_curl_easy_post_finished (&wh->post_ctx); + GNUNET_free (wh->url); + GNUNET_free (wh); +} diff --git a/src/lib/exchange_api_kyc_wallet.c b/src/lib/exchange_api_kyc_wallet.c index 7197694ae..b12657a64 100644 --- a/src/lib/exchange_api_kyc_wallet.c +++ b/src/lib/exchange_api_kyc_wallet.c @@ -81,27 +81,28 @@ handle_kyc_wallet_finished (void *cls, struct TALER_EXCHANGE_KycWalletHandle *kwh = cls; const json_t *j = response; struct TALER_EXCHANGE_WalletKycResponse ks = { - .http_status = (unsigned int) response_code + .hr.reply = j, + .hr.http_status = (unsigned int) response_code }; kwh->job = NULL; switch (response_code) { case 0: - ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + ks.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - ks.ec = TALER_JSON_get_error_code (j); + ks.hr.ec = TALER_JSON_get_error_code (j); /* This should never happen, either us or the exchange is buggy (or API version conflict); just pass JSON reply to the application */ break; case MHD_HTTP_FORBIDDEN: - ks.ec = TALER_JSON_get_error_code (j); + ks.hr.ec = TALER_JSON_get_error_code (j); break; case MHD_HTTP_NOT_FOUND: - ks.ec = TALER_JSON_get_error_code (j); + ks.hr.ec = TALER_JSON_get_error_code (j); break; case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: { @@ -121,25 +122,25 @@ handle_kyc_wallet_finished (void *cls, NULL, NULL)) { GNUNET_break_op (0); - ks.http_status = 0; - ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + ks.hr.http_status = 0; + ks.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } break; } case MHD_HTTP_INTERNAL_SERVER_ERROR: - ks.ec = TALER_JSON_get_error_code (j); + ks.hr.ec = TALER_JSON_get_error_code (j); /* Server had an internal issue; we should retry, but this API leaves this to the application */ break; default: /* unexpected response code */ GNUNET_break_op (0); - ks.ec = TALER_JSON_get_error_code (j); + ks.hr.ec = TALER_JSON_get_error_code (j); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange /kyc-wallet\n", (unsigned int) response_code, - (int) ks.ec); + (int) ks.hr.ec); break; } kwh->cb (kwh->cb_cls, diff --git a/src/testing/testing_api_cmd_kyc_check_get.c b/src/testing/testing_api_cmd_kyc_check_get.c index ee7a8468b..595d54dc9 100644 --- a/src/testing/testing_api_cmd_kyc_check_get.c +++ b/src/testing/testing_api_cmd_kyc_check_get.c @@ -75,14 +75,14 @@ check_kyc_cb (void *cls, struct TALER_TESTING_Interpreter *is = kcg->is; kcg->kwh = NULL; - if (kcg->expected_response_code != ks->http_status) + if (kcg->expected_response_code != ks->hr.http_status) { TALER_TESTING_unexpected_status (is, - ks->http_status, + ks->hr.http_status, kcg->expected_response_code); return; } - switch (ks->http_status) + switch (ks->hr.http_status) { case MHD_HTTP_OK: kcg->access_token = ks->details.ok.access_token; diff --git a/src/testing/testing_api_cmd_kyc_proof.c b/src/testing/testing_api_cmd_kyc_proof.c index b079fffce..e5135e0f4 100644 --- a/src/testing/testing_api_cmd_kyc_proof.c +++ b/src/testing/testing_api_cmd_kyc_proof.c @@ -85,14 +85,14 @@ proof_kyc_cb (void *cls, struct TALER_TESTING_Interpreter *is = kcg->is; kcg->kph = NULL; - if (kcg->expected_response_code != kpr->http_status) + if (kcg->expected_response_code != kpr->hr.http_status) { TALER_TESTING_unexpected_status (is, - kpr->http_status, + kpr->hr.http_status, kcg->expected_response_code); return; } - switch (kpr->http_status) + switch (kpr->hr.http_status) { case MHD_HTTP_SEE_OTHER: kcg->redirect_url = GNUNET_strdup (kpr->details.found.redirect_url); @@ -105,7 +105,7 @@ proof_kyc_cb (void *cls, GNUNET_break (0); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u to /kyc-proof\n", - kpr->http_status); + kpr->hr.http_status); break; } TALER_TESTING_interpreter_next (kcg->is); diff --git a/src/testing/testing_api_cmd_kyc_wallet_get.c b/src/testing/testing_api_cmd_kyc_wallet_get.c index ffb143ffb..e6b0d4cfe 100644 --- a/src/testing/testing_api_cmd_kyc_wallet_get.c +++ b/src/testing/testing_api_cmd_kyc_wallet_get.c @@ -106,14 +106,14 @@ wallet_kyc_cb (void *cls, struct TALER_TESTING_Interpreter *is = kwg->is; kwg->kwh = NULL; - if (kwg->expected_response_code != wkr->http_status) + if (kwg->expected_response_code != wkr->hr.http_status) { TALER_TESTING_unexpected_status (is, - wkr->http_status, + wkr->hr.http_status, kwg->expected_response_code); return; } - switch (wkr->http_status) + switch (wkr->hr.http_status) { case MHD_HTTP_NO_CONTENT: break; |