-debug KYC webhook logic

This commit is contained in:
Christian Grothoff 2023-01-28 12:20:18 +01:00
parent 35d50ba36a
commit 8c5a12302e
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
6 changed files with 79 additions and 57 deletions

View File

@ -296,11 +296,12 @@ handler_kyc_webhook_generic (
rc->rh_ctx = kwh; rc->rh_ctx = kwh;
rc->rh_cleaner = &clean_kwh; rc->rh_cleaner = &clean_kwh;
if (GNUNET_OK != if ( (NULL == args[0]) ||
(GNUNET_OK !=
TALER_KYCLOGIC_lookup_logic (args[0], TALER_KYCLOGIC_lookup_logic (args[0],
&kwh->plugin, &kwh->plugin,
&kwh->pd, &kwh->pd,
&kwh->provider_section)) &kwh->provider_section)) )
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"KYC logic `%s' unknown (check KYC provider configuration)\n", "KYC logic `%s' unknown (check KYC provider configuration)\n",
@ -308,7 +309,7 @@ handler_kyc_webhook_generic (
return TALER_MHD_reply_with_error (rc->connection, return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_NOT_FOUND, MHD_HTTP_NOT_FOUND,
TALER_EC_EXCHANGE_KYC_GENERIC_LOGIC_UNKNOWN, TALER_EC_EXCHANGE_KYC_GENERIC_LOGIC_UNKNOWN,
"$NAME"); args[0]);
} }
kwh->wh = kwh->plugin->webhook (kwh->plugin->cls, kwh->wh = kwh->plugin->webhook (kwh->plugin->cls,
kwh->pd, kwh->pd,

View File

@ -18,5 +18,5 @@ KYC_KYCAID_AUTH_TOKEN = XXX
# Form to use. # Form to use.
KYC_KYCAID_FORM_ID = XXX KYC_KYCAID_FORM_ID = XXX
# Authentication token to use. # URL to go to after the process is complete.
KYC_KYCAID_POST_URL = https://example.com/ KYC_KYCAID_POST_URL = https://example.com/

View File

@ -32,4 +32,4 @@ KYC_OAUTH2_CLIENT_SECRET = password
# This is just an example, details will depend on the # This is just an example, details will depend on the
# provider! # provider!
# #
KYC_ATTRIBUTE_TEMPLATE = "{"fullname":"{{first_name}} {{last_name}}","phone":"{{phone}}"}" KYC_OAUTH2_ATTRIBUTE_TEMPLATE = "{"fullname":"{{first_name}} {{last_name}}","phone":"{{phone}}"}"

View File

@ -6,7 +6,10 @@
[kyclogic-persona] [kyclogic-persona]
# Optional authorization token for the webhook # Optional authorization token for the webhook.
# This must be the same for all uses of the
# Persona provider, and is thus not in a
# template-specific section.
#WEBHOOK_AUTH_TOKEN = wbhsec_698b5a19-c790-47f6-b396-deb572ec82f9 #WEBHOOK_AUTH_TOKEN = wbhsec_698b5a19-c790-47f6-b396-deb572ec82f9
@ -31,3 +34,7 @@ KYC_PERSONA_TEMPLATE_ID = itempl_Uj6Xxxxx
# Where do we redirect to after KYC finished successfully. # Where do we redirect to after KYC finished successfully.
KYC_PERSONA_POST_URL = https://taler.net/ KYC_PERSONA_POST_URL = https://taler.net/
# Salt to give to requests for idempotency.
# Optional.
# KYC_PERSONA_SALT = salt

View File

@ -942,35 +942,35 @@ convert_attributes (const json_t *attr)
const char *birthdate = NULL; const char *birthdate = NULL;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("country_code", GNUNET_JSON_spec_string ("country-code",
&country_code), &country_code),
NULL), NULL),
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("name_first", GNUNET_JSON_spec_string ("name-first",
&name_first), &name_first),
NULL), NULL),
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("name_middle", GNUNET_JSON_spec_string ("name-middle",
&name_middle), &name_middle),
NULL), NULL),
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("name_last", GNUNET_JSON_spec_string ("name-last",
&name_last), &name_last),
NULL), NULL),
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("address_street_1", GNUNET_JSON_spec_string ("address-street-1",
&address_street_1), &address_street_1),
NULL), NULL),
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("address_street_2", GNUNET_JSON_spec_string ("address-street-2",
&address_street_2), &address_street_2),
NULL), NULL),
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("address_city", GNUNET_JSON_spec_string ("address-city",
&address_city), &address_city),
NULL), NULL),
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("address_postal_code", GNUNET_JSON_spec_string ("address-postal-code",
&address_postal_code), &address_postal_code),
NULL), NULL),
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
@ -991,8 +991,8 @@ convert_attributes (const json_t *attr)
} }
{ {
char *name = NULL; char *name = NULL;
char *address_street = NULL; char *street = NULL;
char *address_city = NULL; char *city = NULL;
if ( (NULL != name_last) || if ( (NULL != name_last) ||
(NULL != name_first) || (NULL != name_first) ||
@ -1013,7 +1013,7 @@ convert_attributes (const json_t *attr)
if ( (NULL != address_city) || if ( (NULL != address_city) ||
(NULL != address_postal_code) ) (NULL != address_postal_code) )
{ {
GNUNET_asprintf (&address_city, GNUNET_asprintf (&city,
"%s%s%s %s", "%s%s%s %s",
(NULL != country_code) (NULL != country_code)
? country_code ? country_code
@ -1031,7 +1031,7 @@ convert_attributes (const json_t *attr)
if ( (NULL != address_street_1) || if ( (NULL != address_street_1) ||
(NULL != address_street_2) ) (NULL != address_street_2) )
{ {
GNUNET_asprintf (&address_street, GNUNET_asprintf (&street,
"%s%s%s", "%s%s%s",
(NULL != address_street_1) (NULL != address_street_1)
? address_street_1 ? address_street_1
@ -1056,16 +1056,18 @@ convert_attributes (const json_t *attr)
GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ( GNUNET_JSON_pack_string (
TALER_ATTRIBUTE_ADDRESS_STREET, TALER_ATTRIBUTE_ADDRESS_STREET,
address_street)), street)),
GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ( GNUNET_JSON_pack_string (
TALER_ATTRIBUTE_ADDRESS_CITY, TALER_ATTRIBUTE_ADDRESS_CITY,
address_city)), city)),
GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ( GNUNET_JSON_pack_string (
TALER_ATTRIBUTE_RESIDENCES, TALER_ATTRIBUTE_RESIDENCES,
country_code)) country_code))
); );
GNUNET_free (street);
GNUNET_free (city);
GNUNET_free (name); GNUNET_free (name);
} }
return ret; return ret;
@ -1170,7 +1172,6 @@ handle_proof_finished (void *cls,
const char *type = NULL; const char *type = NULL;
json_t *attributes; json_t *attributes;
json_t *relationships; json_t *relationships;
json_t *included;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string ("type", GNUNET_JSON_spec_string ("type",
&type), &type),
@ -1180,8 +1181,6 @@ handle_proof_finished (void *cls,
&attributes), &attributes),
GNUNET_JSON_spec_json ("relationships", GNUNET_JSON_spec_json ("relationships",
&relationships), &relationships),
GNUNET_JSON_spec_json ("included",
&included),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()
}; };
@ -1210,10 +1209,10 @@ handle_proof_finished (void *cls,
struct GNUNET_JSON_Specification ispec[] = { struct GNUNET_JSON_Specification ispec[] = {
GNUNET_JSON_spec_string ("status", GNUNET_JSON_spec_string ("status",
&status), &status),
GNUNET_JSON_spec_string ("reference_id", GNUNET_JSON_spec_string ("reference-id",
&reference_id), &reference_id),
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("expired_at", GNUNET_JSON_spec_string ("expired-at",
&expired_at), &expired_at),
NULL), NULL),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()
@ -1319,7 +1318,7 @@ handle_proof_finished (void *cls,
struct GNUNET_TIME_Absolute expiration; struct GNUNET_TIME_Absolute expiration;
json_t *attr; json_t *attr;
attr = extract_attributes (included); attr = convert_attributes (attributes);
if (NULL == attr) if (NULL == attr)
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
@ -1744,10 +1743,10 @@ handle_webhook_finished (void *cls,
struct GNUNET_JSON_Specification ispec[] = { struct GNUNET_JSON_Specification ispec[] = {
GNUNET_JSON_spec_string ("status", GNUNET_JSON_spec_string ("status",
&status), &status),
GNUNET_JSON_spec_string ("reference_id", GNUNET_JSON_spec_string ("reference-id",
&reference_id), &reference_id),
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("expired_at", GNUNET_JSON_spec_string ("expired-at",
&expired_at), &expired_at),
NULL), NULL),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()
@ -2081,7 +2080,7 @@ persona_webhook (void *cls,
"payload"), "payload"),
"data"), "data"),
"relationships"), "relationships"),
"inquiry_template"), "inquiry-template"),
"data"), "data"),
"id")); "id"));
if (NULL == wh->template_id) if (NULL == wh->template_id)
@ -2124,7 +2123,6 @@ persona_webhook (void *cls,
return wh; return wh;
} }
persona_inquiry_id persona_inquiry_id
= json_string_value ( = json_string_value (
json_object_get ( json_object_get (

View File

@ -459,7 +459,6 @@ webhook_finished_cb (
(void) expiration; (void) expiration;
(void) provider_section; (void) provider_section;
kwh->wh = NULL; kwh->wh = NULL;
GNUNET_break (NULL != attributes);
GNUNET_break (0 == GNUNET_memcmp (account_id, GNUNET_break (0 == GNUNET_memcmp (account_id,
&cmd_line_h_payto)); &cmd_line_h_payto));
GNUNET_break (0 == strcmp (provider_user_id, GNUNET_break (0 == strcmp (provider_user_id,
@ -474,6 +473,12 @@ webhook_finished_cb (
"KYC successful for user `%s' (legi: %s)\n", "KYC successful for user `%s' (legi: %s)\n",
provider_user_id, provider_user_id,
provider_legitimization_id); provider_legitimization_id);
GNUNET_break (NULL != attributes);
fprintf (stderr,
"Extracted attributes:\n");
json_dumpf (attributes,
stderr,
JSON_INDENT (2));
break; break;
default: default:
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@ -563,6 +568,9 @@ handler_kyc_webhook_generic (
{ {
struct KycWebhookContext *kwh = rc->rh_ctx; struct KycWebhookContext *kwh = rc->rh_ctx;
json_dumpf (root,
stderr,
JSON_INDENT (2));
if (NULL == kwh) if (NULL == kwh)
{ /* first time */ { /* first time */
kwh = GNUNET_new (struct KycWebhookContext); kwh = GNUNET_new (struct KycWebhookContext);
@ -570,11 +578,12 @@ handler_kyc_webhook_generic (
rc->rh_ctx = kwh; rc->rh_ctx = kwh;
rc->rh_cleaner = &clean_kwh; rc->rh_cleaner = &clean_kwh;
if (GNUNET_OK != if ( (NULL == args[0]) ||
(GNUNET_OK !=
TALER_KYCLOGIC_lookup_logic (args[0], TALER_KYCLOGIC_lookup_logic (args[0],
&kwh->plugin, &kwh->plugin,
&kwh->pd, &kwh->pd,
&kwh->section_name)) &kwh->section_name)) )
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"KYC logic `%s' unknown (check KYC provider configuration)\n", "KYC logic `%s' unknown (check KYC provider configuration)\n",
@ -584,14 +593,6 @@ handler_kyc_webhook_generic (
TALER_EC_EXCHANGE_KYC_GENERIC_LOGIC_UNKNOWN, TALER_EC_EXCHANGE_KYC_GENERIC_LOGIC_UNKNOWN,
args[0]); args[0]);
} }
if (0 != strcmp (args[0],
kwh->section_name))
{
return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_GENERIC_PARAMETER_MALFORMED,
"$PROVIDER_SECTION");
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Calling KYC provider specific webhook\n"); "Calling KYC provider specific webhook\n");
kwh->wh = kwh->plugin->webhook (kwh->plugin->cls, kwh->wh = kwh->plugin->webhook (kwh->plugin->cls,
@ -652,6 +653,8 @@ handler_kyc_webhook_get (
struct TEKT_RequestContext *rc, struct TEKT_RequestContext *rc,
const char *const args[]) const char *const args[])
{ {
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Webhook GET triggered\n");
return handler_kyc_webhook_generic (rc, return handler_kyc_webhook_generic (rc,
MHD_HTTP_METHOD_GET, MHD_HTTP_METHOD_GET,
NULL, NULL,
@ -673,6 +676,8 @@ handler_kyc_webhook_post (
const json_t *root, const json_t *root,
const char *const args[]) const char *const args[])
{ {
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Webhook POST triggered\n");
return handler_kyc_webhook_generic (rc, return handler_kyc_webhook_generic (rc,
MHD_HTTP_METHOD_POST, MHD_HTTP_METHOD_POST,
root, root,
@ -715,17 +720,26 @@ proof_cb (
status, status,
http_status, http_status,
provider_user_id); provider_user_id);
if (NULL != attributes) if (TALER_KYCLOGIC_STATUS_SUCCESS == status)
{
GNUNET_break (NULL != attributes);
fprintf (stderr,
"Extracted attributes:\n");
json_dumpf (attributes, json_dumpf (attributes,
stderr, stderr,
JSON_INDENT (2)); JSON_INDENT (2));
MHD_resume_connection (rs->rc->connection); }
TALER_MHD_daemon_trigger (); GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Returning response %p with status %u\n",
response,
http_status);
rs->rc->response = response; rs->rc->response = response;
rs->rc->http_status = http_status; rs->rc->http_status = http_status;
GNUNET_CONTAINER_DLL_remove (rs_head, GNUNET_CONTAINER_DLL_remove (rs_head,
rs_tail, rs_tail,
rs); rs);
MHD_resume_connection (rs->rc->connection);
TALER_MHD_daemon_trigger ();
GNUNET_free (rs); GNUNET_free (rs);
} }
@ -750,6 +764,8 @@ handler_kyc_proof_get (
const char *section_name; const char *section_name;
const char *h_paytos; const char *h_paytos;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"GET /kyc-proof triggered\n");
if (NULL == args[0]) if (NULL == args[0])
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
@ -1162,14 +1178,14 @@ handle_mhd_request (void *cls,
} }
/* cache to avoid the loop next time */ /* cache to avoid the loop next time */
rc->rh = rh; rc->rh = rh;
/* run handler */ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
return proceed_with_handler (rc, "Handler found for %s '%s'\n",
url + tok_size + 1, method,
upload_data, url);
upload_data_size); return MHD_YES;
} }
if (found) /* FIXME: this can never be true right now */ if (found)
{ {
/* we found a matching address, but the method is wrong */ /* we found a matching address, but the method is wrong */
struct MHD_Response *reply; struct MHD_Response *reply;
@ -1348,7 +1364,7 @@ initiate_cb (
return; return;
} }
fprintf (stdout, fprintf (stdout,
"Visit `%s' to begin KYC process (-u: '%s', -U: '%s')\n", "Visit `%s' to begin KYC process.\nAlso use: taler-exchange-kyc-tester -w -u '%s' -U '%s'\n",
redirect_url, redirect_url,
provider_user_id, provider_user_id,
provider_legitimization_id); provider_legitimization_id);