add test for KYC required on reserve close

This commit is contained in:
Christian Grothoff 2023-01-29 21:52:07 +01:00
parent e8c8aa9efe
commit a1c0c2fafd
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
5 changed files with 120 additions and 20 deletions

View File

@ -178,14 +178,13 @@ reserve_close_transaction (void *cls,
{ {
struct ReserveCloseContext *rcc = cls; struct ReserveCloseContext *rcc = cls;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
struct TALER_Amount balance;
char *payto_uri = NULL; char *payto_uri = NULL;
const struct TALER_WireFeeSet *wf; const struct TALER_WireFeeSet *wf;
qs = TEH_plugin->select_reserve_close_info ( qs = TEH_plugin->select_reserve_close_info (
TEH_plugin->cls, TEH_plugin->cls,
rcc->reserve_pub, rcc->reserve_pub,
&balance, &rcc->balance,
&payto_uri); &payto_uri);
switch (qs) switch (qs)
{ {
@ -226,6 +225,9 @@ reserve_close_transaction (void *cls,
(0 != strcmp (payto_uri, (0 != strcmp (payto_uri,
rcc->payto_uri)) ) ) rcc->payto_uri)) ) )
{ {
/* KYC check may be needed: we're not returning
the money to the account that funded the reserve
in the first place. */
const char *kyc_needed; const char *kyc_needed;
TALER_payto_hash (rcc->payto_uri, TALER_payto_hash (rcc->payto_uri,
@ -263,6 +265,8 @@ reserve_close_transaction (void *cls,
"iterate_reserve_close_info"); "iterate_reserve_close_info");
return qs; return qs;
} }
if (NULL != kyc_needed)
{
rcc->kyc.ok = false; rcc->kyc.ok = false;
return TEH_plugin->insert_kyc_requirement_for_account ( return TEH_plugin->insert_kyc_requirement_for_account (
TEH_plugin->cls, TEH_plugin->cls,
@ -270,6 +274,7 @@ reserve_close_transaction (void *cls,
&rcc->kyc_payto, &rcc->kyc_payto,
&rcc->kyc.requirement_row); &rcc->kyc.requirement_row);
} }
}
rcc->kyc.ok = true; rcc->kyc.ok = true;
if (NULL == rcc->payto_uri) if (NULL == rcc->payto_uri)
@ -296,7 +301,7 @@ reserve_close_transaction (void *cls,
if (0 > if (0 >
TALER_amount_subtract (&rcc->wire_amount, TALER_amount_subtract (&rcc->wire_amount,
&balance, &rcc->balance,
&wf->closing)) &wf->closing))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@ -314,7 +319,7 @@ reserve_close_transaction (void *cls,
payto_uri, payto_uri,
&rcc->reserve_sig, &rcc->reserve_sig,
rcc->timestamp, rcc->timestamp,
&balance, &rcc->balance,
&wf->closing); &wf->closing);
GNUNET_free (payto_uri); GNUNET_free (payto_uri);
if (GNUNET_DB_STATUS_HARD_ERROR == qs) if (GNUNET_DB_STATUS_HARD_ERROR == qs)

View File

@ -27,6 +27,27 @@ BASE_URL = "http://localhost:8083/"
# HTTP port the auditor listens to # HTTP port the auditor listens to
PORT = 8083 PORT = 8083
[kyc-provider-test-oauth2]
COST = 0
LOGIC = oauth2
USER_TYPE = INDIVIDUAL
PROVIDED_CHECKS = DUMMY
KYC_OAUTH2_VALIDITY = forever
KYC_OAUTH2_AUTH_URL = http://localhost:6666/oauth/v2/token
KYC_OAUTH2_LOGIN_URL = http://localhost:6666/oauth/v2/login
KYC_OAUTH2_INFO_URL = http://localhost:6666/api/user/me
KYC_OAUTH2_CLIENT_ID = taler-exchange
KYC_OAUTH2_CLIENT_SECRET = exchange-secret
KYC_OAUTH2_POST_URL = http://example.com/
KYC_OAUTH2_ATTRIBUTE_TEMPLATE = "{"full_name":"{{last_name}}, {{first_name}}"}"
[kyc-legitimization-close]
OPERATION_TYPE = CLOSE
REQUIRED_CHECKS = DUMMY
THRESHOLD = EUR:0
TIMEFRAME = 1d
[exchange] [exchange]
TERMS_ETAG = 0 TERMS_ETAG = 0

View File

@ -20,11 +20,9 @@
* @file testing/test_exchange_p2p.c * @file testing/test_exchange_p2p.c
* @brief testcase to test exchange's P2P payments * @brief testcase to test exchange's P2P payments
* @author Christian Grothoff * @author Christian Grothoff
*
* TODO:
* - enable reserve close test once implementation is complete!
*/ */
#include "platform.h" #include "platform.h"
#include "taler_attributes.h"
#include "taler_util.h" #include "taler_util.h"
#include "taler_signatures.h" #include "taler_signatures.h"
#include "taler_exchange_service.h" #include "taler_exchange_service.h"
@ -454,10 +452,30 @@ run (void *cls,
MHD_HTTP_NOT_FOUND, MHD_HTTP_NOT_FOUND,
"nx-attribute-name", "nx-attribute-name",
NULL), NULL),
/* FIXME: do KYC for reserve, then get actual attributes attested */ TALER_TESTING_cmd_oauth ("start-oauth-service",
6666),
TALER_TESTING_cmd_reserve_close ("reserve-101-close-kyc",
"create-reserve-101",
/* 42b => not to origin */
"payto://x-taler-bank/localhost/42?receiver-name=42b",
MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS),
TALER_TESTING_cmd_check_kyc_get ("check-kyc-close-pending",
"reserve-101-close-kyc",
MHD_HTTP_ACCEPTED),
TALER_TESTING_cmd_proof_kyc_oauth2 ("proof-close-kyc",
"reserve-101-close-kyc",
"kyc-provider-test-oauth2",
"pass",
MHD_HTTP_SEE_OTHER),
TALER_TESTING_cmd_check_kyc_get ("check-kyc-close-ok",
"reserve-101-close-kyc",
MHD_HTTP_NO_CONTENT),
/* Now it should pass */
TALER_TESTING_cmd_reserve_close ("reserve-101-close", TALER_TESTING_cmd_reserve_close ("reserve-101-close",
"create-reserve-101", "create-reserve-101",
NULL, /* to origin */ /* 42b => not to origin */
"payto://x-taler-bank/localhost/42?receiver-name=42b",
MHD_HTTP_OK), MHD_HTTP_OK),
TALER_TESTING_cmd_exec_closer ("close-reserves-101", TALER_TESTING_cmd_exec_closer ("close-reserves-101",
config_file, config_file,

View File

@ -227,7 +227,7 @@ run (void *cls,
MHD_HTTP_OK, MHD_HTTP_OK,
TALER_ATTRIBUTE_FULL_NAME, TALER_ATTRIBUTE_FULL_NAME,
NULL), NULL),
TALER_TESTING_cmd_reserve_attest ("wallet-get-attestable", TALER_TESTING_cmd_reserve_attest ("wallet-get-attest",
"wallet-kyc-fail", "wallet-kyc-fail",
MHD_HTTP_OK, MHD_HTTP_OK,
TALER_ATTRIBUTE_FULL_NAME, TALER_ATTRIBUTE_FULL_NAME,

View File

@ -67,6 +67,18 @@ struct CloseState
* Interpreter state. * Interpreter state.
*/ */
struct TALER_TESTING_Interpreter *is; struct TALER_TESTING_Interpreter *is;
/**
* Set to the KYC requirement payto hash *if* the exchange replied with a
* request for KYC.
*/
struct TALER_PaytoHashP h_payto;
/**
* Set to the KYC requirement row *if* the exchange replied with
* a request for KYC.
*/
uint64_t requirement_row;
}; };
@ -98,10 +110,19 @@ reserve_close_cb (void *cls,
TALER_TESTING_interpreter_fail (ss->is); TALER_TESTING_interpreter_fail (ss->is);
return; return;
} }
if (MHD_HTTP_OK != rs->hr.http_status) switch (rs->hr.http_status)
{ {
TALER_TESTING_interpreter_next (is); case MHD_HTTP_OK:
return; break;
case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
/* nothing to check */
ss->requirement_row
= rs->details.unavailable_for_legal_reasons.requirement_row;
ss->h_payto
= rs->details.unavailable_for_legal_reasons.h_payto;
break;
default:
break;
} }
TALER_TESTING_interpreter_next (is); TALER_TESTING_interpreter_next (is);
} }
@ -178,6 +199,40 @@ close_cleanup (void *cls,
} }
/**
* Offer internal data to a "close" CMD state to other
* commands.
*
* @param cls closure
* @param[out] ret result (could be anything)
* @param trait name of the trait
* @param index index number of the object to offer.
* @return #GNUNET_OK on success
*/
static enum GNUNET_GenericReturnValue
close_traits (void *cls,
const void **ret,
const char *trait,
unsigned int index)
{
struct CloseState *cs = cls;
struct TALER_TESTING_Trait traits[] = {
TALER_TESTING_make_trait_legi_requirement_row (
&cs->requirement_row),
TALER_TESTING_make_trait_h_payto (
&cs->h_payto),
TALER_TESTING_trait_end ()
};
if (cs->expected_response_code != MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)
return GNUNET_NO;
return TALER_TESTING_get_trait (traits,
ret,
trait,
index);
}
struct TALER_TESTING_Command struct TALER_TESTING_Command
TALER_TESTING_cmd_reserve_close (const char *label, TALER_TESTING_cmd_reserve_close (const char *label,
const char *reserve_reference, const char *reserve_reference,
@ -196,7 +251,8 @@ TALER_TESTING_cmd_reserve_close (const char *label,
.cls = ss, .cls = ss,
.label = label, .label = label,
.run = &close_run, .run = &close_run,
.cleanup = &close_cleanup .cleanup = &close_cleanup,
.traits = &close_traits
}; };
return cmd; return cmd;