exchange

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

commit 6acf87182f1f7737ed8cb454d80d289efefb6824
parent 83b611cce67df825cab11f1cabc2ec082e9663ab
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon, 15 Dec 2025 15:52:29 +0100

fix account-type determination logic

Diffstat:
Msrc/exchange/taler-exchange-httpd_kyc-check.c | 10+++++++---
Msrc/exchange/taler-exchange-httpd_kyc-info.c | 18++++++++++++++----
Msrc/exchangedb/0003-kyc_targets.sql | 4++--
Msrc/exchangedb/Makefile.am | 1+
Asrc/exchangedb/exchange-0006.sql | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/exchangedb/exchange_do_insert_aml_decision.sql | 4++--
Msrc/exchangedb/exchange_do_insert_successor_measure.sql | 4++--
Msrc/exchangedb/exchange_do_kycauth_in_insert.sql | 4++--
Msrc/exchangedb/exchange_do_reserves_in_insert.sql | 4++--
Msrc/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql | 4++--
Msrc/exchangedb/pg_lookup_kyc_requirement_by_row.c | 12++++++++----
Msrc/exchangedb/pg_lookup_kyc_requirement_by_row.h | 6+++---
Msrc/include/taler/taler_exchangedb_plugin.h | 6+++---
Msrc/include/taler/taler_kyclogic_lib.h | 13++++++++-----
Msrc/kyclogic/kyclogic_api.c | 23++++++++++++-----------
15 files changed, 134 insertions(+), 45 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_kyc-check.c b/src/exchange/taler-exchange-httpd_kyc-check.c @@ -213,7 +213,7 @@ TEH_handler_kyc_check ( bool aml_review; bool kyc_required; bool access_ok = false; - bool is_wallet; + enum GNUNET_GenericReturnValue is_wallet; uint64_t rule_gen = 0; if (NULL == kyp) @@ -341,6 +341,7 @@ TEH_handler_kyc_check ( TALER_EC_GENERIC_DB_STORE_FAILED, "lookup_kyc_requirement_by_row"); } + do_suspend = false; if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { @@ -446,10 +447,13 @@ TEH_handler_kyc_check ( GNUNET_JSON_pack_data_auto ("expected_account_pub", &kyp->account_pub)); } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "KYC rules apply to %s:\n", - is_wallet ? "wallet" : "account"); + (GNUNET_SYSERR == is_wallet) + ? "unknown account type" + : ( (GNUNET_YES == is_wallet) + ? "wallet" + : "account")); if (NULL != jrules) json_dumpf (jrules, stderr, diff --git a/src/exchange/taler-exchange-httpd_kyc-info.c b/src/exchange/taler-exchange-httpd_kyc-info.c @@ -130,9 +130,11 @@ struct KycPoller unsigned int response_code; /** - * True if our @e h_payto is for a wallet. + * #GNUNET_YES if our @e h_payto is for a wallet, + * #GNUNET_NO if it is for an account, + * #GNUNET_SYSERR if we do not know. */ - bool is_wallet; + enum GNUNET_GenericReturnValue is_wallet; /** * True if we are still suspended. @@ -578,7 +580,11 @@ current_rules_cb ( } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Making applicable zero-measures for %s under current rules active\n", - kyp->is_wallet ? "wallets" : "accounts"); + (GNUNET_SYSERR == kyp->is_wallet) + ? "unknown account type" + : ( (GNUNET_YES == kyp->is_wallet) + ? "wallets" + : "accounts")); json_dumpf (jmeasures, stderr, JSON_INDENT (2)); @@ -691,6 +697,8 @@ TEH_handler_kyc_info ( if (NULL == kyp) { + bool bis_wallet; + kyp = GNUNET_new (struct KycPoller); kyp->connection = rc->connection; rc->rh_ctx = kyp; @@ -747,11 +755,12 @@ TEH_handler_kyc_info ( } /* etag */ /* Check access token */ + kyp->is_wallet = GNUNET_SYSERR; qs = TEH_plugin->lookup_h_payto_by_access_token ( TEH_plugin->cls, &kyp->access_token, &kyp->h_payto, - &kyp->is_wallet); + &bis_wallet); if (qs < 0) { GNUNET_break (0); @@ -769,6 +778,7 @@ TEH_handler_kyc_info ( TALER_JSON_pack_ec ( TALER_EC_EXCHANGE_KYC_INFO_AUTHORIZATION_FAILED)); } + kyp->is_wallet = (bis_wallet) ? GNUNET_YES : GNUNET_NO; if (GNUNET_TIME_absolute_is_future (kyp->timeout)) { diff --git a/src/exchangedb/0003-kyc_targets.sql b/src/exchangedb/0003-kyc_targets.sql @@ -92,9 +92,9 @@ BEGIN LOOP my_payto = my_rec.payto_uri; my_is_wallet - = (LOWER (SUBSTRING (my_payto, 22)) = + = (LOWER (SUBSTRING (my_payto, 0, 23)) = 'payto://taler-reserve/') OR - (LOWER (SUBSTRING (my_payto, 27)) = + (LOWER (SUBSTRING (my_payto, 0, 28)) = 'payto://taler-reserve-http/'); INSERT INTO kyc_targets (h_normalized_payto diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am @@ -40,6 +40,7 @@ sql_DATA = \ exchange-0003.sql \ exchange-0004.sql \ exchange-0005.sql \ + exchange-0006.sql \ drop.sql \ procedures.sql \ tops-0001.sql diff --git a/src/exchangedb/exchange-0006.sql b/src/exchangedb/exchange-0006.sql @@ -0,0 +1,66 @@ +-- +-- This file is part of TALER +-- Copyright (C) 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 +-- 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/> +-- + +BEGIN; + +SELECT _v.register_patch('exchange-0006', NULL, NULL); + +SET search_path TO exchange; + +CREATE PROCEDURE patch_table_kyc_targets() +LANGUAGE plpgsql +AS $$ +DECLARE + my_rec RECORD; + my_payto TEXT; + my_is_wallet BOOL; + wtc CURSOR FOR + SELECT + h_normalized_payto + ,payto_uri + FROM exchange.wire_targets; +BEGIN + +-- Only run the migration if the tables already exist. +PERFORM + FROM pg_tables + WHERE schemaname = 'exchange' + AND tablename = 'kyc_targets'; + +IF FOUND +THEN + + FOR my_rec IN wtc + LOOP + my_payto = my_rec.payto_uri; + my_is_wallet + = (LOWER (SUBSTRING (my_payto, 0, 23)) = + 'payto://taler-reserve/') OR + (LOWER (SUBSTRING (my_payto, 0, 28)) = + 'payto://taler-reserve-http/'); + UPDATE kyc_targets + SET is_wallet=my_is_wallet + WHERE h_normalized_payto=my_rec.h_normalized_payto; + END LOOP; +END IF; + +END $$; + +CALL patch_table_kyc_targets(); + +DROP PROCEDURE patch_table_kyc_targets; + +COMMIT; diff --git a/src/exchangedb/exchange_do_insert_aml_decision.sql b/src/exchangedb/exchange_do_insert_aml_decision.sql @@ -118,9 +118,9 @@ THEN END IF; -- Well, fine, setup the account out_is_wallet - = (LOWER (SUBSTRING (in_payto_uri, 22)) = + = (LOWER (SUBSTRING (in_payto_uri, 0, 23)) = 'payto://taler-reserve/') OR - (LOWER (SUBSTRING (in_payto_uri, 27)) = + (LOWER (SUBSTRING (in_payto_uri, 0, 28)) = 'payto://taler-reserve-http/'); INSERT INTO kyc_targets (h_normalized_payto diff --git a/src/exchangedb/exchange_do_insert_successor_measure.sql b/src/exchangedb/exchange_do_insert_successor_measure.sql @@ -74,9 +74,9 @@ THEN END IF; my_is_wallet - = (LOWER (SUBSTRING (in_payto_uri, 22)) = + = (LOWER (SUBSTRING (in_payto_uri, 0, 23)) = 'payto://taler-reserve/') OR - (LOWER (SUBSTRING (in_payto_uri, 27)) = + (LOWER (SUBSTRING (in_payto_uri, 0, 28)) = 'payto://taler-reserve-http/'); INSERT INTO kyc_targets (h_normalized_payto diff --git a/src/exchangedb/exchange_do_kycauth_in_insert.sql b/src/exchangedb/exchange_do_kycauth_in_insert.sql @@ -63,9 +63,9 @@ BEGIN THEN -- First time we see this account, setup everything. my_is_wallet - = (LOWER (SUBSTRING (in_payto_uri, 22)) = + = (LOWER (SUBSTRING (in_payto_uri, 0, 23)) = 'payto://taler-reserve/') OR - (LOWER (SUBSTRING (in_payto_uri, 27)) = + (LOWER (SUBSTRING (in_payto_uri, 0, 28)) = 'payto://taler-reserve-http/'); INSERT INTO kyc_targets (h_normalized_payto diff --git a/src/exchangedb/exchange_do_reserves_in_insert.sql b/src/exchangedb/exchange_do_reserves_in_insert.sql @@ -63,9 +63,9 @@ BEGIN -- RAISE WARNING 'Starting loop on %', ini_notify; my_is_wallet - = (LOWER (SUBSTRING (ini_payto_uri, 22)) = + = (LOWER (SUBSTRING (ini_payto_uri, 0, 23)) = 'payto://taler-reserve/') OR - (LOWER (SUBSTRING (ini_payto_uri, 27)) = + (LOWER (SUBSTRING (ini_payto_uri, 0, 28)) = 'payto://taler-reserve-http/'); INSERT INTO kyc_targets (h_normalized_payto diff --git a/src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql b/src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql @@ -56,9 +56,9 @@ ELSE -- No constraint on merchant_pub, just create -- the wire_target. my_is_wallet - = (LOWER (SUBSTRING (in_payto_uri, 22)) = + = (LOWER (SUBSTRING (in_payto_uri, 0, 23)) = 'payto://taler-reserve/') OR - (LOWER (SUBSTRING (in_payto_uri, 27)) = + (LOWER (SUBSTRING (in_payto_uri, 0, 28)) = 'payto://taler-reserve-http/'); INSERT INTO kyc_targets (h_normalized_payto diff --git a/src/exchangedb/pg_lookup_kyc_requirement_by_row.c b/src/exchangedb/pg_lookup_kyc_requirement_by_row.c @@ -32,7 +32,7 @@ TEH_PG_lookup_kyc_requirement_by_row ( const struct TALER_NormalizedPaytoHashP *h_payto, bool have_pub, union TALER_AccountPublicKeyP *account_pub, - bool *is_wallet, + enum GNUNET_GenericReturnValue *is_wallet, struct TALER_ReservePublicKeyP *reserve_pub, struct TALER_AccountAccessTokenP *access_token, uint64_t *rule_gen, @@ -48,6 +48,8 @@ TEH_PG_lookup_kyc_requirement_by_row ( : GNUNET_PQ_query_param_null (), GNUNET_PQ_query_param_end }; + bool bis_wallet; + bool bis_wallet_unknown; bool not_found; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_allow_null ( @@ -70,8 +72,8 @@ TEH_PG_lookup_kyc_requirement_by_row ( GNUNET_PQ_result_spec_allow_null ( /* can be NULL due to LEFT JOIN */ GNUNET_PQ_result_spec_bool ("is_wallet", - is_wallet), - NULL), + &bis_wallet), + &bis_wallet_unknown), GNUNET_PQ_result_spec_allow_null ( /* can be NULL due to LEFT JOIN */ GNUNET_PQ_result_spec_bool ("aml_review", @@ -91,7 +93,7 @@ TEH_PG_lookup_kyc_requirement_by_row ( *jrules = NULL; *aml_review = false; - *is_wallet = false; + *is_wallet = GNUNET_SYSERR; *rule_gen = 0; if (! have_pub) memset (account_pub, @@ -124,6 +126,8 @@ TEH_PG_lookup_kyc_requirement_by_row ( rs); if (qs <= 0) return qs; + if (! bis_wallet_unknown) + *is_wallet = (bis_wallet) ? GNUNET_YES : GNUNET_NO; if (not_found) return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; return qs; diff --git a/src/exchangedb/pg_lookup_kyc_requirement_by_row.h b/src/exchangedb/pg_lookup_kyc_requirement_by_row.h @@ -35,8 +35,8 @@ * false if it is merely provided for the public key to be returned * @param[out] account_pub set to public key of the account * needed to authorize access, all zeros if not known - * @param[out] is_wallet set to true if the account is - * that of a wallet (false is used if unknown) + * @param[out] is_wallet set to #GNUNET_YES if the account is + * that of a wallet (#GNUNET_SYSERR is used if unknown) * @param[out] reserve_pub set to last reserve public key * used for a wire transfer from the account to the * exchange; alternatively used to authorize access, @@ -59,7 +59,7 @@ TEH_PG_lookup_kyc_requirement_by_row ( const struct TALER_NormalizedPaytoHashP *h_payto, bool have_pub, union TALER_AccountPublicKeyP *account_pub, - bool *is_wallet, + enum GNUNET_GenericReturnValue *is_wallet, struct TALER_ReservePublicKeyP *reserve_pub, struct TALER_AccountAccessTokenP *access_token, uint64_t *rule_gen, diff --git a/src/include/taler/taler_exchangedb_plugin.h b/src/include/taler/taler_exchangedb_plugin.h @@ -7227,8 +7227,8 @@ struct TALER_EXCHANGEDB_Plugin * false if it is merely provided for the public key to be returned * @param[in,out] account_pub set to public key of the account * needed to authorize access, all zeros if not known - * @param[out] is_wallet set to true if the account is - * that of a wallet (false is used if unknown) + * @param[out] is_wallet set to #GNUNET_YES if the account is + * that of a wallet (#GNUNET_SYSERR is used if unknown) * @param[out] reserve_pub set to last reserve public key * used for a wire transfer from the account to the * exchange; alternatively used to authorize access, @@ -7251,7 +7251,7 @@ struct TALER_EXCHANGEDB_Plugin const struct TALER_NormalizedPaytoHashP *h_payto, bool have_pub, union TALER_AccountPublicKeyP *account_pub, - bool *is_wallet, + enum GNUNET_GenericReturnValue *is_wallet, struct TALER_ReservePublicKeyP *reserve_pub, struct TALER_AccountAccessTokenP *access_token, uint64_t *rule_gen, diff --git a/src/include/taler/taler_kyclogic_lib.h b/src/include/taler/taler_kyclogic_lib.h @@ -344,15 +344,16 @@ TALER_KYCLOGIC_get_aml_program_fallback (const char *prog_name); * has performed any operation. * * @param lrs rule set to investigate, NULL for default - * @param is_wallet true to return measures for wallets, - * false to return measures for accounts + * @param is_wallet #GNUNET_YES if this is for a wallet, + * #GNUNET_NO for account, + * #GNUNET_SYSERR for unknown (returns all rules) * @return LegitimizationMeasures, NULL if there are no * zero measures */ json_t * TALER_KYCLOGIC_zero_measures ( const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs, - bool is_wallet); + enum GNUNET_GenericReturnValue is_wallet); /** @@ -485,13 +486,15 @@ TALER_KYCLOGIC_check_to_jmeasures ( * * @param jrules a ``LegitimizationRuleSet`` with KYC rules; * NULL to use default rules - * @param is_wallet true if this is for a wallet + * @param is_wallet #GNUNET_YES if this is for a wallet, + * #GNUNET_NO for account, + * #GNUNET_SYSERR for unknown (returns all rules) * @return set to JSON array with public limits * of type ``AccountLimit`` */ json_t * TALER_KYCLOGIC_rules_to_limits (const json_t *jrules, - bool is_wallet); + enum GNUNET_GenericReturnValue is_wallet); /** diff --git a/src/kyclogic/kyclogic_api.c b/src/kyclogic/kyclogic_api.c @@ -383,13 +383,14 @@ TALER_KYCLOGIC_rules_get_successor ( * Check if @a trigger applies to our context. * * @param trigger the trigger to evaluate - * @param is_wallet true if we are talking about a wallet, - * false if we are talking about an account + * @param is_wallet #GNUNET_YES if this is for a wallet, + * #GNUNET_NO for account, + * #GNUNET_SYSERR for unknown (returns all rules) * @return true if @a trigger applies in this context */ static bool trigger_applies (enum TALER_KYCLOGIC_KycTriggerEvent trigger, - bool is_wallet) + enum GNUNET_GenericReturnValue is_wallet) { switch (trigger) { @@ -397,17 +398,17 @@ trigger_applies (enum TALER_KYCLOGIC_KycTriggerEvent trigger, GNUNET_break (0); break; case TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW: - return ! is_wallet; + return GNUNET_YES != is_wallet; case TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT: - return ! is_wallet; + return GNUNET_YES != is_wallet; case TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE: - return is_wallet; + return GNUNET_NO != is_wallet; case TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE: - return is_wallet; + return GNUNET_NO != is_wallet; case TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE: - return ! is_wallet; + return GNUNET_YES != is_wallet; case TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE: - return ! is_wallet; + return GNUNET_YES != is_wallet; case TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION: return true; case TALER_KYCLOGIC_KYC_TRIGGER_REFUND: @@ -1005,7 +1006,7 @@ TALER_KYCLOGIC_status2s (enum TALER_KYCLOGIC_KycStatus status) json_t * TALER_KYCLOGIC_rules_to_limits (const json_t *jrules, - bool is_wallet) + enum GNUNET_GenericReturnValue is_wallet) { if (NULL == jrules) { @@ -1255,7 +1256,7 @@ TALER_KYCLOGIC_rule_to_measures ( json_t * TALER_KYCLOGIC_zero_measures ( const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs, - bool is_wallet) + enum GNUNET_GenericReturnValue is_wallet) { json_t *zero_measures; const struct TALER_KYCLOGIC_KycRule *rules;