diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_reserves_purse.c')
-rw-r--r-- | src/exchange/taler-exchange-httpd_reserves_purse.c | 97 |
1 files changed, 83 insertions, 14 deletions
diff --git a/src/exchange/taler-exchange-httpd_reserves_purse.c b/src/exchange/taler-exchange-httpd_reserves_purse.c index d377323e4..4730a5791 100644 --- a/src/exchange/taler-exchange-httpd_reserves_purse.c +++ b/src/exchange/taler-exchange-httpd_reserves_purse.c @@ -27,6 +27,7 @@ #include <microhttpd.h> #include <pthread.h> #include "taler_json_lib.h" +#include "taler_kyclogic_lib.h" #include "taler_mhd_lib.h" #include "taler-exchange-httpd_reserves_purse.h" #include "taler-exchange-httpd_responses.h" @@ -101,6 +102,16 @@ struct ReservePurseContext struct TEH_PurseDetails pd; /** + * Hash of the @e payto_uri. + */ + struct TALER_PaytoHashP h_payto; + + /** + * KYC status of the operation. + */ + struct TALER_EXCHANGEDB_KycStatus kyc; + + /** * Minimum age for deposits into this purse. */ uint32_t min_age; @@ -119,6 +130,46 @@ struct ReservePurseContext /** + * 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 ReservePurseContext` + * @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 ReservePurseContext *rpc = cls; + enum GNUNET_DB_QueryStatus qs; + + cb (cb_cls, + &rpc->deposit_total, + GNUNET_TIME_absolute_get ()); + qs = TEH_plugin->select_merge_amounts_for_kyc_check ( + TEH_plugin->cls, + &rpc->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 /reserves/$PID/purse. 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 @@ -139,6 +190,26 @@ purse_transaction (void *cls, struct ReservePurseContext *rpc = cls; enum GNUNET_DB_QueryStatus qs; + const char *required; + + required = TALER_KYCLOGIC_kyc_test_required ( + TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE, + &rpc->h_payto, + TEH_plugin->select_satisfied_kyc_processes, + TEH_plugin->cls, + &amount_iterator, + rpc); + if (NULL != required) + { + rpc->kyc.ok = false; + return TEH_plugin->insert_kyc_requirement_for_account ( + TEH_plugin->cls, + required, + &rpc->h_payto, + &rpc->kyc.payment_target_uuid); + } + rpc->kyc.ok = true; + { bool in_conflict = true; @@ -230,7 +301,6 @@ purse_transaction (void *cls, bool in_conflict = true; bool insufficient_funds = true; bool no_reserve = true; - bool no_kyc = true; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Creating purse with flags %d\n", @@ -246,10 +316,8 @@ purse_transaction (void *cls, ? NULL : &rpc->gf->fees.purse, rpc->reserve_pub, - TEH_KYC_NONE != TEH_kyc_config.mode, &in_conflict, &no_reserve, - &no_kyc, &insufficient_funds); if (qs < 0) { @@ -322,17 +390,6 @@ purse_transaction (void *cls, TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN)); 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 (insufficient_funds) { *mhd_ret @@ -472,6 +529,15 @@ TEH_handler_reserves_purse ( return MHD_YES; /* failure */ } } + { + char *payto_uri; + + payto_uri = TALER_reserve_make_payto (TEH_base_url, + reserve_pub); + TALER_payto_hash (payto_uri, + &rpc.h_payto); + GNUNET_free (payto_uri); + } GNUNET_assert (GNUNET_OK == TALER_amount_set_zero (TEH_currency, &rpc.deposit_total)); @@ -641,6 +707,9 @@ TEH_handler_reserves_purse ( } } + if (! rpc.kyc.ok) + return TEH_RESPONSE_reply_kyc_required (connection, + &rpc.kyc); /* generate regular response */ { MHD_RESULT res; |