aboutsummaryrefslogtreecommitdiff
path: root/src/exchange/taler-exchange-httpd_purses_merge.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange/taler-exchange-httpd_purses_merge.c')
-rw-r--r--src/exchange/taler-exchange-httpd_purses_merge.c96
1 files changed, 79 insertions, 17 deletions
diff --git a/src/exchange/taler-exchange-httpd_purses_merge.c b/src/exchange/taler-exchange-httpd_purses_merge.c
index 25d91e1b..c1db6cf3 100644
--- a/src/exchange/taler-exchange-httpd_purses_merge.c
+++ b/src/exchange/taler-exchange-httpd_purses_merge.c
@@ -28,6 +28,7 @@
#include <pthread.h>
#include "taler_dbevents.h"
#include "taler_json_lib.h"
+#include "taler_kyclogic_lib.h"
#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_purses_merge.h"
#include "taler-exchange-httpd_responses.h"
@@ -103,11 +104,21 @@ struct PurseMergeContext
/**
* URI of the account the purse is to be merged into.
- * Must be of the form 'payto://taler/$EXCHANGE_URL/RESERVE_PUB'.
+ * Must be of the form 'payto://taler-reserve/$EXCHANGE_URL/RESERVE_PUB'.
*/
const char *payto_uri;
/**
+ * Hash of the @e payto_uri.
+ */
+ struct TALER_PaytoHashP h_payto;
+
+ /**
+ * KYC status of the operation.
+ */
+ struct TALER_EXCHANGEDB_KycStatus kyc;
+
+ /**
* Base URL of the exchange provider hosting the reserve.
*/
char *provider_url;
@@ -202,6 +213,46 @@ reply_merge_success (struct MHD_Connection *connection,
/**
+ * Function called to iterate over KYC-relevant
+ * transaction amounts for a particular time range.
+ * Called within a database transaction, so must
+ * not start a new one.
+ *
+ * @param cls a `struct PurseMergeContext`
+ * @param limit maximum time-range for which events
+ * should be fetched (timestamp in the past)
+ * @param cb function to call on each event found,
+ * events must be returned in reverse chronological
+ * order
+ * @param cb_cls closure for @a cb
+ */
+static void
+amount_iterator (void *cls,
+ struct GNUNET_TIME_Absolute limit,
+ TALER_EXCHANGEDB_KycAmountCallback cb,
+ void *cb_cls)
+{
+ struct PurseMergeContext *pcc = cls;
+ enum GNUNET_DB_QueryStatus qs;
+
+ cb (cb_cls,
+ &pcc->target_amount,
+ GNUNET_TIME_absolute_get ());
+ qs = TEH_plugin->select_merge_amounts_for_kyc_check (
+ TEH_plugin->cls,
+ &pcc->h_payto,
+ limit,
+ cb,
+ cb_cls);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Got %d additional transactions for this merge and limit %llu\n",
+ qs,
+ (unsigned long long) limit.abs_value_us);
+ GNUNET_break (qs >= 0);
+}
+
+
+/**
* Execute database transaction for /purses/$PID/merge. Runs the transaction
* logic; IF it returns a non-error code, the transaction logic MUST NOT queue
* a MHD response. IF it returns an hard error, the transaction logic MUST
@@ -224,9 +275,26 @@ merge_transaction (void *cls,
bool in_conflict = true;
bool no_balance = true;
bool no_partner = true;
- bool no_kyc = true;
bool no_reserve = true;
+ const char *required;
+ required = TALER_KYCLOGIC_kyc_test_required (
+ TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE,
+ &pcc->h_payto,
+ TEH_plugin->select_satisfied_kyc_processes,
+ TEH_plugin->cls,
+ &amount_iterator,
+ pcc);
+ if (NULL != required)
+ {
+ pcc->kyc.ok = false;
+ return TEH_plugin->insert_kyc_requirement_for_account (
+ TEH_plugin->cls,
+ required,
+ &pcc->h_payto,
+ &pcc->kyc.payment_target_uuid);
+ }
+ pcc->kyc.ok = true;
qs = TEH_plugin->do_purse_merge (
TEH_plugin->cls,
pcc->purse_pub,
@@ -235,11 +303,9 @@ merge_transaction (void *cls,
&pcc->reserve_sig,
pcc->provider_url,
&pcc->reserve_pub,
- TEH_KYC_NONE != TEH_kyc_config.mode,
&no_partner,
&no_balance,
&no_reserve,
- &no_kyc,
&in_conflict);
if (qs < 0)
{
@@ -272,17 +338,6 @@ merge_transaction (void *cls,
NULL);
return GNUNET_DB_STATUS_HARD_ERROR;
}
- if ( (no_kyc) &&
- (TEH_KYC_NONE != TEH_kyc_config.mode) )
- {
- *mhd_ret
- = TALER_MHD_REPLY_JSON_PACK (
- connection,
- MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS,
- TALER_JSON_pack_ec (
- TALER_EC_EXCHANGE_GENERIC_KYC_REQUIRED));
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
if (no_balance)
{
*mhd_ret =
@@ -333,6 +388,7 @@ merge_transaction (void *cls,
GNUNET_free (partner_url);
return GNUNET_DB_STATUS_HARD_ERROR;
}
+
return qs;
}
@@ -434,7 +490,6 @@ TEH_handler_purses_merge (
TALER_EC_GENERIC_PARAMETER_MALFORMED,
"payto_uri");
}
-
http = (0 == strncmp (pcc.payto_uri,
"payto://taler-reserve+http/",
strlen ("payto://taler-reserve+http/")));
@@ -477,6 +532,8 @@ TEH_handler_purses_merge (
}
slash++;
}
+ TALER_payto_hash (pcc.payto_uri,
+ &pcc.h_payto);
if (0 == strcmp (pcc.provider_url,
TEH_base_url))
{
@@ -615,6 +672,12 @@ TEH_handler_purses_merge (
}
}
+
+ GNUNET_free (pcc.provider_url);
+ if (! pcc.kyc.ok)
+ return TEH_RESPONSE_reply_kyc_required (connection,
+ &pcc.kyc);
+
{
struct TALER_PurseEventP rep = {
.header.size = htons (sizeof (rep)),
@@ -630,7 +693,6 @@ TEH_handler_purses_merge (
0);
}
- GNUNET_free (pcc.provider_url);
/* generate regular response */
return reply_merge_success (connection,
&pcc);