diff options
author | Christian Grothoff <christian@grothoff.org> | 2024-05-07 17:30:06 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2024-07-29 12:18:40 +0200 |
commit | 15cdd0ee05235648aa619e08c5c67b484ff631c4 (patch) | |
tree | b355e021539aaece13ff706b9502cfcf416ac9f3 | |
parent | 883148144cf4bd14576b9018ba8d283be7f8ac2b (diff) |
fix purses_merge
-rw-r--r-- | src/exchange/Makefile.am | 2 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_purses_merge.c | 53 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_withdraw.c | 196 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_withdraw.h | 26 |
4 files changed, 157 insertions, 120 deletions
diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am index 2cf514f0c..31e7a0fe0 100644 --- a/src/exchange/Makefile.am +++ b/src/exchange/Makefile.am @@ -162,6 +162,7 @@ taler_exchange_httpd_SOURCES = \ taler-exchange-httpd_purses_deposit.c taler-exchange-httpd_purses_deposit.h \ taler-exchange-httpd_purses_delete.c taler-exchange-httpd_purses_delete.h \ taler-exchange-httpd_purses_get.c taler-exchange-httpd_purses_get.h \ + taler-exchange-httpd_purses_merge.c taler-exchange-httpd_purses_merge.h \ taler-exchange-httpd_recoup.c taler-exchange-httpd_recoup.h \ taler-exchange-httpd_recoup-refresh.c taler-exchange-httpd_recoup-refresh.h \ taler-exchange-httpd_refreshes_reveal.c taler-exchange-httpd_refreshes_reveal.h \ @@ -177,7 +178,6 @@ taler_exchange_httpd_SOURCES = \ taler-exchange-httpd_transfers_get.c taler-exchange-httpd_transfers_get.h \ taler-exchange-httpd_withdraw.c taler-exchange-httpd_withdraw.h -# taler-exchange-httpd_purses_merge.c taler-exchange-httpd_purses_merge.h \ # taler-exchange-httpd_reserves_close.c taler-exchange-httpd_reserves_close.h \ # taler-exchange-httpd_reserves_purse.c taler-exchange-httpd_reserves_purse.h \ # taler-exchange-httpd_kyc-check.c taler-exchange-httpd_kyc-check.h \ diff --git a/src/exchange/taler-exchange-httpd_purses_merge.c b/src/exchange/taler-exchange-httpd_purses_merge.c index fb5ce4d90..5d96ca9e2 100644 --- a/src/exchange/taler-exchange-httpd_purses_merge.c +++ b/src/exchange/taler-exchange-httpd_purses_merge.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2024 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -32,6 +32,7 @@ #include "taler_mhd_lib.h" #include "taler-exchange-httpd_purses_merge.h" #include "taler-exchange-httpd_responses.h" +#include "taler-exchange-httpd_withdraw.h" #include "taler_exchangedb_lib.h" #include "taler-exchange-httpd_keys.h" @@ -279,50 +280,22 @@ merge_transaction (void *cls, bool in_conflict = true; bool no_balance = true; bool no_partner = true; - char *required; + union TALER_AccountPublicKeyP account_pub = { + .reserve_pub = pcc->reserve_pub + }; - qs = TALER_KYCLOGIC_kyc_test_required ( + qs = TEH_legitimization_check ( + &pcc->kyc, + connection, + mhd_ret, TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE, &pcc->h_payto, - TEH_plugin->select_satisfied_kyc_processes, - TEH_plugin->cls, + &account_pub, &amount_iterator, - pcc, - &required); - if (qs < 0) - { - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - return qs; - GNUNET_break (0); - *mhd_ret = - TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "kyc_test_required"); + pcc); + if ( (qs < 0) || + (! pcc->kyc.ok) ) return qs; - } - if (NULL != required) - { - pcc->kyc.ok = false; - qs = TEH_plugin->insert_kyc_requirement_for_account ( - TEH_plugin->cls, - required, - &pcc->h_payto, - &pcc->reserve_pub, - &pcc->kyc.requirement_row); - GNUNET_free (required); - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - { - GNUNET_break (0); - *mhd_ret - = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "insert_kyc_requirement_for_account"); - } - return qs; - } - pcc->kyc.ok = true; qs = TEH_plugin->do_purse_merge ( TEH_plugin->cls, pcc->purse_pub, diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c index f54235bde..559079048 100644 --- a/src/exchange/taler-exchange-httpd_withdraw.c +++ b/src/exchange/taler-exchange-httpd_withdraw.c @@ -35,6 +35,103 @@ #include "taler_util.h" +enum GNUNET_DB_QueryStatus +TEH_legitimization_check ( + struct TALER_EXCHANGEDB_KycStatus *kyc, + struct MHD_Connection *connection, + MHD_RESULT *mhd_ret, + enum TALER_KYCLOGIC_KycTriggerEvent et, + const struct TALER_PaytoHashP *h_payto, + const union TALER_AccountPublicKeyP *account_pub, + TALER_KYCLOGIC_KycAmountIterator ai, + void *ai_cls) +{ + struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs = NULL; + struct TALER_KYCLOGIC_KycRule *requirement; + enum GNUNET_DB_QueryStatus qs; + + { + json_t *jrules; + + qs = TEH_plugin->get_kyc_rules (TEH_plugin->cls, + h_payto, + &jrules); + if (qs < 0) + { + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { + GNUNET_break (0); + *mhd_ret = TALER_MHD_reply_with_ec (connection, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "get_kyc_rules"); + } + return qs; + } + if (qs > 0) + { + lrs = TALER_KYCLOGIC_rules_parse (jrules); + GNUNET_break (NULL != lrs); + /* Fall back to default rules on parse error! */ + json_decref (jrules); + } + } + + qs = TALER_KYCLOGIC_kyc_test_required ( + et, + h_payto, + lrs, + ai, + ai_cls, + &requirement); + if (qs < 0) + { + TALER_KYCLOGIC_rules_free (lrs); + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { + GNUNET_break (0); + *mhd_ret = TALER_MHD_reply_with_ec (connection, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "kyc_test_required"); + } + return qs; + } + + if (NULL == requirement) + { + TALER_KYCLOGIC_rules_free (lrs); + kyc->ok = true; + return qs; + } + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "KYC requirement is %s\n", + TALER_KYCLOGIC_rule2s (requirement)); + kyc->ok = false; + { + json_t *jrule; + + jrule = TALER_KYCLOGIC_rule2j (requirement); + qs = TEH_plugin->trigger_kyc_rule_for_account ( + TEH_plugin->cls, + h_payto, + account_pub, + jrule, + TALER_KYCLOGIC_rule2priority (requirement), + &kyc->requirement_row); + json_decref (jrule); + } + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { + GNUNET_break (0); + *mhd_ret = TALER_MHD_reply_with_ec (connection, + TALER_EC_GENERIC_DB_STORE_FAILED, + "trigger_kyc_rule_for_account"); + } + TALER_KYCLOGIC_rules_free (lrs); + return qs; +} + + /** * Closure for #withdraw_amount_cb(). */ @@ -88,11 +185,12 @@ withdraw_amount_cb ( wc->withdraw_total, wc->now.abs_time)) return; - qs = TEH_plugin->select_withdraw_amounts_for_kyc_check (TEH_plugin->cls, - &wc->h_payto, - limit, - cb, - cb_cls); + qs = TEH_plugin->select_withdraw_amounts_for_kyc_check ( + TEH_plugin->cls, + &wc->h_payto, + limit, + cb, + cb_cls); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Got %d additional transactions for this age-withdrawal and limit %llu\n", qs, @@ -116,6 +214,9 @@ TEH_withdraw_kyc_check ( .withdraw_total = withdraw_total, .now = now }; + union TALER_AccountPublicKeyP account_pub = { + .reserve_pub = *reserve_pub + }; /* Check if the money came from a wire transfer */ qs = TEH_plugin->reserves_get_origin ( @@ -131,81 +232,18 @@ TEH_withdraw_kyc_check ( "reserves_get_origin"); return qs; } - /* If _no_ results, reserve was created by merge, in which case no KYC check is required as the merge already did that. */ - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) - { - json_t *jrules; - struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs = NULL; - struct TALER_KYCLOGIC_KycRule *requirement; - - qs = TEH_plugin->get_kyc_rules (TEH_plugin->cls, - &wc.h_payto, - &jrules); - if (qs < 0) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return qs; - } - if (qs > 0) - { - lrs = TALER_KYCLOGIC_rules_parse (jrules); - GNUNET_break (NULL != lrs); - /* Fall back to default rules on parse error! */ - json_decref (jrules); - } - qs = TALER_KYCLOGIC_kyc_test_required ( - TALER_KYCLOGIC_KYC_TRIGGER_AGE_WITHDRAW, - &wc.h_payto, - lrs, - &withdraw_amount_cb, - &wc, - &requirement); - if (qs < 0) - { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - TALER_KYCLOGIC_rules_free (lrs); - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - *mhd_ret = TALER_MHD_reply_with_ec (connection, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "kyc_test_required"); - return qs; - } - - if (NULL != requirement) - { - json_t *jrule; - union TALER_AccountPublicKeyP account_pub; - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "KYC requirement is %s\n", - TALER_KYCLOGIC_rule2s (requirement)); - jrule = TALER_KYCLOGIC_rule2j (requirement); - account_pub.reserve_pub - = *reserve_pub; - kyc->ok = false; - qs = TEH_plugin->trigger_kyc_rule_for_account ( - TEH_plugin->cls, - &wc.h_payto, - &account_pub, - jrule, - TALER_KYCLOGIC_rule2priority (requirement), - &kyc->requirement_row); - TALER_KYCLOGIC_rules_free (lrs); - json_decref (jrule); - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - { - GNUNET_break (0); - *mhd_ret = TALER_MHD_reply_with_ec (connection, - TALER_EC_GENERIC_DB_STORE_FAILED, - "trigger_kyc_rule_for_account"); - } - return qs; - } - TALER_KYCLOGIC_rules_free (lrs); - } - kyc->ok = true; - return qs; + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + return qs; + return TEH_legitimization_check ( + kyc, + connection, + mhd_ret, + TALER_KYCLOGIC_KYC_TRIGGER_AGE_WITHDRAW, + &wc.h_payto, + &account_pub, + &withdraw_amount_cb, + &wc); } diff --git a/src/exchange/taler-exchange-httpd_withdraw.h b/src/exchange/taler-exchange-httpd_withdraw.h index 1391735c5..6c67a0eb3 100644 --- a/src/exchange/taler-exchange-httpd_withdraw.h +++ b/src/exchange/taler-exchange-httpd_withdraw.h @@ -26,6 +26,32 @@ /** + * Do legitimization check. + * + * @param[out] kyc set to kyc status + * @param[in,out] connection used to return hard errors + * @param[out] mhd_ret set if errors were returned + * (only on hard error) + * @param et type of event we are checking + * @param account_pub public key of the account + * @param ai callback to get amounts involved historically + * @param ai_cls closure for @a ai + * @return transaction status, error will have been + * queued if transaction status is set to hard error + */ +enum GNUNET_DB_QueryStatus +TEH_legitimization_check ( + struct TALER_EXCHANGEDB_KycStatus *kyc, + struct MHD_Connection *connection, + MHD_RESULT *mhd_ret, + enum TALER_KYCLOGIC_KycTriggerEvent et, + const struct TALER_PaytoHashP *h_payto, + const union TALER_AccountPublicKeyP *account_pub, + TALER_KYCLOGIC_KycAmountIterator ai, + void *ai_cls); + + +/** * Do legitimization check for withdrawing @a withdraw_total * from @a reserve_pub at time @a now. * |