exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit 5921ef2774299fc9d85e8a5c63030f7a3a66e4e3
parent caaac7a565ac65b5cbcf48b90453d3009d23a6cb
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sat, 19 Apr 2025 22:05:17 +0200

fix measure de-duplication, ensure next measure is activated when address check is required

Diffstat:
Msrc/curl/curl.c | 9++++++++-
Msrc/exchange/taler-exchange-httpd_kyc-info.c | 67++++++++++++++++++++++++++++++++++++++++++++-----------------------
Msrc/exchange/taler-exchange-httpd_kyc-upload.c | 6+++++-
Msrc/kyclogic/plugin_kyclogic_oauth2.c | 52++++++++++++++++++++++++++++++++++++++++------------
Msrc/kyclogic/taler-exchange-helper-measure-tops-address-check | 3++-
5 files changed, 99 insertions(+), 38 deletions(-)

diff --git a/src/curl/curl.c b/src/curl/curl.c @@ -131,6 +131,13 @@ TALER_curl_easy_post (struct TALER_CURL_PostContext *ctx, { ctx->json_enc = str; } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Uploading JSON of %d bytes (%s)\n", + (int) slen, + (TALER_CURL_COMPRESS_BODIES && + (! ctx->disable_compression) ) + ? "compressed" + : "uncompressed"); GNUNET_assert ( NULL != (ctx->headers = curl_slist_append ( @@ -144,7 +151,7 @@ TALER_curl_easy_post (struct TALER_CURL_PostContext *ctx, GNUNET_assert (CURLE_OK == curl_easy_setopt (eh, CURLOPT_POSTFIELDSIZE, - slen)); + (long) slen)); return GNUNET_OK; } diff --git a/src/exchange/taler-exchange-httpd_kyc-info.c b/src/exchange/taler-exchange-httpd_kyc-info.c @@ -402,34 +402,30 @@ resume_with_reply (struct KycPoller *kyp, fprintf (stderr, "\n"); } - kri = TALER_KYCLOGIC_measure_to_requirement ( - check_name, - prog_name, - context, - &kyp->access_token, - i, - legitimization_measure_row_id); - if (NULL == kri) - { - GNUNET_break (0); - json_decref (kris); - fail_with_ec ( - kyp, - TALER_EC_GENERIC_DB_INVARIANT_FAILURE, - "could not convert measure to requirement"); - return; - } /* Check if requirement is a duplicate, and in that case do not return it */ { - size_t off; - json_t *have; bool duplicate = false; - json_array_foreach (kris, off, have) + for (size_t off = 0; off < i; off++) { - if (1 == json_equal (have, - kri)) + json_t *have = json_array_get (measures, + off); + if ( (1 == + json_equal (json_object_get (have, + "check_name"), + json_object_get (mi, + "check_name")) ) && + (1 == + json_equal (json_object_get (have, + "check_name"), + json_object_get (mi, + "check_name")) ) && + (1 == + json_equal (json_object_get (have, + "check_name"), + json_object_get (mi, + "check_name")) ) ) { /* Duplicate requirement, do not return again */ duplicate = true; @@ -438,10 +434,26 @@ resume_with_reply (struct KycPoller *kyp, } if (duplicate) { - json_decref (kri); continue; } } + kri = TALER_KYCLOGIC_measure_to_requirement ( + check_name, + prog_name, + context, + &kyp->access_token, + i, + legitimization_measure_row_id); + if (NULL == kri) + { + GNUNET_break (0); + json_decref (kris); + fail_with_ec ( + kyp, + TALER_EC_GENERIC_DB_INVARIANT_FAILURE, + "could not convert measure to requirement"); + return; + } GNUNET_assert (0 == json_array_append_new (kris, kri)); @@ -509,12 +521,21 @@ current_rules_cb ( = rur->lrs; kyp->legitimization_outcome_last_row = rur->legitimization_outcome_last_row; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "LRS is for the account uses %s\n", + NULL == kyp->lrs + ? "default rules" + : "custom rules"); + /* Check if there is an unfinished legitimization measure */ qs = TEH_plugin->lookup_kyc_status_by_token ( TEH_plugin->cls, &kyp->access_token, &legitimization_measure_last_row, &jmeasures); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "lookup_kyc_status_by_token returned %d\n", + (int) qs); if (qs < 0) { GNUNET_break (0); diff --git a/src/exchange/taler-exchange-httpd_kyc-upload.c b/src/exchange/taler-exchange-httpd_kyc-upload.c @@ -237,7 +237,11 @@ TEH_handler_kyc_upload ( TALER_EC_GENERIC_PARAMETER_MALFORMED, "ID is malformed"); } - return MHD_YES; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "/kyc-upload received form submission\n"); + json_dumpf (root, + stderr, + JSON_INDENT (2)); } if (NULL != uc->response) { diff --git a/src/kyclogic/plugin_kyclogic_oauth2.c b/src/kyclogic/plugin_kyclogic_oauth2.c @@ -27,6 +27,11 @@ #include <regex.h> #include "taler_util.h" +/** + * Set to 1 to get extra-verbose, possibly privacy-sensitive + * data in the logs. + */ +#define DEBUG 0 /** * Saves the state of a plugin. @@ -729,8 +734,6 @@ initiate_task (void *cls) struct TALER_KYCLOGIC_InitiateHandle *ih = cls; const struct TALER_KYCLOGIC_ProviderDetails *pd = ih->pd; struct PluginState *ps = pd->ps; - char *hdr; - struct curl_slist *slist; CURL *eh; ih->task = NULL; @@ -757,28 +760,40 @@ initiate_task (void *cls) curl_easy_setopt (eh, CURLOPT_URL, pd->setup_url)); +#if DEBUG GNUNET_assert (CURLE_OK == curl_easy_setopt (eh, - CURLOPT_POST, + CURLOPT_VERBOSE, 1)); +#endif if (NULL == ih->initial_address) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Staring OAuth 2.0 without initial address\n"); GNUNET_assert (CURLE_OK == curl_easy_setopt (eh, + CURLOPT_POST, + 1)); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, CURLOPT_POSTFIELDS, "")); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_POSTFIELDSIZE, + (long) 0)); } else { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Staring OAuth 2.0 with initial address\n"); +#if DEBUG json_dumpf (ih->initial_address, stderr, JSON_INDENT (2)); fprintf (stderr, "\n"); +#endif if (GNUNET_OK != TALER_curl_easy_post (&ih->ctx, eh, @@ -803,19 +818,26 @@ initiate_task (void *cls) curl_easy_setopt (eh, CURLOPT_MAXREDIRS, 5L)); - GNUNET_asprintf (&hdr, - "%s: Bearer %s", - MHD_HTTP_HEADER_AUTHORIZATION, - pd->client_secret); - slist = curl_slist_append (NULL, - hdr); ih->job = GNUNET_CURL_job_add2 (ps->curl_ctx, eh, - slist, + ih->ctx.headers, &handle_curl_setup_finished, ih); - curl_slist_free_all (slist); - GNUNET_free (hdr); + { + char *hdr; + struct curl_slist *slist; + + GNUNET_asprintf (&hdr, + "%s: Bearer %s", + MHD_HTTP_HEADER_AUTHORIZATION, + pd->client_secret); + slist = curl_slist_append (NULL, + hdr); + GNUNET_CURL_extend_headers (ih->job, + slist); + curl_slist_free_all (slist); + GNUNET_free (hdr); + } } @@ -855,11 +877,13 @@ oauth2_initiate (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Initiating OAuth2 validation with context\n"); +#if DEBUG json_dumpf (context, stderr, JSON_INDENT (2)); fprintf (stderr, "\n"); +#endif ih->initial_address = json_incref (json_object_get (context, "initial_address")); } @@ -1067,11 +1091,13 @@ converted_proof_cb (void *cls, } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Attribute conversion output is:\n"); +#if DEBUG json_dumpf (attr, stderr, JSON_INDENT (2)); fprintf (stderr, "\n"); +#endif { const char *id; struct GNUNET_JSON_Specification ispec[] = { @@ -1157,9 +1183,11 @@ parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Calling converter `%s' with JSON\n", pd->conversion_binary); +#if DEBUG json_dumpf (j, stderr, JSON_INDENT (2)); +#endif ph->ec = TALER_JSON_external_conversion_start ( j, &converted_proof_cb, diff --git a/src/kyclogic/taler-exchange-helper-measure-tops-address-check b/src/kyclogic/taler-exchange-helper-measure-tops-address-check @@ -147,8 +147,9 @@ NEW_RULES=$(echo "$NEW_RULES" | jq --argjson cm "$CUSTOM_MEASURES" '(.rules[].me jq -n \ --argjson et "$EXPIRATION_TIME" \ --argjson sm "$SUCCESSOR_MEASURE" \ + --argjson nm '"custom-address-investigation"' \ --argjson cm "$CUSTOM_MEASURES" \ --argjson nr "$NEW_RULES" \ - '{"new_rules":($nr+{"expiration_time":$et,"successor_measure":$sm,"custom_measures":({}+$nr.custom_measures+$cm)})}|del(..|nulls)' + '{"new_measures":$nm,"new_rules":($nr+{"expiration_time":$et,"successor_measure":$sm,"custom_measures":({}+$nr.custom_measures+$cm)})}|del(..|nulls)' exit 0