aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-05-07 17:30:06 +0200
committerChristian Grothoff <christian@grothoff.org>2024-07-29 12:18:40 +0200
commit15cdd0ee05235648aa619e08c5c67b484ff631c4 (patch)
treeb355e021539aaece13ff706b9502cfcf416ac9f3
parent883148144cf4bd14576b9018ba8d283be7f8ac2b (diff)
fix purses_merge
-rw-r--r--src/exchange/Makefile.am2
-rw-r--r--src/exchange/taler-exchange-httpd_purses_merge.c53
-rw-r--r--src/exchange/taler-exchange-httpd_withdraw.c196
-rw-r--r--src/exchange/taler-exchange-httpd_withdraw.h26
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.
*