exchange

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

commit 0ccac11126abe49e123961d40cce404966beeea8
parent 393aa0739773bc19810b0d4695096e4841e2ad65
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed, 11 Sep 2024 20:14:02 +0200

partial fix for kyc-deposit-deposit integration test

Diffstat:
Msrc/exchange/taler-exchange-aggregator.c | 7+++++++
Msrc/exchange/taler-exchange-httpd_common_kyc.c | 61++++++++++++++++++++++++++++++++++++++++---------------------
Msrc/exchange/taler-exchange-httpd_common_kyc.h | 27+++++++++++++++++++--------
Msrc/exchangedb/pg_get_kyc_rules.c | 23++++++++++++++++++++---
Msrc/exchangedb/pg_get_kyc_rules.h | 10+++++++++-
Msrc/include/taler_exchangedb_plugin.h | 10+++++++++-
6 files changed, 104 insertions(+), 34 deletions(-)

diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c @@ -522,10 +522,17 @@ legitimization_satisfied (struct AggregationUnit *au_active) { json_t *jrules; union TALER_AccountPublicKeyP account_pub; + struct TALER_ReservePublicKeyP reserve_pub; + bool no_account_pub; + bool no_reserve_pub; + /* FIXME: optimization potential: custom API to *just* get jrules... */ qs = db_plugin->get_kyc_rules (db_plugin->cls, &au_active->h_payto, + &no_account_pub, &account_pub, + &no_reserve_pub, + &reserve_pub, &jrules); if (qs < 0) { diff --git a/src/exchange/taler-exchange-httpd_common_kyc.c b/src/exchange/taler-exchange-httpd_common_kyc.c @@ -1632,11 +1632,17 @@ legitimization_check_run ( &old_scope); { json_t *jrules; + bool no_account_pub; + bool no_reserve_pub; - qs = TEH_plugin->get_kyc_rules (TEH_plugin->cls, - &lch->h_payto, - &lch->lcr.kyc.account_pub, - &jrules); + qs = TEH_plugin->get_kyc_rules ( + TEH_plugin->cls, + &lch->h_payto, + &no_account_pub, + &lch->lcr.kyc.account_pub, + &no_reserve_pub, + &lch->lcr.reserve_pub.reserve_pub, + &jrules); switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: @@ -1651,34 +1657,47 @@ legitimization_check_run ( case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: break; } + lch->lcr.kyc.have_account_pub - = ! GNUNET_is_zero (&lch->lcr.kyc.account_pub); - if ( (NULL == jrules) && - (lch->have_merchant_pub) && - (0 != GNUNET_memcmp (&lch->merchant_pub, - &lch->lcr.kyc.account_pub.merchant_pub)) ) + = ! no_account_pub; + lch->lcr.have_reserve_pub + = ! no_reserve_pub; + if ( (lch->have_merchant_pub) && + ( (! lch->lcr.kyc.have_account_pub) || + (0 != + GNUNET_memcmp (&lch->merchant_pub, + &lch->lcr.kyc.account_pub.merchant_pub)) ) && + ( (! lch->lcr.have_reserve_pub) || + (0 != + GNUNET_memcmp (&lch->merchant_pub, + &lch->lcr.reserve_pub.merchant_pub)) ) ) { - /* We do not have custom rules, defer enforcing merchant_pub - match until we actually have deposit constraints */ - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "KYC: merchant_pub given but no target_pub known!\n"); - lch->bad_kyc_auth = true; - } - if (NULL != jrules) - { - /* We have custom KYC rules */ - if ( (lch->have_merchant_pub) && - (0 != GNUNET_memcmp (&lch->merchant_pub, - &lch->lcr.kyc.account_pub.merchant_pub)) ) + if (NULL == jrules) + { + /* We do not have custom rules, defer enforcing merchant_pub + match until we actually have deposit constraints */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "KYC: merchant_pub given but no known target_pub(%d)/reserve_pub(%d) match!\n", + lch->lcr.kyc.have_account_pub, + lch->lcr.have_reserve_pub); + lch->bad_kyc_auth = true; + } + else { /* We have custom rules, but the target_pub for those custom rules does not match the merchant_pub. Fail the KYC process! */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "KYC: merchant_pub does not match target_pub of custom rules!\n"); + json_decref (jrules); fail_kyc_auth (lch); return; } + } + + /* parse and free jrules (if we had any) */ + if (NULL != jrules) + { lrs = TALER_KYCLOGIC_rules_parse (jrules); GNUNET_break (NULL != lrs); /* Fall back to default rules on parse error! */ diff --git a/src/exchange/taler-exchange-httpd_common_kyc.h b/src/exchange/taler-exchange-httpd_common_kyc.h @@ -195,6 +195,12 @@ struct TEH_LegitimizationCheckResult struct TALER_EXCHANGEDB_KycStatus kyc; /** + * Last reserve public key of a wire transfer from + * the account to the exchange. + */ + union TALER_AccountPublicKeyP reserve_pub; + + /** * Smallest amount (over any timeframe) that may * require additional KYC checks (if @a kyc.ok). */ @@ -207,25 +213,30 @@ struct TEH_LegitimizationCheckResult struct GNUNET_TIME_Timestamp expiration_date; /** + * Response to return. Note that the response must + * be queued or destroyed by the callee. NULL + * if the legitimization check was successful and the handler should return + * a handler-specific result. + */ + struct MHD_Response *response; + + /** * HTTP status code for @a response, or 0 */ unsigned int http_status; /** + * True if @e reserve_pub is set. + */ + bool have_reserve_pub; + + /** * Set to true if the merchant public key does not * match the public key we have on file for this * target account (and thus a new KYC AUTH is * required). */ bool bad_kyc_auth; - - /** - * Response to return. Note that the response must - * be queued or destroyed by the callee. NULL - * if the legitimization check was successful and the handler should return - * a handler-specific result. - */ - struct MHD_Response *response; }; diff --git a/src/exchangedb/pg_get_kyc_rules.c b/src/exchangedb/pg_get_kyc_rules.c @@ -30,7 +30,10 @@ enum GNUNET_DB_QueryStatus TEH_PG_get_kyc_rules ( void *cls, const struct TALER_PaytoHashP *h_payto, + bool *no_account_pub, union TALER_AccountPublicKeyP *account_pub, + bool *no_reserve_pub, + struct TALER_ReservePublicKeyP *reserve_pub, json_t **jrules) { struct PostgresClosure *pg = cls; @@ -45,7 +48,11 @@ TEH_PG_get_kyc_rules ( GNUNET_PQ_result_spec_allow_null ( GNUNET_PQ_result_spec_auto_from_type ("target_pub", account_pub), - NULL), + no_account_pub), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + reserve_pub), + no_reserve_pub), GNUNET_PQ_result_spec_allow_null ( TALER_PQ_result_spec_json ("jnew_rules", jrules), @@ -54,20 +61,30 @@ TEH_PG_get_kyc_rules ( }; *jrules = NULL; + *no_account_pub = true; + *no_reserve_pub = true; memset (account_pub, 0, sizeof (*account_pub)); + memset (reserve_pub, + 0, + sizeof (*reserve_pub)); PREPARE (pg, "get_kyc_rules", "SELECT" " wt.target_pub" " ,lo.jnew_rules" + " ,ri.reserve_pub" " FROM wire_targets wt" + " LEFT JOIN reserves_in ri" + " ON (ri.wire_source_h_payto = wt.wire_target_h_payto)" " LEFT JOIN legitimization_outcomes lo" " ON (lo.h_payto = wt.wire_target_h_payto)" " WHERE wt.wire_target_h_payto=$1" - " AND lo.expiration_time >= $2" - " AND lo.is_active;"); + " AND COALESCE(lo.expiration_time >= $2, TRUE)" + " AND COALESCE(lo.is_active, TRUE)" + " ORDER BY ri.execution_date DESC" + " LIMIT 1;"); return GNUNET_PQ_eval_prepared_singleton_select ( pg->conn, "get_kyc_rules", diff --git a/src/exchangedb/pg_get_kyc_rules.h b/src/exchangedb/pg_get_kyc_rules.h @@ -31,7 +31,12 @@ * * @param cls the @e cls of this struct with the plugin-specific state * @param h_payto account identifier - * @param[out] account_pub account public key the rules + * @param[out] no_account_pub set to true if no @a account_pub is available + * @param[out] account_pub set to account public key the rules + * apply to (because this key was used in KYC auth) + * @param[out] no_reserve_pub set to true if no @a reserve_pub is available + * @param[out] reserve_pub set to last incoming reserve public key + * of a wire transfer to the exchange from the given @a h_payto * apply to (because this key was used in KYC auth) * @param[out] jrules set to the active KYC rules for the * given account, set to NULL if no custom rules are active @@ -41,7 +46,10 @@ enum GNUNET_DB_QueryStatus TEH_PG_get_kyc_rules ( void *cls, const struct TALER_PaytoHashP *h_payto, + bool *no_account_pub, union TALER_AccountPublicKeyP *account_pub, + bool *no_reserve_pub, + struct TALER_ReservePublicKeyP *reserve_pub, json_t **jrules); #endif diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h @@ -7128,7 +7128,12 @@ struct TALER_EXCHANGEDB_Plugin * * @param cls the @e cls of this struct with the plugin-specific state * @param h_payto account identifier - * @param[out] account_pub account public key the rules + * @param[out] no_account_pub set to true if no @a account_pub is available + * @param[out] account_pub set to account public key the rules + * apply to (because this key was used in KYC auth) + * @param[out] no_reserve_pub set to true if no @a reserve_pub is available + * @param[out] reserve_pub set to last incoming reserve public key + * of a wire transfer to the exchange from the given @a h_payto * apply to (because this key was used in KYC auth) * @param[out] jrules set to the active KYC rules for the * given account, set to NULL if no custom rules are active @@ -7138,7 +7143,10 @@ struct TALER_EXCHANGEDB_Plugin (*get_kyc_rules)( void *cls, const struct TALER_PaytoHashP *h_payto, + bool *no_account_pub, union TALER_AccountPublicKeyP *account_pub, + bool *no_reserve_pub, + struct TALER_ReservePublicKeyP *reserve_pub, json_t **jrules);