add KYC errors for p2p payments
This commit is contained in:
parent
3e99c50c0f
commit
93943bdb5b
@ -1 +1 @@
|
||||
Subproject commit aebd5420308d7599aadb8818a82d9ffc89492334
|
||||
Subproject commit d4234f340c6e7261de36ab5fad3d53597ea8ecd0
|
@ -150,7 +150,7 @@ batch_withdraw_transaction (void *cls,
|
||||
{
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_NOT_FOUND,
|
||||
TALER_EC_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN,
|
||||
TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN,
|
||||
NULL);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
@ -171,7 +171,7 @@ batch_withdraw_transaction (void *cls,
|
||||
/* Wallet-to-wallet payments _always_ require KYC */
|
||||
*mhd_ret = TALER_MHD_REPLY_JSON_PACK (
|
||||
connection,
|
||||
MHD_HTTP_ACCEPTED,
|
||||
MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS,
|
||||
GNUNET_JSON_pack_uint64 ("payment_target_uuid",
|
||||
wc->kyc.payment_target_uuid));
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
@ -206,7 +206,7 @@ batch_withdraw_transaction (void *cls,
|
||||
{
|
||||
*mhd_ret = TALER_MHD_REPLY_JSON_PACK (
|
||||
connection,
|
||||
MHD_HTTP_ACCEPTED,
|
||||
MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS,
|
||||
GNUNET_JSON_pack_uint64 ("payment_target_uuid",
|
||||
wc->kyc.payment_target_uuid));
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
|
@ -223,6 +223,8 @@ merge_transaction (void *cls,
|
||||
bool in_conflict = true;
|
||||
bool no_balance = true;
|
||||
bool no_partner = true;
|
||||
bool no_kyc = true;
|
||||
bool no_reserve = true;
|
||||
|
||||
// FIXME: add KYC-check logic!
|
||||
qs = TEH_plugin->do_purse_merge (TEH_plugin->cls,
|
||||
@ -234,6 +236,8 @@ merge_transaction (void *cls,
|
||||
&pcc->reserve_pub,
|
||||
&no_partner,
|
||||
&no_balance,
|
||||
&no_reserve,
|
||||
&no_kyc,
|
||||
&in_conflict);
|
||||
if (qs < 0)
|
||||
{
|
||||
@ -257,6 +261,25 @@ merge_transaction (void *cls,
|
||||
pcc->provider_url);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
if (no_reserve)
|
||||
{
|
||||
*mhd_ret =
|
||||
TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_NOT_FOUND,
|
||||
TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN,
|
||||
NULL);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
if (no_kyc)
|
||||
{
|
||||
*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 =
|
||||
|
@ -213,8 +213,6 @@ purse_transaction (void *cls,
|
||||
{
|
||||
bool in_conflict = true;
|
||||
|
||||
// FIXME: also check KYC state of the account
|
||||
// FIXME: distinguish reserve-not-found!
|
||||
/* 1) store purse */
|
||||
qs = TEH_plugin->insert_purse_request (TEH_plugin->cls,
|
||||
&rpc->purse_pub,
|
||||
@ -294,14 +292,14 @@ purse_transaction (void *cls,
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
|
||||
// FIXME: return 404 if reserve-not-found!
|
||||
// FIXME: if KYC check failed, generate 451 response!
|
||||
}
|
||||
|
||||
/* 2) create purse with reserve (and debit reserve for purse creation!) */
|
||||
{
|
||||
bool in_conflict = true;
|
||||
bool insufficient_funds = true;
|
||||
bool no_reserve = true;
|
||||
bool no_kyc = true;
|
||||
|
||||
qs = TEH_plugin->do_reserve_purse (
|
||||
TEH_plugin->cls,
|
||||
@ -315,6 +313,8 @@ purse_transaction (void *cls,
|
||||
: &rpc->gf->fees.purse,
|
||||
rpc->reserve_pub,
|
||||
&in_conflict,
|
||||
&no_reserve,
|
||||
&no_kyc,
|
||||
&insufficient_funds);
|
||||
if (qs < 0)
|
||||
{
|
||||
@ -377,6 +377,26 @@ purse_transaction (void *cls,
|
||||
GNUNET_free (partner_url);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
if (no_reserve)
|
||||
{
|
||||
*mhd_ret
|
||||
= TALER_MHD_REPLY_JSON_PACK (
|
||||
connection,
|
||||
MHD_HTTP_NOT_FOUND,
|
||||
TALER_JSON_pack_ec (
|
||||
TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN));
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
if (no_kyc)
|
||||
{
|
||||
*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
|
||||
|
@ -133,7 +133,7 @@ withdraw_transaction (void *cls,
|
||||
{
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_NOT_FOUND,
|
||||
TALER_EC_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN,
|
||||
TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN,
|
||||
NULL);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
@ -153,7 +153,7 @@ withdraw_transaction (void *cls,
|
||||
/* Wallet-to-wallet payments _always_ require KYC */
|
||||
*mhd_ret = TALER_MHD_REPLY_JSON_PACK (
|
||||
connection,
|
||||
MHD_HTTP_ACCEPTED,
|
||||
MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS,
|
||||
GNUNET_JSON_pack_uint64 ("payment_target_uuid",
|
||||
wc->kyc.payment_target_uuid));
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
@ -188,7 +188,7 @@ withdraw_transaction (void *cls,
|
||||
{
|
||||
*mhd_ret = TALER_MHD_REPLY_JSON_PACK (
|
||||
connection,
|
||||
MHD_HTTP_ACCEPTED,
|
||||
MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS,
|
||||
GNUNET_JSON_pack_uint64 ("payment_target_uuid",
|
||||
wc->kyc.payment_target_uuid));
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
|
@ -3092,6 +3092,8 @@ CREATE OR REPLACE FUNCTION exchange_do_purse_merge(
|
||||
IN in_reserve_pub BYTEA,
|
||||
OUT out_no_partner BOOLEAN,
|
||||
OUT out_no_balance BOOLEAN,
|
||||
OUT out_no_kyc BOOLEAN,
|
||||
OUT out_no_reserve BOOLEAN,
|
||||
OUT out_conflict BOOLEAN)
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
@ -3121,6 +3123,8 @@ ELSE
|
||||
THEN
|
||||
out_no_partner=TRUE;
|
||||
out_conflict=FALSE;
|
||||
out_no_kyc=FALSE;
|
||||
out_no_reserve=FALSE;
|
||||
RETURN;
|
||||
END IF;
|
||||
END IF;
|
||||
@ -3144,6 +3148,8 @@ IF NOT FOUND
|
||||
THEN
|
||||
out_no_balance=TRUE;
|
||||
out_conflict=FALSE;
|
||||
out_no_kyc=FALSE;
|
||||
out_no_reserve=FALSE;
|
||||
RETURN;
|
||||
END IF;
|
||||
out_no_balance=FALSE;
|
||||
@ -3176,17 +3182,49 @@ THEN
|
||||
THEN
|
||||
-- Purse was merged, but to some other reserve. Not allowed.
|
||||
out_conflict=TRUE;
|
||||
out_no_kyc=FALSE;
|
||||
out_no_reserve=FALSE;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
-- "success"
|
||||
out_conflict=FALSE;
|
||||
out_no_kyc=FALSE;
|
||||
out_no_reserve=FALSE;
|
||||
RETURN;
|
||||
END IF;
|
||||
out_conflict=FALSE;
|
||||
|
||||
ASSERT NOT my_finished, 'internal invariant failed';
|
||||
|
||||
IF in_partner_url IS NULL
|
||||
THEN
|
||||
-- Need to do KYC check.
|
||||
SELECT NOT kyc_passed
|
||||
INTO out_no_kyc
|
||||
FROM reserves
|
||||
WHERE reserve_pub=in_reserve_pub;
|
||||
|
||||
IF NOT FOUND
|
||||
THEN
|
||||
out_no_kyc=TRUE;
|
||||
out_no_reserve=TRUE;
|
||||
RETURN;
|
||||
END IF;
|
||||
out_no_reserve=FALSE;
|
||||
|
||||
IF (out_no_kyc)
|
||||
THEN
|
||||
RETURN;
|
||||
END IF;
|
||||
ELSE
|
||||
-- KYC is not our responsibility
|
||||
out_no_reserve=FALSE;
|
||||
out_no_kyc=FALSE;
|
||||
END IF;
|
||||
|
||||
|
||||
|
||||
-- Store account merge signature.
|
||||
INSERT INTO account_merges
|
||||
(reserve_pub
|
||||
@ -3248,6 +3286,8 @@ CREATE OR REPLACE FUNCTION exchange_do_reserve_purse(
|
||||
IN in_purse_fee_frac INT4,
|
||||
IN in_reserve_pub BYTEA,
|
||||
OUT out_no_funds BOOLEAN,
|
||||
OUT out_no_kyc BOOLEAN,
|
||||
OUT out_no_reserve BOOLEAN,
|
||||
OUT out_conflict BOOLEAN)
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
@ -3281,16 +3321,40 @@ THEN
|
||||
THEN
|
||||
-- Purse was merged, but to some other reserve. Not allowed.
|
||||
out_conflict=TRUE;
|
||||
out_no_kyc=FALSE;
|
||||
out_no_reserve=FALSE;
|
||||
out_no_funds=FALSE;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
-- "success"
|
||||
out_conflict=FALSE;
|
||||
out_no_funds=FALSE;
|
||||
out_no_kyc=FALSE;
|
||||
out_no_reserve=FALSE;
|
||||
RETURN;
|
||||
END IF;
|
||||
out_conflict=FALSE;
|
||||
|
||||
SELECT NOT kyc_passed
|
||||
INTO out_no_kyc
|
||||
FROM reserves
|
||||
WHERE reserve_pub=in_reserve_pub;
|
||||
|
||||
IF NOT FOUND
|
||||
THEN
|
||||
out_no_kyc=TRUE;
|
||||
out_no_reserve=TRUE;
|
||||
out_no_funds=TRUE;
|
||||
RETURN;
|
||||
END IF;
|
||||
out_no_reserve=FALSE;
|
||||
|
||||
IF (out_no_kyc)
|
||||
THEN
|
||||
out_no_funds=FALSE;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
IF (in_reserve_quota)
|
||||
THEN
|
||||
@ -3303,6 +3367,7 @@ THEN
|
||||
IF NOT FOUND
|
||||
THEN
|
||||
out_no_funds=TRUE;
|
||||
RETURN;
|
||||
END IF;
|
||||
ELSE
|
||||
-- UPDATE reserves balance (and check if balance is enough to pay the fee)
|
||||
@ -3328,6 +3393,7 @@ ELSE
|
||||
IF NOT FOUND
|
||||
THEN
|
||||
out_no_funds=TRUE;
|
||||
RETURN;
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
|
@ -3973,6 +3973,8 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
"SELECT"
|
||||
" out_no_partner AS no_partner"
|
||||
",out_no_balance AS no_balance"
|
||||
",out_no_kyc AS no_kyc"
|
||||
",out_no_reserve AS no_reserve"
|
||||
",out_conflict AS conflict"
|
||||
" FROM exchange_do_purse_merge"
|
||||
" ($1, $2, $3, $4, $5, $6);",
|
||||
@ -3982,6 +3984,8 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
"call_reserve_purse",
|
||||
"SELECT"
|
||||
" out_no_funds AS insufficient_funds"
|
||||
",out_no_reserve AS no_reserve"
|
||||
",out_no_kyc AS no_kyc"
|
||||
",out_conflict AS conflict"
|
||||
" FROM exchange_do_reserve_purse"
|
||||
" ($1, $2, $3, $4, $5, $6, $7, $8);",
|
||||
@ -14490,6 +14494,8 @@ postgres_get_purse_deposit (
|
||||
* @param reserve_pub public key of the reserve to credit
|
||||
* @param[out] no_partner set to true if @a partner_url is unknown
|
||||
* @param[out] no_balance set to true if the @a purse_pub is not paid up yet
|
||||
* @param[out] no_reserve set to true if the @a reserve_pub is not known
|
||||
* @param[out] no_kyc set to true if the @a reserve_pub lacks KYC
|
||||
* @param[out] in_conflict set to true if @a purse_pub was merged into a different reserve already
|
||||
* @return transaction status code
|
||||
*/
|
||||
@ -14504,6 +14510,8 @@ postgres_do_purse_merge (
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
bool *no_partner,
|
||||
bool *no_balance,
|
||||
bool *no_reserve,
|
||||
bool *no_kyc,
|
||||
bool *in_conflict)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
@ -14523,6 +14531,10 @@ postgres_do_purse_merge (
|
||||
no_partner),
|
||||
GNUNET_PQ_result_spec_bool ("no_balance",
|
||||
no_balance),
|
||||
GNUNET_PQ_result_spec_bool ("no_kyc",
|
||||
no_kyc),
|
||||
GNUNET_PQ_result_spec_bool ("no_reserve",
|
||||
no_reserve),
|
||||
GNUNET_PQ_result_spec_bool ("conflict",
|
||||
in_conflict),
|
||||
GNUNET_PQ_result_spec_end
|
||||
@ -14561,6 +14573,8 @@ postgres_do_reserve_purse (
|
||||
const struct TALER_Amount *purse_fee,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
bool *in_conflict,
|
||||
bool *no_reserve,
|
||||
bool *no_kyc,
|
||||
bool *insufficient_funds)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
@ -14582,6 +14596,10 @@ postgres_do_reserve_purse (
|
||||
insufficient_funds),
|
||||
GNUNET_PQ_result_spec_bool ("conflict",
|
||||
in_conflict),
|
||||
GNUNET_PQ_result_spec_bool ("no_kyc",
|
||||
no_kyc),
|
||||
GNUNET_PQ_result_spec_bool ("no_reserve",
|
||||
no_reserve),
|
||||
GNUNET_PQ_result_spec_end
|
||||
};
|
||||
|
||||
|
@ -5039,6 +5039,8 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
* @param reserve_pub public key of the reserve to credit
|
||||
* @param[out] no_partner set to true if @a partner_url is unknown
|
||||
* @param[out] no_balance set to true if the @a purse_pub is not paid up yet
|
||||
* @param[out] no_reserve set to true if the @a reserve_pub is not known
|
||||
* @param[out] no_kyc set to true if the @a reserve_pub lacks KYC
|
||||
* @param[out] in_conflict set to true if @a purse_pub was merged into a different reserve already
|
||||
* @return transaction status code
|
||||
*/
|
||||
@ -5053,6 +5055,8 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
bool *no_partner,
|
||||
bool *no_balance,
|
||||
bool *no_reserve,
|
||||
bool *no_kyc,
|
||||
bool *in_conflict);
|
||||
|
||||
|
||||
@ -5069,6 +5073,8 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
* @param purse_fee amount to charge the reserve for the purse creation, NULL to use the quota
|
||||
* @param reserve_pub public key of the reserve to credit
|
||||
* @param[out] in_conflict set to true if @a purse_pub was merged into a different reserve already
|
||||
* @param[out] no_reserve set to true if @a reserve_pub is not a known reserve
|
||||
* @param[out] no_kyc set to true if @a reserve_pub has not passed KYC checks
|
||||
* @param[out] insufficient_funds set to true if @a reserve_pub has insufficient capacity to create another purse
|
||||
* @return transaction status code
|
||||
*/
|
||||
@ -5082,6 +5088,8 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
const struct TALER_Amount *purse_fee,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
bool *in_conflict,
|
||||
bool *no_reserve,
|
||||
bool *no_kyc,
|
||||
bool *insufficient_funds);
|
||||
|
||||
|
||||
|
@ -203,7 +203,7 @@ handle_reserve_batch_withdraw_finished (
|
||||
wr.details.success.num_coins = wh->num_coins;
|
||||
break;
|
||||
}
|
||||
case MHD_HTTP_ACCEPTED:
|
||||
case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
|
||||
{
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_uint64 ("payment_target_uuid",
|
||||
|
@ -224,6 +224,11 @@ handle_purse_create_with_merge_finished (void *cls,
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
|
||||
/* aka KYC required */
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
|
@ -157,7 +157,7 @@ handle_reserve_withdraw_finished (
|
||||
wr.details.success.exchange_vals = wh->alg_values;
|
||||
break;
|
||||
}
|
||||
case MHD_HTTP_ACCEPTED:
|
||||
case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
|
||||
{
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_uint64 ("payment_target_uuid",
|
||||
|
@ -106,7 +106,7 @@ run (void *cls,
|
||||
"create-reserve-1",
|
||||
"EUR:10",
|
||||
0, /* age restriction off */
|
||||
MHD_HTTP_ACCEPTED),
|
||||
MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS),
|
||||
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1",
|
||||
"create-reserve-1",
|
||||
"EUR:5",
|
||||
@ -123,7 +123,7 @@ run (void *cls,
|
||||
"create-reserve-1",
|
||||
"EUR:5",
|
||||
0, /* age restriction off */
|
||||
MHD_HTTP_ACCEPTED),
|
||||
MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS),
|
||||
TALER_TESTING_cmd_proof_kyc ("proof-kyc",
|
||||
"create-reserve-1",
|
||||
"pass",
|
||||
|
@ -242,12 +242,12 @@ reserve_withdraw_cb (void *cls,
|
||||
{
|
||||
if (0 != ws->do_retry)
|
||||
{
|
||||
if (TALER_EC_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN != wr->hr.ec)
|
||||
if (TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN != wr->hr.ec)
|
||||
ws->do_retry--; /* we don't count reserve unknown as failures here */
|
||||
if ( (0 == wr->hr.http_status) ||
|
||||
(TALER_EC_GENERIC_DB_SOFT_FAILURE == wr->hr.ec) ||
|
||||
(TALER_EC_EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS == wr->hr.ec) ||
|
||||
(TALER_EC_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN == wr->hr.ec) ||
|
||||
(TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN == wr->hr.ec) ||
|
||||
(MHD_HTTP_INTERNAL_SERVER_ERROR == wr->hr.http_status) )
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
@ -257,7 +257,7 @@ reserve_withdraw_cb (void *cls,
|
||||
/* on DB conflicts, do not use backoff */
|
||||
if (TALER_EC_GENERIC_DB_SOFT_FAILURE == wr->hr.ec)
|
||||
ws->backoff = GNUNET_TIME_UNIT_ZERO;
|
||||
else if (TALER_EC_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN != wr->hr.ec)
|
||||
else if (TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN != wr->hr.ec)
|
||||
ws->backoff = EXCHANGE_LIB_BACKOFF (ws->backoff);
|
||||
else
|
||||
ws->backoff = GNUNET_TIME_relative_max (UNKNOWN_MIN_BACKOFF,
|
||||
|
Loading…
Reference in New Issue
Block a user