commit 3665a932b381d5e539b2bd8fdb65209cf8b8ed56 parent a1e12a191ce5327b6e317889a1cd1087fcc772ca Author: Christian Grothoff <christian@grothoff.org> Date: Tue, 22 Apr 2025 12:33:57 +0200 pass around 'is_wallet' everywhere around the KYC/AML code so we can fix #9767 Diffstat:
34 files changed, 331 insertions(+), 74 deletions(-)
diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c @@ -660,6 +660,7 @@ commit_aggregation (struct AggregationUnit *au) db_plugin, &attribute_key, &au->h_normalized_payto, + false, /* aggregation doesn't apply to wallets */ &evaluate_rules, au); if (NULL != au->ru) @@ -801,6 +802,7 @@ evaluate_rules ( db_plugin, &attribute_key, &au->h_normalized_payto, + false, /* aggregation does not apply to wallets */ &evaluate_rules, au); if (NULL != au->ru) @@ -1199,6 +1201,7 @@ run_aggregation (void *cls) &au->h_full_payto); TALER_full_payto_normalize_and_hash (au->payto_uri, &au->h_normalized_payto); + GNUNET_break (! TALER_payto_is_wallet (au->payto_uri.full_payto)); do_aggregate (au); } diff --git a/src/exchange/taler-exchange-httpd_aml-decision.c b/src/exchange/taler-exchange-httpd_aml-decision.c @@ -234,6 +234,7 @@ TEH_handler_post_aml_decision ( }; struct GNUNET_TIME_Timestamp expiration_time; json_t *jmeasures = NULL; + bool is_wallet; if (NULL == adc) { @@ -406,7 +407,8 @@ TEH_handler_post_aml_decision ( &invalid_officer, &unknown_account, &last_date, - &legi_measure_serial_id); + &legi_measure_serial_id, + &is_wallet); json_decref (jmeasures); if (qs <= 0) { @@ -473,6 +475,7 @@ TEH_handler_post_aml_decision ( &rc->async_scope_id, instant_ms, &h_payto, + is_wallet, &aml_trigger_callback, adc ); diff --git a/src/exchange/taler-exchange-httpd_common_kyc.c b/src/exchange/taler-exchange-httpd_common_kyc.c @@ -40,6 +40,11 @@ */ #define EXTRA_CHECK 0 +/** + * Enable extra logging that may include sensitive data? + */ +#define DEBUG 1 + struct TEH_KycMeasureRunContext { @@ -85,11 +90,6 @@ struct TEH_KycMeasureRunContext json_t *jmeasures; /** - * KYC measure the client is (trying to) satisfy. - */ - uint32_t measure_index; - - /** * Handle to an external process that evaluates the * need to run AML on the account. */ @@ -100,6 +100,15 @@ struct TEH_KycMeasureRunContext */ struct GNUNET_SCHEDULER_Task *async_task; + /** + * KYC measure the client is (trying to) satisfy. + */ + uint32_t measure_index; + + /** + * True if @e account_id is for a wallet. + */ + bool is_wallet; }; @@ -216,6 +225,7 @@ kyc_aml_finished ( = TEH_kyc_fallback ( &kat->scope, &kat->account_id, + kat->is_wallet, kat->process_row, kat->fallback_name, &fallback_result_cb, @@ -352,6 +362,7 @@ TEH_kyc_run_measure_for_attributes ( const struct GNUNET_AsyncScopeId *scope, uint64_t process_row, const struct TALER_NormalizedPaytoHashP *account_id, + bool is_wallet, TEH_KycMeasureRunContextCallback cb, void *cb_cls) { @@ -362,6 +373,7 @@ TEH_kyc_run_measure_for_attributes ( kat->scope = *scope; kat->process_row = process_row; kat->account_id = *account_id; + kat->is_wallet = is_wallet; kat->cb = cb; kat->cb_cls = cb_cls; qs = TEH_plugin->lookup_active_legitimization ( @@ -387,14 +399,17 @@ TEH_kyc_run_measure_for_attributes ( } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Running AML program on for current measures\n"); +#if DEBUG json_dumpf (kat->jmeasures, stderr, JSON_INDENT (2)); fprintf (stderr, "\n"); +#endif { struct TALER_EXCHANGEDB_HistoryBuilderContext hbc = { .account = &kat->account_id, + .is_wallet = kat->is_wallet, .db_plugin = TEH_plugin, .attribute_key = &TEH_attribute_key }; @@ -449,6 +464,7 @@ TEH_kyc_run_measure_directly ( const struct GNUNET_AsyncScopeId *scope, const struct TALER_KYCLOGIC_Measure *instant_ms, const struct TALER_NormalizedPaytoHashP *account_id, + bool is_wallet, TEH_KycMeasureRunContextCallback cb, void *cb_cls) { @@ -465,6 +481,7 @@ TEH_kyc_run_measure_directly ( kat->measure_index = 0; kat->scope = *scope; kat->account_id = *account_id; + kat->is_wallet = is_wallet; kat->cb = cb; kat->cb_cls = cb_cls; @@ -526,6 +543,7 @@ TEH_kyc_run_measure_directly ( { struct TALER_EXCHANGEDB_HistoryBuilderContext hbc = { .account = &kat->account_id, + .is_wallet = kat->is_wallet, .db_plugin = TEH_plugin, .attribute_key = &TEH_attribute_key }; @@ -668,6 +686,7 @@ handle_aml_fallback_result ( bool unknown_account; struct GNUNET_TIME_Timestamp last_date; uint64_t legitimization_measure_serial_id; + bool is_wallet; qs = TEH_plugin->insert_aml_decision ( TEH_plugin->cls, @@ -692,7 +711,8 @@ handle_aml_fallback_result ( &invalid_officer, &unknown_account, &last_date, - &legitimization_measure_serial_id); + &legitimization_measure_serial_id, + &is_wallet); } if (qs < 0) @@ -742,6 +762,7 @@ struct TEH_KycAmlFallback* TEH_kyc_fallback ( const struct GNUNET_AsyncScopeId *scope, const struct TALER_NormalizedPaytoHashP *account_id, + bool is_wallet, uint64_t orig_requirement_row, const char *fallback_measure, TEH_KycAmlFallbackCallback cb, @@ -769,6 +790,7 @@ TEH_kyc_fallback ( { struct TALER_EXCHANGEDB_HistoryBuilderContext hbc = { .account = &fb->account_id, + .is_wallet = is_wallet, .db_plugin = TEH_plugin, .attribute_key = &TEH_attribute_key }; @@ -979,6 +1001,11 @@ struct TEH_LegitimizationCheckHandle bool have_merchant_pub; /** + * Is our @e h_payto for a wallet? + */ + bool is_wallet; + + /** * Set to true if the merchant public key does not * match the public key we have on file for this * target account *and* a rule actually triggered @@ -1148,6 +1175,8 @@ setup_legitimization_check ( lch->et = et; lch->payto_uri.full_payto = GNUNET_strdup (payto_uri.full_payto); + lch->is_wallet + = TALER_payto_is_wallet (payto_uri.full_payto); lch->h_payto = *h_payto; if (NULL != account_pub) { @@ -1396,9 +1425,9 @@ current_rules_cb ( &lch->scope, instant_ms, &lch->h_payto, + lch->is_wallet, &legi_check_aml_trigger_cb, - lch - ); + lch); if (NULL == lch->kat) { GNUNET_break (0); @@ -1620,6 +1649,7 @@ legitimization_check_run ( lch->ru = TALER_EXCHANGEDB_update_rules (TEH_plugin, &TEH_attribute_key, &lch->h_payto, + lch->is_wallet, ¤t_rules_cb, lch); } diff --git a/src/exchange/taler-exchange-httpd_common_kyc.h b/src/exchange/taler-exchange-httpd_common_kyc.h @@ -86,6 +86,7 @@ TEH_kyc_store_attributes ( * @param scope the HTTP request logging scope * @param process_row legitimization process the data provided is about * @param account_id account the the data provided is about + * @param is_wallet true if @a account_id is a wallet * @param cb function to call with the result * @param cb_cls closure for @a cb * @return handle to cancel the operation @@ -96,6 +97,7 @@ TEH_kyc_run_measure_for_attributes ( const struct GNUNET_AsyncScopeId *scope, uint64_t process_row, const struct TALER_NormalizedPaytoHashP *account_id, + bool is_wallet, TEH_KycMeasureRunContextCallback cb, void *cb_cls); @@ -112,6 +114,7 @@ TEH_kyc_run_measure_for_attributes ( * @param scope the HTTP request logging scope * @param instant_ms instant measure to run * @param account_id account affected by the measure + * @param is_wallet true if @a account_id is for a wallet * @param cb function to call with the result * @param cb_cls closure for @a cb * @return handle to cancel the operation @@ -121,6 +124,7 @@ TEH_kyc_run_measure_directly ( const struct GNUNET_AsyncScopeId *scope, const struct TALER_KYCLOGIC_Measure *instant_ms, const struct TALER_NormalizedPaytoHashP *account_id, + bool is_wallet, TEH_KycMeasureRunContextCallback cb, void *cb_cls); @@ -162,6 +166,7 @@ typedef void * * @param scope the HTTP request logging scope * @param account_id account to activate fallback for + * @param is_wallet true if @a account_id is for a wallet * @param orig_requirement_row original requirement * row that now triggered the fallback * @param fallback_measure fallback to activate @@ -174,6 +179,7 @@ struct TEH_KycAmlFallback * TEH_kyc_fallback ( const struct GNUNET_AsyncScopeId *scope, const struct TALER_NormalizedPaytoHashP *account_id, + bool is_wallet, uint64_t orig_requirement_row, const char *fallback_measure, TEH_KycAmlFallbackCallback cb, diff --git a/src/exchange/taler-exchange-httpd_kyc-info.c b/src/exchange/taler-exchange-httpd_kyc-info.c @@ -71,21 +71,20 @@ struct KycPoller struct TALER_EXCHANGEDB_RuleUpdater *ru; /** - * #MHD_HTTP_HEADER_IF_NONE_MATCH Etag value sent by the client. 0 for none - * (or malformed). + * Current legitimization rule set, owned by callee. Will be NULL on error + * or for default rules. Will not contain skip rules and not be expired. */ - uint64_t etag_outcome_in; + struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs; /** - * #MHD_HTTP_HEADER_IF_NONE_MATCH Etag value sent by the client. 0 for none - * (or malformed). + * Handle for async KYC processing. */ - uint64_t etag_measure_in; + struct TEH_KycMeasureRunContext *kat; /** - * When will this request time out? + * Response to return, NULL if none yet. */ - struct GNUNET_TIME_Absolute timeout; + struct MHD_Response *response; /** * Set to access token for a KYC process by the account, @@ -98,32 +97,32 @@ struct KycPoller */ struct TALER_NormalizedPaytoHashP h_payto; - /** - * Current legitimization rule set, owned by callee. Will be NULL on error - * or for default rules. Will not contain skip rules and not be expired. + * #MHD_HTTP_HEADER_IF_NONE_MATCH Etag value sent by the client. 0 for none + * (or malformed). */ - struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs; + uint64_t etag_outcome_in; /** - * + * #MHD_HTTP_HEADER_IF_NONE_MATCH Etag value sent by the client. 0 for none + * (or malformed). */ - uint64_t legitimization_measure_last_row; + uint64_t etag_measure_in; /** - * Row in the legitimization outcomes table that @e lrs matches. + * When will this request time out? */ - uint64_t legitimization_outcome_last_row; + struct GNUNET_TIME_Absolute timeout; /** - * True if we are still suspended. + * */ - bool suspended; + uint64_t legitimization_measure_last_row; /** - * Handle for async KYC processing. + * Row in the legitimization outcomes table that @e lrs matches. */ - struct TEH_KycMeasureRunContext *kat; + uint64_t legitimization_outcome_last_row; /** * HTTP status code to use with @e response. @@ -131,9 +130,14 @@ struct KycPoller unsigned int response_code; /** - * Response to return, NULL if none yet. + * True if our @e h_payto is for a wallet. */ - struct MHD_Response *response; + bool is_wallet; + + /** + * True if we are still suspended. + */ + bool suspended; }; @@ -744,7 +748,8 @@ TEH_handler_kyc_info ( qs = TEH_plugin->lookup_h_payto_by_access_token ( TEH_plugin->cls, &kyp->access_token, - &kyp->h_payto); + &kyp->h_payto, + &kyp->is_wallet); if (qs < 0) { GNUNET_break (0); @@ -792,6 +797,7 @@ TEH_handler_kyc_info ( kyp->ru = TALER_EXCHANGEDB_update_rules (TEH_plugin, &TEH_attribute_key, &kyp->h_payto, + kyp->is_wallet, ¤t_rules_cb, kyp); kyp->suspended = true; diff --git a/src/exchange/taler-exchange-httpd_kyc-proof.c b/src/exchange/taler-exchange-httpd_kyc-proof.c @@ -126,6 +126,11 @@ struct KycProofContext */ bool suspended; + /** + * True if @e h_payto is for a wallet. + */ + bool is_wallet; + }; @@ -363,6 +368,7 @@ proof_cb ( &rc->async_scope_id, kpc->process_row, &kpc->h_payto, + kpc->is_wallet, &proof_finish, kpc); if (NULL == kpc->kat) @@ -543,7 +549,8 @@ TEH_handler_kyc_proof ( &kpc->process_row, &expiration, &kpc->provider_user_id, - &kpc->provider_legitimization_id); + &kpc->provider_legitimization_id, + &kpc->is_wallet); switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: diff --git a/src/exchange/taler-exchange-httpd_kyc-start.c b/src/exchange/taler-exchange-httpd_kyc-start.c @@ -126,6 +126,11 @@ struct KycPoller */ bool suspended; + /** + * True if @e h_payto is for a wallet + */ + bool is_wallet; + }; @@ -328,7 +333,8 @@ TEH_handler_kyc_start ( &kyp->access_token, &kyp->h_payto, &kyp->jmeasures, - &is_finished); + &is_finished, + &kyp->is_wallet); if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); diff --git a/src/exchange/taler-exchange-httpd_kyc-upload.c b/src/exchange/taler-exchange-httpd_kyc-upload.c @@ -262,6 +262,7 @@ TEH_handler_kyc_upload ( const char *error_message; char *form_name; enum TALER_ErrorCode ec; + bool is_wallet; qs = TEH_plugin->lookup_completed_legitimization ( TEH_plugin->cls, @@ -269,6 +270,7 @@ TEH_handler_kyc_upload ( uc->measure_index, &uc->access_token, &h_payto, + &is_wallet, &jmeasures, &is_finished, &enc_attributes_len, @@ -283,7 +285,8 @@ TEH_handler_kyc_upload ( &uc->access_token, &h_payto, &jmeasures, - &is_finished); + &is_finished, + &is_wallet); if (qs < 0) { GNUNET_break (0); @@ -400,6 +403,7 @@ TEH_handler_kyc_upload ( &rc->async_scope_id, legi_process_row, &h_payto, + is_wallet, &aml_trigger_callback, uc); if (NULL == uc->kat) diff --git a/src/exchange/taler-exchange-httpd_kyc-webhook.c b/src/exchange/taler-exchange-httpd_kyc-webhook.c @@ -206,6 +206,7 @@ kyc_aml_webhook_finished ( * @param cls closure * @param process_row legitimization process the webhook was about * @param account_id account the webhook was about + * @param is_wallet true if @a account_id is for a wallet * @param provider_name name of the KYC provider that was run * @param provider_user_id set to user ID at the provider, or NULL if not supported or unknown * @param provider_legitimization_id set to legitimization process ID at the provider, or NULL if not supported or unknown @@ -220,6 +221,7 @@ webhook_finished_cb ( void *cls, uint64_t process_row, const struct TALER_NormalizedPaytoHashP *account_id, + bool is_wallet, const char *provider_name, const char *provider_user_id, const char *provider_legitimization_id, @@ -258,6 +260,7 @@ webhook_finished_cb ( &kwh->rc->async_scope_id, process_row, account_id, + is_wallet, &kyc_aml_webhook_finished, kwh); if (NULL == kwh->kat) diff --git a/src/exchangedb/exchange_do_insert_aml_decision.sql b/src/exchangedb/exchange_do_insert_aml_decision.sql @@ -37,13 +37,15 @@ CREATE FUNCTION exchange_do_insert_aml_decision( OUT out_invalid_officer BOOLEAN, OUT out_account_unknown BOOLEAN, OUT out_last_date INT8, - OUT out_legitimization_measure_serial_id INT8) + OUT out_legitimization_measure_serial_id INT8, + OUT out_payto_uri TEXT) LANGUAGE plpgsql AS $$ DECLARE my_outcome_serial_id INT8; my_legitimization_process_serial_id INT8; my_kyc_attributes_serial_id INT8; + my_rec RECORD; my_access_token BYTEA; my_i INT4; ini_event TEXT; @@ -98,7 +100,8 @@ ELSE END IF; SELECT access_token - INTO my_access_token + ,payto_uri + INTO my_rec FROM wire_targets WHERE h_normalized_payto=in_h_normalized_payto; @@ -110,7 +113,7 @@ THEN out_account_unknown=TRUE; RETURN; END IF; - + out_payto_uri = in_payto_uri; INSERT INTO wire_targets (wire_target_h_payto ,h_normalized_payto @@ -121,6 +124,9 @@ THEN ,in_payto_uri) RETURNING access_token INTO my_access_token; +ELSE + my_access_token = my_rec.access_token; + out_payto_uri = my_rec.payto_uri; END IF; -- Did KYC measures get prescribed? diff --git a/src/exchangedb/exchangedb_aml.c b/src/exchangedb/exchangedb_aml.c @@ -75,6 +75,7 @@ TALER_EXCHANGEDB_persist_aml_program_result ( bool unknown_account; struct GNUNET_TIME_Timestamp last_date; uint64_t legitimization_measure_serial_id; + bool is_wallet; qs = plugin->insert_aml_decision ( plugin->cls, @@ -99,7 +100,8 @@ TALER_EXCHANGEDB_persist_aml_program_result ( &invalid_officer, &unknown_account, &last_date, - &legitimization_measure_serial_id); + &legitimization_measure_serial_id, + &is_wallet); GNUNET_break (qs > 0); goto cleanup; } @@ -186,6 +188,11 @@ struct TALER_EXCHANGEDB_RuleUpdater * Counter used to limit recursion depth. */ unsigned int depth; + + /** + * True if @e account is for a wallet. + */ + bool is_wallet; }; @@ -412,6 +419,7 @@ run_measure (struct TALER_EXCHANGEDB_RuleUpdater *ru, { struct TALER_EXCHANGEDB_HistoryBuilderContext hbc = { .account = &ru->account, + .is_wallet = ru->is_wallet, .db_plugin = ru->plugin, .attribute_key = &ru->attribute_key }; @@ -648,6 +656,7 @@ TALER_EXCHANGEDB_update_rules ( struct TALER_EXCHANGEDB_Plugin *plugin, const struct TALER_AttributeEncryptionKeyP *attribute_key, const struct TALER_NormalizedPaytoHashP *account, + bool is_wallet, TALER_EXCHANGEDB_CurrentRulesCallback cb, void *cb_cls) { @@ -657,6 +666,7 @@ TALER_EXCHANGEDB_update_rules ( ru->plugin = plugin; ru->attribute_key = *attribute_key; ru->account = *account; + ru->is_wallet = is_wallet; ru->cb = cb; ru->cb_cls = cb_cls; ru->t = GNUNET_SCHEDULER_add_now (&fetch_latest_rules, diff --git a/src/exchangedb/exchangedb_history.c b/src/exchangedb/exchangedb_history.c @@ -258,7 +258,8 @@ TALER_EXCHANGEDB_current_rule_builder (void *cls) GNUNET_break (0); return NULL; case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - jlrs = json_incref ((json_t *) TALER_KYCLOGIC_get_default_legi_rules ()); + jlrs = TALER_KYCLOGIC_get_default_legi_rules ( + hbc->is_wallet); break; case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: break; diff --git a/src/exchangedb/pg_insert_aml_decision.c b/src/exchangedb/pg_insert_aml_decision.c @@ -51,7 +51,8 @@ TEH_PG_insert_aml_decision ( bool *invalid_officer, bool *unknown_account, struct GNUNET_TIME_Timestamp *last_date, - uint64_t *legitimization_measure_serial_id) + uint64_t *legitimization_measure_serial_id, + bool *is_wallet) { struct PostgresClosure *pg = cls; struct TALER_KycCompletedEventP rep = { @@ -124,6 +125,7 @@ TEH_PG_insert_aml_decision ( pg->conn), GNUNET_PQ_query_param_end }; + char *rpayto = NULL; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_bool ("out_invalid_officer", invalid_officer), @@ -133,6 +135,10 @@ TEH_PG_insert_aml_decision ( last_date), GNUNET_PQ_result_spec_uint64 ("out_legitimization_measure_serial_id", legitimization_measure_serial_id), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("out_payto_uri", + &rpayto), + NULL), GNUNET_PQ_result_spec_end }; enum GNUNET_DB_QueryStatus qs; @@ -154,6 +160,7 @@ TEH_PG_insert_aml_decision ( ",out_account_unknown" ",out_last_date" ",out_legitimization_measure_serial_id" + ",out_payto_uri" " FROM exchange_do_insert_aml_decision" "($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18);"); qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, @@ -163,5 +170,16 @@ TEH_PG_insert_aml_decision ( GNUNET_PQ_cleanup_query_params_closures (params); GNUNET_free (notify_s); GNUNET_PQ_event_do_poll (pg->conn); + if (qs <= 0) + return qs; + if (NULL != rpayto) + { + *is_wallet = TALER_payto_is_wallet (rpayto); + GNUNET_free (rpayto); + } + else + { + GNUNET_assert ((*invalid_officer) || (*unknown_account)); + } return qs; } diff --git a/src/exchangedb/pg_insert_aml_decision.h b/src/exchangedb/pg_insert_aml_decision.h @@ -57,6 +57,7 @@ * the INSERT is not performed if @a last_date is not before @a decision_time * @param[out] legitimization_measure_serial_id serial ID of the legitimization measures * of the decision + * @param[out] is_wallet set to true if @a h_payto is for a wallet * @return database transaction status */ enum GNUNET_DB_QueryStatus @@ -83,7 +84,8 @@ TEH_PG_insert_aml_decision ( bool *invalid_officer, bool *unknown_account, struct GNUNET_TIME_Timestamp *last_date, - uint64_t *legitimization_measure_serial_id); + uint64_t *legitimization_measure_serial_id, + bool *is_wallet); #endif diff --git a/src/exchangedb/pg_kyc_provider_account_lookup.c b/src/exchangedb/pg_kyc_provider_account_lookup.c @@ -32,6 +32,7 @@ TEH_PG_kyc_provider_account_lookup ( const char *provider_name, const char *provider_legitimization_id, struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet, uint64_t *process_row) { struct PostgresClosure *pg = cls; @@ -40,25 +41,38 @@ TEH_PG_kyc_provider_account_lookup ( GNUNET_PQ_query_param_string (provider_name), GNUNET_PQ_query_param_end }; + char *payto_uri; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("h_payto", h_payto), + GNUNET_PQ_result_spec_string ("payto_uri", + &payto_uri), GNUNET_PQ_result_spec_uint64 ("legitimization_process_serial_id", process_row), GNUNET_PQ_result_spec_end }; + enum GNUNET_DB_QueryStatus qs; + *is_wallet = false; PREPARE (pg, "get_wire_target_by_legitimization_id", "SELECT " - " h_payto" - ",legitimization_process_serial_id" - " FROM legitimization_processes" + " lp.h_payto" + ",wt.payto_uri" + ",lp.legitimization_process_serial_id" + " FROM legitimization_processes lp" + " JOIN wire_targets wt" + " ON (lp.h_payto = wt.h_normalized_payto)" " WHERE provider_legitimization_id=$1" " AND provider_name=$2;"); - return GNUNET_PQ_eval_prepared_singleton_select ( + qs = GNUNET_PQ_eval_prepared_singleton_select ( pg->conn, "get_wire_target_by_legitimization_id", params, rs); + if (qs <= 0) + return qs; + *is_wallet = TALER_payto_is_wallet (payto_uri); + GNUNET_free (payto_uri); + return qs; } diff --git a/src/exchangedb/pg_kyc_provider_account_lookup.h b/src/exchangedb/pg_kyc_provider_account_lookup.h @@ -34,6 +34,7 @@ * @param provider_name * @param provider_legitimization_id legi to look up * @param[out] h_payto where to write the result + * @param[out] is_wallet set to true if @a h_payto is for a wallet * @param[out] process_row where to write the row of the entry * @return database transaction status */ @@ -43,6 +44,7 @@ TEH_PG_kyc_provider_account_lookup ( const char *provider_name, const char *provider_legitimization_id, struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet, uint64_t *process_row); #endif diff --git a/src/exchangedb/pg_lookup_completed_legitimization.c b/src/exchangedb/pg_lookup_completed_legitimization.c @@ -33,6 +33,7 @@ TEH_PG_lookup_completed_legitimization ( uint32_t measure_index, struct TALER_AccountAccessTokenP *access_token, struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet, json_t **jmeasures, bool *is_finished, size_t *encrypted_attributes_len, @@ -45,6 +46,7 @@ TEH_PG_lookup_completed_legitimization ( GNUNET_PQ_query_param_uint32 (&measure_index), GNUNET_PQ_query_param_end }; + char *payto_uri; struct GNUNET_PQ_ResultSpec rs[] = { TALER_PQ_result_spec_json ( "jmeasures", @@ -64,16 +66,22 @@ TEH_PG_lookup_completed_legitimization ( encrypted_attributes, encrypted_attributes_len), NULL), + GNUNET_PQ_result_spec_string ( + "payto_uri", + &payto_uri), GNUNET_PQ_result_spec_end }; + enum GNUNET_DB_QueryStatus qs; *encrypted_attributes_len = 0; *encrypted_attributes = NULL; + *is_wallet = false; PREPARE (pg, "lookup_completed_legitimization", "SELECT " " lm.jmeasures" ",wt.h_normalized_payto" + ",wt.payto_uri" ",lm.access_token" ",lm.is_finished" ",ka.encrypted_attributes" @@ -86,9 +94,14 @@ TEH_PG_lookup_completed_legitimization ( " ON (ka.legitimization_serial = lp.legitimization_process_serial_id)" " WHERE lm.legitimization_measure_serial_id=$1" " AND lp.measure_index=$2;"); - return GNUNET_PQ_eval_prepared_singleton_select ( + qs = GNUNET_PQ_eval_prepared_singleton_select ( pg->conn, "lookup_completed_legitimization", params, rs); + if (qs <= 0) + return qs; + *is_wallet = TALER_payto_is_wallet (payto_uri); + GNUNET_free (payto_uri); + return qs; } diff --git a/src/exchangedb/pg_lookup_completed_legitimization.h b/src/exchangedb/pg_lookup_completed_legitimization.h @@ -38,6 +38,7 @@ * set to token for access control that must match * @param[out] h_payto set to the the hash of the * payto URI of the account undergoing legitimization + * @param[out] is_wallet set to true if @a h_payto is for a wallet * @param[out] jmeasures set to the legitimization * measures that were put on the account * @param[out] is_finished set to true if the legitimization was @@ -56,6 +57,7 @@ TEH_PG_lookup_completed_legitimization ( uint32_t measure_index, struct TALER_AccountAccessTokenP *access_token, struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet, json_t **jmeasures, bool *is_finished, size_t *encrypted_attributes_len, diff --git a/src/exchangedb/pg_lookup_h_payto_by_access_token.c b/src/exchangedb/pg_lookup_h_payto_by_access_token.c @@ -30,30 +30,42 @@ enum GNUNET_DB_QueryStatus TEH_PG_lookup_h_payto_by_access_token ( void *cls, const struct TALER_AccountAccessTokenP *access_token, - struct TALER_NormalizedPaytoHashP *h_payto) + struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (access_token), GNUNET_PQ_query_param_end }; + char *payto; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ( "h_normalized_payto", h_payto), + GNUNET_PQ_result_spec_string ( + "payto_uri", + &payto), GNUNET_PQ_result_spec_end }; + enum GNUNET_DB_QueryStatus qs; + *is_wallet = false; PREPARE (pg, "lookup_h_payto_by_access_token", "SELECT " " h_normalized_payto" + " ,payto_uri" " FROM wire_targets" " WHERE (access_token = $1);"); - return GNUNET_PQ_eval_prepared_singleton_select ( + qs = GNUNET_PQ_eval_prepared_singleton_select ( pg->conn, "lookup_h_payto_by_access_token", params, rs); - + if (qs <= 0) + return qs; + *is_wallet = TALER_payto_is_wallet (payto); + GNUNET_free (payto); + return qs; } diff --git a/src/exchangedb/pg_lookup_h_payto_by_access_token.h b/src/exchangedb/pg_lookup_h_payto_by_access_token.h @@ -34,12 +34,15 @@ * set to token for access control * @param[out] h_payto set to the the hash of the * payto URI of the account (if found) + * @param[out] is_wallet set to true if @a h_payto + * is for a wallet * @return database transaction status */ enum GNUNET_DB_QueryStatus TEH_PG_lookup_h_payto_by_access_token ( void *cls, const struct TALER_AccountAccessTokenP *access_token, - struct TALER_NormalizedPaytoHashP *h_payto); + struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet); #endif diff --git a/src/exchangedb/pg_lookup_kyc_process_by_account.c b/src/exchangedb/pg_lookup_kyc_process_by_account.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022, 2025 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 @@ -34,7 +34,8 @@ TEH_PG_lookup_kyc_process_by_account ( uint64_t *process_row, struct GNUNET_TIME_Absolute *expiration, char **provider_account_id, - char **provider_legitimization_id) + char **provider_legitimization_id, + bool *is_wallet) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { @@ -42,6 +43,7 @@ TEH_PG_lookup_kyc_process_by_account ( GNUNET_PQ_query_param_string (provider_name), GNUNET_PQ_query_param_end }; + char *payto_uri; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_uint64 ( "legitimization_process_serial_id", @@ -59,19 +61,27 @@ TEH_PG_lookup_kyc_process_by_account ( "provider_legitimization_id", provider_legitimization_id), NULL), + GNUNET_PQ_result_spec_string ( + "payto_uri", + &payto_uri), GNUNET_PQ_result_spec_end }; + enum GNUNET_DB_QueryStatus qs; *provider_account_id = NULL; *provider_legitimization_id = NULL; + *is_wallet = false; PREPARE (pg, "lookup_process_by_account", "SELECT " - " legitimization_process_serial_id" - ",expiration_time" - ",provider_user_id" - ",provider_legitimization_id" - " FROM legitimization_processes" + " lp.legitimization_process_serial_id" + ",lp.expiration_time" + ",lp.provider_user_id" + ",lp.provider_legitimization_id" + ",wt.payto_uri" + " FROM legitimization_processes lp" + " JOIN wire_targets wt" + " ON (lp.h_payto = wt.h_normalized_payto)" " WHERE h_payto=$1" " AND provider_name=$2" " AND NOT finished" @@ -79,9 +89,14 @@ TEH_PG_lookup_kyc_process_by_account ( match, so this is just to be safe(r): */ " ORDER BY expiration_time DESC" " LIMIT 1;"); - return GNUNET_PQ_eval_prepared_singleton_select ( + qs = GNUNET_PQ_eval_prepared_singleton_select ( pg->conn, "lookup_process_by_account", params, rs); + if (qs <= 0) + return qs; + *is_wallet = TALER_payto_is_wallet (payto_uri); + GNUNET_free (payto_uri); + return qs; } diff --git a/src/exchangedb/pg_lookup_kyc_process_by_account.h b/src/exchangedb/pg_lookup_kyc_process_by_account.h @@ -36,6 +36,7 @@ * @param[out] expiration how long is this KYC check set to be valid (in the past if invalid) * @param[out] provider_account_id provider account ID * @param[out] provider_legitimization_id provider legitimization ID + * @param[out] is_wallet set to true if @a h_payto is for a wallet * @return database transaction status */ enum GNUNET_DB_QueryStatus @@ -46,6 +47,7 @@ TEH_PG_lookup_kyc_process_by_account ( uint64_t *process_row, struct GNUNET_TIME_Absolute *expiration, char **provider_account_id, - char **provider_legitimization_id); + char **provider_legitimization_id, + bool *is_wallet); #endif diff --git a/src/exchangedb/pg_lookup_pending_legitimization.c b/src/exchangedb/pg_lookup_pending_legitimization.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2024 Taler Systems SA + Copyright (C) 2024, 2025 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 @@ -33,13 +33,15 @@ TEH_PG_lookup_pending_legitimization ( struct TALER_AccountAccessTokenP *access_token, struct TALER_NormalizedPaytoHashP *h_payto, json_t **jmeasures, - bool *is_finished) + bool *is_finished, + bool *is_wallet) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_uint64 (&legitimization_measure_serial_id), GNUNET_PQ_query_param_end }; + char *payto_uri; struct GNUNET_PQ_ResultSpec rs[] = { TALER_PQ_result_spec_json ( "jmeasures", @@ -53,23 +55,34 @@ TEH_PG_lookup_pending_legitimization ( GNUNET_PQ_result_spec_bool ( "is_finished", is_finished), + GNUNET_PQ_result_spec_string ( + "payto_uri", + &payto_uri), GNUNET_PQ_result_spec_end }; + enum GNUNET_DB_QueryStatus qs; + *is_wallet = false; PREPARE (pg, "lookup_pending_legitimization", "SELECT " " lm.jmeasures" ",wt.h_normalized_payto" + ",wt.payto_uri" ",lm.access_token" ",lm.is_finished" " FROM legitimization_measures lm" " JOIN wire_targets wt" " ON (lm.access_token = wt.access_token)" " WHERE lm.legitimization_measure_serial_id=$1;"); - return GNUNET_PQ_eval_prepared_singleton_select ( + qs = GNUNET_PQ_eval_prepared_singleton_select ( pg->conn, "lookup_pending_legitimization", params, rs); + if (qs <= 0) + return qs; + *is_wallet = TALER_payto_is_wallet (payto_uri); + GNUNET_free (payto_uri); + return qs; } diff --git a/src/exchangedb/pg_lookup_pending_legitimization.h b/src/exchangedb/pg_lookup_pending_legitimization.h @@ -40,6 +40,7 @@ * measures that were put on the account * @param[out] is_finished set to true if the legitimization was * already finished + * @param[out] is_wallet set to true if @a h_payto is for a wallet * @return database transaction status */ enum GNUNET_DB_QueryStatus @@ -49,6 +50,7 @@ TEH_PG_lookup_pending_legitimization ( struct TALER_AccountAccessTokenP *access_token, struct TALER_NormalizedPaytoHashP *h_payto, json_t **jmeasures, - bool *is_finished); + bool *is_finished, + bool *is_wallet); #endif diff --git a/src/exchangedb/pg_select_aml_decisions.c b/src/exchangedb/pg_select_aml_decisions.c @@ -86,7 +86,7 @@ handle_aml_result (void *cls, &rowid), GNUNET_PQ_result_spec_auto_from_type ("h_payto", &h_payto), - GNUNET_PQ_result_spec_string ("payto", + GNUNET_PQ_result_spec_string ("payto_uri", &payto), GNUNET_PQ_result_spec_allow_null ( GNUNET_PQ_result_spec_string ("justification", @@ -214,7 +214,10 @@ TEH_PG_select_aml_decisions ( ",lo.to_investigate" ",lo.is_active" ",lo.jnew_rules" + ",wt.payto_uri" " FROM legitimization_outcomes lo" + " JOIN wire_targets wt" + " ON (lo.h_payto = wt.h_normalized_payto)" " LEFT JOIN aml_history ah" " USING (outcome_serial_id)" " WHERE lo.outcome_serial_id < $7" diff --git a/src/include/taler_exchangedb_lib.h b/src/include/taler_exchangedb_lib.h @@ -230,6 +230,11 @@ struct TALER_EXCHANGEDB_HistoryBuilderContext * Key to use to decrypt KYC attributes. */ struct TALER_AttributeEncryptionKeyP *attribute_key; + + /** + * True if @e account is for a wallet. + */ + bool is_wallet; }; @@ -344,6 +349,7 @@ typedef void * @param plugin database plugin to use * @param attribute_key key to use to decrypt attributes * @param account account to get the rule set for + * @param is_wallet true if @a account is a wallet * @param cb function to call with the result * @param cb_cls closure for @a cb * @return handle to cancel the operation @@ -353,6 +359,7 @@ TALER_EXCHANGEDB_update_rules ( struct TALER_EXCHANGEDB_Plugin *plugin, const struct TALER_AttributeEncryptionKeyP *attribute_key, const struct TALER_NormalizedPaytoHashP *account, + bool is_wallet, TALER_EXCHANGEDB_CurrentRulesCallback cb, void *cb_cls); diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h @@ -7425,6 +7425,7 @@ struct TALER_EXCHANGEDB_Plugin * @param[out] expiration how long is this KYC check set to be valid (in the past if invalid) * @param[out] provider_account_id provider account ID * @param[out] provider_legitimization_id provider legitimization ID + * @param[out] is_wallet set to true if @a h_payto is for a wallet * @return database transaction status */ enum GNUNET_DB_QueryStatus @@ -7435,7 +7436,8 @@ struct TALER_EXCHANGEDB_Plugin uint64_t *process_row, struct GNUNET_TIME_Absolute *expiration, char **provider_account_id, - char **provider_legitimization_id); + char **provider_legitimization_id, + bool *is_wallet); /** @@ -7445,6 +7447,7 @@ struct TALER_EXCHANGEDB_Plugin * @param provider_name * @param provider_legitimization_id legi to look up * @param[out] h_payto where to write the result + * @param[out] is_wallet set to true if @a h_payto is for a wallet * @param[out] process_row identifies the legitimization process on our end * @return database transaction status */ @@ -7454,6 +7457,7 @@ struct TALER_EXCHANGEDB_Plugin const char *provider_name, const char *provider_legitimization_id, struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet, uint64_t *process_row); @@ -7855,13 +7859,16 @@ struct TALER_EXCHANGEDB_Plugin * set to token for access control * @param[out] h_payto set to the the hash of the * payto URI of the account (if found) + * @param[out] is_wallet set to true if @a h_payto + * is for a wallet * @return database transaction status */ enum GNUNET_DB_QueryStatus (*lookup_h_payto_by_access_token)( void *cls, const struct TALER_AccountAccessTokenP *access_token, - struct TALER_NormalizedPaytoHashP *h_payto); + struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet); /** @@ -7878,6 +7885,7 @@ struct TALER_EXCHANGEDB_Plugin * measures that were put on the account * @param[out] is_finished set to true if the legitimization was * already finished + * @param[out] is_wallet set to true if @a h_payto is for a wallet * @return database transaction status */ enum GNUNET_DB_QueryStatus @@ -7887,7 +7895,8 @@ struct TALER_EXCHANGEDB_Plugin struct TALER_AccountAccessTokenP *access_token, struct TALER_NormalizedPaytoHashP *h_payto, json_t **jmeasures, - bool *is_finished); + bool *is_finished, + bool *is_wallet); /** @@ -7902,6 +7911,7 @@ struct TALER_EXCHANGEDB_Plugin * set to token for access control that must match * @param[out] h_payto set to the the hash of the * payto URI of the account undergoing legitimization + * @param[out] is_wallet set to true if @a h_payto is for a wallet * @param[out] jmeasures set to the legitimization * measures that were put on the account * @param[out] is_finished set to true if the legitimization was @@ -7920,6 +7930,7 @@ struct TALER_EXCHANGEDB_Plugin uint32_t measure_index, struct TALER_AccountAccessTokenP *access_token, struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet, json_t **jmeasures, bool *is_finished, size_t *encrypted_attributes_len, @@ -8033,6 +8044,7 @@ struct TALER_EXCHANGEDB_Plugin * the INSERT is not performed if @a last_date is not before @a decision_time * @param[out] legitimization_measure_serial_id serial ID of the legitimization measures * of the decision + * @param[out] is_wallet set to true if @a h_payto is for a wallet * @return database transaction status */ enum GNUNET_DB_QueryStatus @@ -8059,7 +8071,8 @@ struct TALER_EXCHANGEDB_Plugin bool *invalid_officer, bool *unknown_account, struct GNUNET_TIME_Timestamp *last_date, - uint64_t *legitimization_measure_serial_id); + uint64_t *legitimization_measure_serial_id, + bool *is_wallet); /** diff --git a/src/include/taler_kyclogic_lib.h b/src/include/taler_kyclogic_lib.h @@ -757,10 +757,12 @@ TALER_KYCLOGIC_get_instant_measure ( /** * Return default legitimization rule set in JSON. * + * @param for_wallet true to return only rules that apply to + * wallets, false to return only rules that apply to accounts * @return default legitimization rules */ -const json_t * -TALER_KYCLOGIC_get_default_legi_rules (void); +json_t * +TALER_KYCLOGIC_get_default_legi_rules (bool for_wallet); /** * Check if there is a measure in @a lrs that is named @a measure. diff --git a/src/include/taler_kyclogic_plugin.h b/src/include/taler_kyclogic_plugin.h @@ -191,6 +191,7 @@ typedef void * @param cls closure * @param process_row legitimization process the webhook was about * @param account_id account the webhook was about + * @param is_wallet true if @a account_id is for a wallet * @param provider_name name of the provider that was run * @param provider_user_id set to user ID at the provider, or NULL if not supported or unknown * @param provider_legitimization_id set to legitimization process ID at the provider, or NULL if not supported or unknown @@ -205,6 +206,7 @@ typedef void void *cls, uint64_t process_row, const struct TALER_NormalizedPaytoHashP *account_id, + bool is_wallet, const char *provider_name, const char *provider_user_id, const char *provider_legitimization_id, @@ -224,6 +226,7 @@ typedef void * @param provider_name * @param provider_legitimization_id legi to look up * @param[out] h_payto where to write the result + * @param[out] is_wallet set to true if @e h_payto is for a wallet * @param[out] process_row where to write the row of the entry * @return database transaction status */ @@ -233,6 +236,7 @@ typedef enum GNUNET_DB_QueryStatus const char *provider_name, const char *provider_legitimization_id, struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet, uint64_t *process_row); diff --git a/src/kyclogic/kyclogic_api.c b/src/kyclogic/kyclogic_api.c @@ -4671,10 +4671,11 @@ TALER_KYCLOGIC_get_zero_limits () } -const json_t * -TALER_KYCLOGIC_get_default_legi_rules () +json_t * +TALER_KYCLOGIC_get_default_legi_rules (bool for_wallet) { - return default_rules.jlrs; + // FIXME-#9767: specialize based on 'for_wallet'! + return json_incref ((json_t *) default_rules.jlrs); } diff --git a/src/kyclogic/plugin_kyclogic_kycaid.c b/src/kyclogic/plugin_kyclogic_kycaid.c @@ -288,6 +288,11 @@ struct TALER_KYCLOGIC_WebhookHandle * HTTP response code to return asynchronously. */ unsigned int response_code; + + /** + * True if @e h_payto is for a wallet. + */ + bool is_wallet; }; @@ -857,6 +862,7 @@ webhook_conversion_cb (void *cls, wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, + wh->is_wallet, wh->pd->section, wh->applicant_id, wh->verification_id, @@ -885,6 +891,7 @@ webhook_conversion_cb (void *cls, wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, + wh->is_wallet, wh->pd->section, wh->applicant_id, wh->verification_id, @@ -902,6 +909,7 @@ webhook_conversion_cb (void *cls, wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, + wh->is_wallet, wh->pd->section, wh->applicant_id, wh->verification_id, @@ -961,6 +969,7 @@ handle_webhook_finished (void *cls, wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, + wh->is_wallet, wh->pd->section, wh->applicant_id, wh->verification_id, @@ -998,6 +1007,7 @@ handle_webhook_finished (void *cls, wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, + wh->is_wallet, wh->pd->section, wh->applicant_id, wh->verification_id, @@ -1026,6 +1036,7 @@ handle_webhook_finished (void *cls, wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, + wh->is_wallet, wh->pd->section, wh->applicant_id, wh->verification_id, @@ -1048,6 +1059,7 @@ handle_webhook_finished (void *cls, wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, + wh->is_wallet, wh->pd->section, wh->applicant_id, wh->verification_id, @@ -1066,6 +1078,7 @@ handle_webhook_finished (void *cls, wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, + wh->is_wallet, wh->pd->section, wh->applicant_id, wh->verification_id, @@ -1090,6 +1103,7 @@ handle_webhook_finished (void *cls, wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, + wh->is_wallet, wh->pd->section, wh->applicant_id, wh->verification_id, @@ -1108,6 +1122,7 @@ handle_webhook_finished (void *cls, wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, + wh->is_wallet, wh->pd->section, wh->applicant_id, wh->verification_id, @@ -1126,6 +1141,7 @@ handle_webhook_finished (void *cls, wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, + wh->is_wallet, wh->pd->section, wh->applicant_id, wh->verification_id, @@ -1150,6 +1166,7 @@ handle_webhook_finished (void *cls, wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, + wh->is_wallet, wh->pd->section, wh->applicant_id, wh->verification_id, @@ -1180,6 +1197,7 @@ async_webhook_reply (void *cls) (0 == wh->process_row) ? NULL : &wh->h_payto, + wh->is_wallet, wh->pd->section, wh->applicant_id, /* provider user ID */ wh->verification_id, /* provider legi ID */ @@ -1314,6 +1332,7 @@ kycaid_webhook (void *cls, pd->section, verification_id, &wh->h_payto, + &wh->is_wallet, &wh->process_row); if (qs < 0) { diff --git a/src/kyclogic/plugin_kyclogic_oauth2.c b/src/kyclogic/plugin_kyclogic_oauth2.c @@ -1712,6 +1712,7 @@ wh_return_not_found (void *cls) wh->cb (wh->cb_cls, 0LLU, NULL, + false, NULL, NULL, NULL, diff --git a/src/kyclogic/plugin_kyclogic_persona.c b/src/kyclogic/plugin_kyclogic_persona.c @@ -357,6 +357,11 @@ struct TALER_KYCLOGIC_WebhookHandle * HTTP response code to return asynchronously. */ unsigned int response_code; + + /** + * True if @e h_payto is for a wallet. + */ + bool is_wallet; }; @@ -1578,6 +1583,7 @@ webhook_generic_reply (struct TALER_KYCLOGIC_WebhookHandle *wh, wh->cb (wh->cb_cls, wh->process_row, &wh->h_payto, + wh->is_wallet, wh->pd->section, account_id, inquiry_id, @@ -1905,6 +1911,7 @@ async_webhook_reply (void *cls) (0 == wh->process_row) ? NULL : &wh->h_payto, + wh->is_wallet, wh->pd->section, NULL, wh->inquiry_id, /* provider legi ID */ @@ -2108,6 +2115,7 @@ persona_webhook (void *cls, wh->pd->section, persona_inquiry_id, &wh->h_payto, + &wh->is_wallet, &wh->process_row); if (qs < 0) { diff --git a/src/kyclogic/taler-exchange-kyc-tester.c b/src/kyclogic/taler-exchange-kyc-tester.c @@ -279,6 +279,11 @@ static unsigned int kyc_row_id = 42; static int print_h_payto; /** + * -W command-line option. + */ +static int cmd_line_is_wallet; + +/** * -w command-line option. */ static int run_webservice; @@ -442,6 +447,7 @@ kyc_webhook_cleanup (void) * @param cls closure * @param process_row legitimization process request the webhook was about * @param account_id account the webhook was about + * @param is_wallet true if @a account_id is for a wallet * @param provider_section configuration section of the logic * @param provider_user_id set to user ID at the provider, or NULL if not supported or unknown * @param provider_legitimization_id set to legitimization process ID at the provider, or NULL if not supported or unknown @@ -456,6 +462,7 @@ webhook_finished_cb ( void *cls, uint64_t process_row, const struct TALER_NormalizedPaytoHashP *account_id, + bool is_wallet, const char *provider_section, const char *provider_user_id, const char *provider_legitimization_id, @@ -470,6 +477,7 @@ webhook_finished_cb ( (void) expiration; (void) provider_section; kwh->wh = NULL; + GNUNET_break (is_wallet); if ( (NULL != account_id) && (0 != GNUNET_memcmp (account_id, &cmd_line_h_payto)) ) @@ -558,6 +566,7 @@ clean_kwh (struct TEKT_RequestContext *rc) * @param provider_section * @param provider_legitimization_id legi to look up * @param[out] h_payto where to write the result + * @param[out] is_wallet set to true if @a h_payto is for a wallet * @param[out] legi_row where to write the row ID for the legitimization ID * @return database transaction status */ @@ -567,6 +576,7 @@ kyc_provider_account_lookup ( const char *provider_section, const char *provider_legitimization_id, struct TALER_NormalizedPaytoHashP *h_payto, + bool *is_wallet, uint64_t *legi_row) { (void) cls; @@ -576,6 +586,7 @@ kyc_provider_account_lookup ( provider_legitimization_id); *h_payto = cmd_line_h_payto; *legi_row = kyc_row_id; + *is_wallet = (0 != cmd_line_is_wallet); return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } @@ -1832,6 +1843,11 @@ main (int argc, "run-webservice", "run the integrated HTTP service", &run_webservice), + GNUNET_GETOPT_option_flag ( + 'W', + "wallet-payto", + "simulate that the address the KYC process is about is a wallet", + &cmd_line_is_wallet), GNUNET_GETOPT_OPTION_END }; enum GNUNET_GenericReturnValue ret;