diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_purses_merge.c')
-rw-r--r-- | src/exchange/taler-exchange-httpd_purses_merge.c | 96 |
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); |