Compare commits

...

10 Commits

Author SHA1 Message Date
Christian Grothoff
402ca17600
-fix warning 2023-01-16 11:28:13 +01:00
Christian Grothoff
d5619de525
fix test_kyc_api: adapt test logic to improved OAuth2.0 kyc API: 2023-01-16 11:25:18 +01:00
Christian Grothoff
6231c365fd
-fix KYC logic change to work for all plugins and not just OAuth2.0 2023-01-16 11:14:59 +01:00
Christian Grothoff
cbb021b6bf
-fix compiler warning: add missing prototype 2023-01-15 22:58:07 +01:00
MS
50a33389da
libeufin-based bank API test
Give Nexus and Sandbox one database each,
in order to reduce concurrent accesses to
the sqlite3 file.
2023-01-13 22:59:22 +01:00
Sebastian
f8ddd0b685
fix kyc-proof handle
1.- redirect_uri has an extra slash
2.- response_type=code is required https://www.rfc-editor.org/rfc/rfc6749#section-3.1.1
3.- add more info to "Unexpected response from KYC gateway"
4.- relax the requirements on the login response, marked as optional
5.- redirect_uri should be the same when exchanging the code for the access_token,
6.- remove legi and payto from kyc-proof path
7.- use state to transport h_payto https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
2023-01-13 12:16:44 -03:00
4374b1868e
gana 2023-01-13 13:12:58 +01:00
Christian Grothoff
f487cf43b3
-make LP delay configurable 2023-01-13 10:52:32 +01:00
Christian Grothoff
caaa90d3d8
-make LP delay configurable 2023-01-13 10:51:45 +01:00
Christian Grothoff
0ac0344d84
exchangedb: remove bogus foreign key constraint 2023-01-13 10:42:34 +01:00
18 changed files with 170 additions and 133 deletions

@ -1 +1 @@
Subproject commit 9753b06eded9186429380f002a073adee06dccfc Subproject commit 832685b6a942a6ebbec8e1e5b8c33b6b85b0a727

View File

@ -1258,8 +1258,7 @@ handle_mhd_request (void *cls,
.url = "kyc-proof", .url = "kyc-proof",
.method = MHD_HTTP_METHOD_GET, .method = MHD_HTTP_METHOD_GET,
.handler.get = &TEH_handler_kyc_proof, .handler.get = &TEH_handler_kyc_proof,
.nargs = 128, .nargs = 1
.nargs_is_upper_bound = true
}, },
{ {
.url = "kyc-wallet", .url = "kyc-wallet",

View File

@ -256,30 +256,41 @@ clean_kpc (struct TEH_RequestContext *rc)
MHD_RESULT MHD_RESULT
TEH_handler_kyc_proof ( TEH_handler_kyc_proof (
struct TEH_RequestContext *rc, struct TEH_RequestContext *rc,
const char *const args[3]) const char *const args[1])
{ {
struct KycProofContext *kpc = rc->rh_ctx; struct KycProofContext *kpc = rc->rh_ctx;
const char *provider_section_or_logic = args[0];
const char *h_payto;
if (NULL == kpc) if (NULL == kpc)
{ {
/* first time */ /* first time */
if ( (NULL == args[0]) || if (NULL == provider_section_or_logic)
(NULL == args[1]) )
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return TALER_MHD_reply_with_error (rc->connection, return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_NOT_FOUND, MHD_HTTP_NOT_FOUND,
TALER_EC_GENERIC_ENDPOINT_UNKNOWN, TALER_EC_GENERIC_ENDPOINT_UNKNOWN,
"'/kyc-proof/$H_PATYO/$LOGIC' required"); "'/kyc-proof/$PROVIDER_SECTION?state=$H_PAYTO' required");
}
h_payto = MHD_lookup_connection_value (rc->connection,
MHD_GET_ARGUMENT_KIND,
"state");
if (NULL == h_payto)
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_GENERIC_PARAMETER_MISSING,
"h_payto");
} }
kpc = GNUNET_new (struct KycProofContext); kpc = GNUNET_new (struct KycProofContext);
kpc->rc = rc; kpc->rc = rc;
rc->rh_ctx = kpc; rc->rh_ctx = kpc;
rc->rh_cleaner = &clean_kpc; rc->rh_cleaner = &clean_kpc;
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[0], GNUNET_STRINGS_string_to_data (h_payto,
strlen (args[0]), strlen (h_payto),
&kpc->h_payto, &kpc->h_payto,
sizeof (kpc->h_payto))) sizeof (kpc->h_payto)))
{ {
@ -290,7 +301,7 @@ TEH_handler_kyc_proof (
"h_payto"); "h_payto");
} }
if (GNUNET_OK != if (GNUNET_OK !=
TALER_KYCLOGIC_lookup_logic (args[1], TALER_KYCLOGIC_lookup_logic (provider_section_or_logic,
&kpc->logic, &kpc->logic,
&kpc->pd, &kpc->pd,
&kpc->provider_section)) &kpc->provider_section))
@ -299,14 +310,14 @@ TEH_handler_kyc_proof (
return TALER_MHD_reply_with_error (rc->connection, return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_NOT_FOUND, MHD_HTTP_NOT_FOUND,
TALER_EC_EXCHANGE_KYC_GENERIC_LOGIC_UNKNOWN, TALER_EC_EXCHANGE_KYC_GENERIC_LOGIC_UNKNOWN,
args[1]); provider_section_or_logic);
} }
if (NULL != kpc->provider_section) if (NULL != kpc->provider_section)
{ {
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
struct GNUNET_TIME_Absolute expiration; struct GNUNET_TIME_Absolute expiration;
if (0 != strcmp (args[1], if (0 != strcmp (provider_section_or_logic,
kpc->provider_section)) kpc->provider_section))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
@ -352,7 +363,6 @@ TEH_handler_kyc_proof (
} }
kpc->ph = kpc->logic->proof (kpc->logic->cls, kpc->ph = kpc->logic->proof (kpc->logic->cls,
kpc->pd, kpc->pd,
&args[2],
rc->connection, rc->connection,
&kpc->h_payto, &kpc->h_payto,
kpc->process_row, kpc->process_row,

View File

@ -105,6 +105,12 @@ static struct GNUNET_TIME_Absolute shard_end_time;
*/ */
static struct GNUNET_TIME_Relative shard_delay; static struct GNUNET_TIME_Relative shard_delay;
/**
* How long did we take to finish the last shard
* for this account?
*/
static struct GNUNET_TIME_Relative longpoll_timeout;
/** /**
* Name of our job in the shard table. * Name of our job in the shard table.
*/ */
@ -474,7 +480,7 @@ transaction_completed (void)
struct GNUNET_TIME_Relative left; struct GNUNET_TIME_Relative left;
latency = GNUNET_TIME_absolute_get_duration (hh_start_time); latency = GNUNET_TIME_absolute_get_duration (hh_start_time);
left = GNUNET_TIME_relative_subtract (LONGPOLL_TIMEOUT, left = GNUNET_TIME_relative_subtract (longpoll_timeout,
latency); latency);
delayed_until = GNUNET_TIME_relative_to_absolute (left); delayed_until = GNUNET_TIME_relative_to_absolute (left);
} }
@ -1157,7 +1163,7 @@ continue_with_shard (void *cls)
limit, limit,
test_mode test_mode
? GNUNET_TIME_UNIT_ZERO ? GNUNET_TIME_UNIT_ZERO
: LONGPOLL_TIMEOUT, : longpoll_timeout,
&history_cb, &history_cb,
NULL); NULL);
if (NULL == hh) if (NULL == hh)
@ -1365,6 +1371,11 @@ main (int argc,
"exit-on-error", "exit-on-error",
"terminate wirewatch if we failed to download information from the bank", "terminate wirewatch if we failed to download information from the bank",
&exit_on_error), &exit_on_error),
GNUNET_GETOPT_option_relative_time ('f',
"longpoll-timeout",
"DELAY",
"what is the timeout when asking the bank about new transactions",
&longpoll_timeout),
GNUNET_GETOPT_option_flag ('I', GNUNET_GETOPT_option_flag ('I',
"ignore-not-found", "ignore-not-found",
"continue, even if the bank account of the exchange was not found", "continue, even if the bank account of the exchange was not found",
@ -1390,6 +1401,7 @@ main (int argc,
}; };
enum GNUNET_GenericReturnValue ret; enum GNUNET_GenericReturnValue ret;
longpoll_timeout = LONGPOLL_TIMEOUT;
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_STRINGS_get_utf8_args (argc, argv, GNUNET_STRINGS_get_utf8_args (argc, argv,
&argc, &argv)) &argc, &argv))

View File

@ -117,9 +117,6 @@ BEGIN
' ADD CONSTRAINT ' || table_name || '_foreign_partner_serial_id' ' ADD CONSTRAINT ' || table_name || '_foreign_partner_serial_id'
' FOREIGN KEY (partner_serial_id) ' ' FOREIGN KEY (partner_serial_id) '
' REFERENCES partners(partner_serial_id) ON DELETE CASCADE' ' REFERENCES partners(partner_serial_id) ON DELETE CASCADE'
',ADD CONSTRAINT ' || table_name || '_foreign_reserve_pub'
' FOREIGN KEY (reserve_pub) '
' REFERENCES reserves (reserve_pub) ON DELETE CASCADE'
',ADD CONSTRAINT ' || table_name || '_foreign_purse_pub' ',ADD CONSTRAINT ' || table_name || '_foreign_purse_pub'
' FOREIGN KEY (purse_pub) ' ' FOREIGN KEY (purse_pub) '
' REFERENCES purse_requests (purse_pub) ON DELETE CASCADE' ' REFERENCES purse_requests (purse_pub) ON DELETE CASCADE'

View File

@ -3600,8 +3600,7 @@ struct TALER_EXCHANGE_KycProofHandle;
* @param h_payto hash of payto URI identifying the target account * @param h_payto hash of payto URI identifying the target account
* @param logic name of the KYC logic to run * @param logic name of the KYC logic to run
* @param args additional args to pass, can be NULL * @param args additional args to pass, can be NULL
* or a string to append to the URL. Must * or a string to append to the URL. Must then begin with '&'.
* then begin with '/' or '?'.
* @param cb function to call with the result * @param cb function to call with the result
* @param cb_cls closure for @a cb * @param cb_cls closure for @a cb
* @return NULL on error * @return NULL on error

View File

@ -303,7 +303,6 @@ struct TALER_KYCLOGIC_Plugin
* *
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param pd provider configuration details * @param pd provider configuration details
* @param url_path rest of the URL after `/kyc-webhook/$H_PAYTO/$LOGIC`
* @param connection MHD connection object (for HTTP headers) * @param connection MHD connection object (for HTTP headers)
* @param account_id which account to trigger process for * @param account_id which account to trigger process for
* @param process_row row in the legitimization processes table the legitimization is for * @param process_row row in the legitimization processes table the legitimization is for
@ -316,7 +315,6 @@ struct TALER_KYCLOGIC_Plugin
struct TALER_KYCLOGIC_ProofHandle * struct TALER_KYCLOGIC_ProofHandle *
(*proof)(void *cls, (*proof)(void *cls,
const struct TALER_KYCLOGIC_ProviderDetails *pd, const struct TALER_KYCLOGIC_ProviderDetails *pd,
const char *const url_path[],
struct MHD_Connection *connection, struct MHD_Connection *connection,
const struct TALER_PaytoHashP *account_id, const struct TALER_PaytoHashP *account_id,
uint64_t process_row, uint64_t process_row,

View File

@ -868,6 +868,24 @@ struct GNUNET_OS_Process *
TALER_TESTING_run_bank (const char *config_filename, TALER_TESTING_run_bank (const char *config_filename,
const char *bank_url); const char *bank_url);
/**
* Prepare libeufin sandbox execution. Check if the port is available and
* reset database.
*
* @param config_filename configuration file name.
* @param reset_db should we reset the bank's database
* @param config_section which configuration section should be used
* @param[out] bc set to the bank's configuration data
* @return #GNUNET_OK on success
*/
enum GNUNET_GenericReturnValue
TALER_TESTING_prepare_libeufin (const char *config_filename,
bool reset_db,
const char *config_section,
struct TALER_TESTING_BankConfiguration *bc);
/** /**
* Start the (nexus) bank process. Assume the port * Start the (nexus) bank process. Assume the port
* is available and the database is clean. Use the "prepare * is available and the database is clean. Use the "prepare
@ -909,7 +927,7 @@ TALER_TESTING_run_fakebank (const char *bank_url,
*/ */
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_TESTING_prepare_bank (const char *config_filename, TALER_TESTING_prepare_bank (const char *config_filename,
int reset_db, bool reset_db,
const char *config_section, const char *config_section,
struct TALER_TESTING_BankConfiguration *bc); struct TALER_TESTING_BankConfiguration *bc);
@ -2517,7 +2535,6 @@ TALER_TESTING_cmd_check_kyc_get (const char *label,
* @param logic_section name of the KYC provider section * @param logic_section name of the KYC provider section
* in the exchange configuration for this proof * in the exchange configuration for this proof
* @param code OAuth 2.0 code to use * @param code OAuth 2.0 code to use
* @param state OAuth 2.0 state to use
* @param expected_response_code expected HTTP status * @param expected_response_code expected HTTP status
* @return the command * @return the command
*/ */
@ -2527,7 +2544,6 @@ TALER_TESTING_cmd_proof_kyc_oauth2 (
const char *payment_target_reference, const char *payment_target_reference,
const char *logic_section, const char *logic_section,
const char *code, const char *code,
const char *state,
unsigned int expected_response_code); unsigned int expected_response_code);

View File

@ -643,7 +643,6 @@ proof_reply (void *cls)
* *
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param pd provider configuration details * @param pd provider configuration details
* @param url_path rest of the URL after `/kyc-webhook/`
* @param connection MHD connection object (for HTTP headers) * @param connection MHD connection object (for HTTP headers)
* @param account_id which account to trigger process for * @param account_id which account to trigger process for
* @param process_row row in the legitimization processes table the legitimization is for * @param process_row row in the legitimization processes table the legitimization is for
@ -656,7 +655,6 @@ proof_reply (void *cls)
static struct TALER_KYCLOGIC_ProofHandle * static struct TALER_KYCLOGIC_ProofHandle *
kycaid_proof (void *cls, kycaid_proof (void *cls,
const struct TALER_KYCLOGIC_ProviderDetails *pd, const struct TALER_KYCLOGIC_ProviderDetails *pd,
const char *const url_path[],
struct MHD_Connection *connection, struct MHD_Connection *connection,
const struct TALER_PaytoHashP *account_id, const struct TALER_PaytoHashP *account_id,
uint64_t process_row, uint64_t process_row,

View File

@ -474,18 +474,17 @@ initiate_task (void *cls)
hps = GNUNET_STRINGS_data_to_string_alloc (&ih->h_payto, hps = GNUNET_STRINGS_data_to_string_alloc (&ih->h_payto,
sizeof (ih->h_payto)); sizeof (ih->h_payto));
GNUNET_asprintf (&redirect_uri, GNUNET_asprintf (&redirect_uri,
"%s/kyc-proof/%s/%s/%s", "%skyc-proof/%s",
ps->exchange_base_url, ps->exchange_base_url,
hps, pd->section);
pd->section,
legi_s);
redirect_uri_encoded = TALER_urlencode (redirect_uri); redirect_uri_encoded = TALER_urlencode (redirect_uri);
GNUNET_free (redirect_uri); GNUNET_free (redirect_uri);
GNUNET_asprintf (&url, GNUNET_asprintf (&url,
"%s?client_id=%s&redirect_uri=%s", "%s?response_type=code&client_id=%s&redirect_uri=%s&state=%s",
pd->login_url, pd->login_url,
pd->client_id, pd->client_id,
redirect_uri_encoded); redirect_uri_encoded,
hps);
GNUNET_free (redirect_uri_encoded); GNUNET_free (redirect_uri_encoded);
ih->cb (ih->cb_cls, ih->cb (ih->cb_cls,
TALER_EC_NONE, TALER_EC_NONE,
@ -611,7 +610,7 @@ handle_proof_error (struct TALER_KYCLOGIC_ProofHandle *ph,
ph->response ph->response
= TALER_MHD_make_error ( = TALER_MHD_make_error (
TALER_EC_EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE, TALER_EC_EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE,
"Unexpected response from KYC gateway"); "Unexpected response from KYC gateway: proof error");
ph->http_status ph->http_status
= MHD_HTTP_BAD_GATEWAY; = MHD_HTTP_BAD_GATEWAY;
return; return;
@ -679,7 +678,7 @@ parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph,
ph->response ph->response
= TALER_MHD_make_error ( = TALER_MHD_make_error (
TALER_EC_EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE, TALER_EC_EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE,
"Unexpected response from KYC gateway"); "Unexpected response from KYC gateway: proof success must contain data and status");
ph->http_status ph->http_status
= MHD_HTTP_BAD_GATEWAY; = MHD_HTTP_BAD_GATEWAY;
return; return;
@ -714,7 +713,7 @@ parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph,
ph->response ph->response
= TALER_MHD_make_error ( = TALER_MHD_make_error (
TALER_EC_EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE, TALER_EC_EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE,
"Unexpected response from KYC gateway"); "Unexpected response from KYC gateway: data must contain id");
ph->http_status ph->http_status
= MHD_HTTP_BAD_GATEWAY; = MHD_HTTP_BAD_GATEWAY;
return; return;
@ -797,15 +796,23 @@ handle_curl_login_finished (void *cls,
const char *token_type; const char *token_type;
uint64_t expires_in_s; uint64_t expires_in_s;
const char *refresh_token; const char *refresh_token;
bool no_expires;
bool no_refresh;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string ("access_token", GNUNET_JSON_spec_string ("access_token",
&access_token), &access_token),
GNUNET_JSON_spec_string ("token_type", GNUNET_JSON_spec_string ("token_type",
&token_type), &token_type),
GNUNET_JSON_spec_uint64 ("expires_in", GNUNET_JSON_spec_mark_optional (
&expires_in_s), GNUNET_JSON_spec_uint64 ("expires_in",
GNUNET_JSON_spec_string ("refresh_token", &expires_in_s),
&refresh_token), &no_expires
),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("refresh_token",
&refresh_token),
&no_refresh
),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()
}; };
CURL *eh; CURL *eh;
@ -825,7 +832,7 @@ handle_curl_login_finished (void *cls,
ph->response ph->response
= TALER_MHD_make_error ( = TALER_MHD_make_error (
TALER_EC_EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE, TALER_EC_EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE,
"Unexpected response from KYC gateway"); "Unexpected response from KYC gateway: login finished");
ph->http_status ph->http_status
= MHD_HTTP_BAD_GATEWAY; = MHD_HTTP_BAD_GATEWAY;
break; break;
@ -918,7 +925,6 @@ handle_curl_login_finished (void *cls,
* *
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param pd provider configuration details * @param pd provider configuration details
* @param url_path rest of the URL after `/kyc-webhook/`
* @param connection MHD connection object (for HTTP headers) * @param connection MHD connection object (for HTTP headers)
* @param account_id which account to trigger process for * @param account_id which account to trigger process for
* @param process_row row in the legitimization processes table the legitimization is for * @param process_row row in the legitimization processes table the legitimization is for
@ -931,7 +937,6 @@ handle_curl_login_finished (void *cls,
static struct TALER_KYCLOGIC_ProofHandle * static struct TALER_KYCLOGIC_ProofHandle *
oauth2_proof (void *cls, oauth2_proof (void *cls,
const struct TALER_KYCLOGIC_ProviderDetails *pd, const struct TALER_KYCLOGIC_ProviderDetails *pd,
const char *const url_path[],
struct MHD_Connection *connection, struct MHD_Connection *connection,
const struct TALER_PaytoHashP *account_id, const struct TALER_PaytoHashP *account_id,
uint64_t process_row, uint64_t process_row,
@ -944,7 +949,6 @@ oauth2_proof (void *cls,
struct TALER_KYCLOGIC_ProofHandle *ph; struct TALER_KYCLOGIC_ProofHandle *ph;
const char *code; const char *code;
(void) url_path;
GNUNET_break (NULL == provider_user_id); GNUNET_break (NULL == provider_user_id);
ph = GNUNET_new (struct TALER_KYCLOGIC_ProofHandle); ph = GNUNET_new (struct TALER_KYCLOGIC_ProofHandle);
GNUNET_snprintf (ph->provider_legitimization_id, GNUNET_snprintf (ph->provider_legitimization_id,
@ -959,6 +963,7 @@ oauth2_proof (void *cls,
GNUNET_free (ph); GNUNET_free (ph);
return NULL; return NULL;
} }
ph->pd = pd; ph->pd = pd;
ph->connection = connection; ph->connection = connection;
ph->h_payto = *account_id; ph->h_payto = *account_id;
@ -1008,23 +1013,24 @@ oauth2_proof (void *cls,
char *client_secret; char *client_secret;
char *authorization_code; char *authorization_code;
char *redirect_uri_encoded;
char *hps;
hps = GNUNET_STRINGS_data_to_string_alloc (&ph->h_payto,
sizeof (ph->h_payto));
GNUNET_asprintf (&redirect_uri,
"%skyc-proof/%s",
ps->exchange_base_url,
pd->section);
redirect_uri_encoded = TALER_urlencode (redirect_uri);
GNUNET_free (redirect_uri);
GNUNET_assert (NULL != redirect_uri_encoded);
client_id = curl_easy_escape (ph->eh, client_id = curl_easy_escape (ph->eh,
pd->client_id, pd->client_id,
0); 0);
GNUNET_assert (NULL != client_id); GNUNET_assert (NULL != client_id);
{
char *request_uri;
GNUNET_asprintf (&request_uri,
"%s?client_id=%s",
pd->login_url,
pd->client_id);
redirect_uri = curl_easy_escape (ph->eh,
request_uri,
0);
GNUNET_free (request_uri);
}
GNUNET_assert (NULL != redirect_uri);
client_secret = curl_easy_escape (ph->eh, client_secret = curl_easy_escape (ph->eh,
pd->client_secret, pd->client_secret,
0); 0);
@ -1036,12 +1042,13 @@ oauth2_proof (void *cls,
GNUNET_asprintf (&ph->post_body, GNUNET_asprintf (&ph->post_body,
"client_id=%s&redirect_uri=%s&client_secret=%s&code=%s&grant_type=authorization_code", "client_id=%s&redirect_uri=%s&client_secret=%s&code=%s&grant_type=authorization_code",
client_id, client_id,
redirect_uri, redirect_uri_encoded,
client_secret, client_secret,
authorization_code); authorization_code);
curl_free (authorization_code); curl_free (authorization_code);
curl_free (client_secret); curl_free (client_secret);
curl_free (redirect_uri); curl_free (redirect_uri_encoded);
curl_free (hps);
curl_free (client_id); curl_free (client_id);
} }
GNUNET_assert (CURLE_OK == GNUNET_assert (CURLE_OK ==

View File

@ -747,13 +747,14 @@ persona_initiate (void *cls,
(unsigned long long) ih->legitimization_uuid); (unsigned long long) ih->legitimization_uuid);
payto_s = GNUNET_STRINGS_data_to_string_alloc (&ih->h_payto, payto_s = GNUNET_STRINGS_data_to_string_alloc (&ih->h_payto,
sizeof (ih->h_payto)); sizeof (ih->h_payto));
/* NOTE: check here that exchange_base_url ends GNUNET_break ('/' ==
with a '/'? */ pd->ps->exchange_base_url[strlen (
pd->ps->exchange_base_url) - 1]);
GNUNET_asprintf (&proof_url, GNUNET_asprintf (&proof_url,
"%skyc-proof/%s/%s", "%skyc-proof/%s?state=%s",
pd->ps->exchange_base_url, pd->ps->exchange_base_url,
payto_s, pd->section,
pd->section); payto_s);
body = GNUNET_JSON_PACK ( body = GNUNET_JSON_PACK (
GNUNET_JSON_pack_object_steal ( GNUNET_JSON_pack_object_steal (
"data", "data",
@ -1345,7 +1346,6 @@ handle_proof_finished (void *cls,
* *
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param pd provider configuration details * @param pd provider configuration details
* @param url_path rest of the URL after `/kyc-webhook/`
* @param connection MHD connection object (for HTTP headers) * @param connection MHD connection object (for HTTP headers)
* @param account_id which account to trigger process for * @param account_id which account to trigger process for
* @param process_row row in the legitimization processes table the legitimization is for * @param process_row row in the legitimization processes table the legitimization is for
@ -1358,7 +1358,6 @@ handle_proof_finished (void *cls,
static struct TALER_KYCLOGIC_ProofHandle * static struct TALER_KYCLOGIC_ProofHandle *
persona_proof (void *cls, persona_proof (void *cls,
const struct TALER_KYCLOGIC_ProviderDetails *pd, const struct TALER_KYCLOGIC_ProviderDetails *pd,
const char *const url_path[],
struct MHD_Connection *connection, struct MHD_Connection *connection,
const struct TALER_PaytoHashP *account_id, const struct TALER_PaytoHashP *account_id,
uint64_t process_row, uint64_t process_row,

View File

@ -279,7 +279,6 @@ template_proof_cancel (struct TALER_KYCLOGIC_ProofHandle *ph)
* *
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param pd provider configuration details * @param pd provider configuration details
* @param url_path rest of the URL after `/kyc-webhook/`
* @param connection MHD connection object (for HTTP headers) * @param connection MHD connection object (for HTTP headers)
* @param account_id which account to trigger process for * @param account_id which account to trigger process for
* @param process_row row in the legitimization processes table the legitimization is for * @param process_row row in the legitimization processes table the legitimization is for
@ -292,7 +291,6 @@ template_proof_cancel (struct TALER_KYCLOGIC_ProofHandle *ph)
static struct TALER_KYCLOGIC_ProofHandle * static struct TALER_KYCLOGIC_ProofHandle *
template_proof (void *cls, template_proof (void *cls,
const struct TALER_KYCLOGIC_ProviderDetails *pd, const struct TALER_KYCLOGIC_ProviderDetails *pd,
const char *const url_path[],
struct MHD_Connection *connection, struct MHD_Connection *connection,
const struct TALER_PaytoHashP *account_id, const struct TALER_PaytoHashP *account_id,
uint64_t process_row, uint64_t process_row,
@ -304,7 +302,6 @@ template_proof (void *cls,
struct PluginState *ps = cls; struct PluginState *ps = cls;
struct TALER_KYCLOGIC_ProofHandle *ph; struct TALER_KYCLOGIC_ProofHandle *ph;
(void) url_path;
(void) account_id; (void) account_id;
(void) process_row; (void) process_row;
(void) provider_user_id; (void) provider_user_id;

View File

@ -727,32 +727,42 @@ proof_cb (
* *
* @param rc request context * @param rc request context
* @param args remaining URL arguments; * @param args remaining URL arguments;
* args[0] is the 'h_payto', * args[0] should be the logic plugin name
* args[1] should be the logic plugin name
*/ */
static MHD_RESULT static MHD_RESULT
handler_kyc_proof_get ( handler_kyc_proof_get (
struct TEKT_RequestContext *rc, struct TEKT_RequestContext *rc,
const char *const args[]) const char *const args[1])
{ {
struct TALER_PaytoHashP h_payto; struct TALER_PaytoHashP h_payto;
struct TALER_KYCLOGIC_ProviderDetails *pd; struct TALER_KYCLOGIC_ProviderDetails *pd;
struct TALER_KYCLOGIC_Plugin *logic; struct TALER_KYCLOGIC_Plugin *logic;
struct ProofRequestState *rs; struct ProofRequestState *rs;
const char *section_name; const char *section_name;
const char *h_paytos;
if ( (NULL == args[0]) || if (NULL == args[0])
(NULL == args[1]) )
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return TALER_MHD_reply_with_error (rc->connection, return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_NOT_FOUND, MHD_HTTP_NOT_FOUND,
TALER_EC_GENERIC_ENDPOINT_UNKNOWN, TALER_EC_GENERIC_ENDPOINT_UNKNOWN,
"'/$H_PAYTO/$LOGIC' required after '/kyc-proof'"); "'/kyc-proof/$PROVIDER_SECTION?state=$H_PAYTO' required");
}
h_paytos = MHD_lookup_connection_value (rc->connection,
MHD_GET_ARGUMENT_KIND,
"state");
if (NULL == h_paytos)
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_GENERIC_PARAMETER_MISSING,
"h_payto");
} }
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[0], GNUNET_STRINGS_string_to_data (h_paytos,
strlen (args[0]), strlen (h_paytos),
&h_payto, &h_payto,
sizeof (h_payto))) sizeof (h_payto)))
{ {
@ -774,18 +784,18 @@ handler_kyc_proof_get (
} }
if (GNUNET_OK != if (GNUNET_OK !=
TALER_KYCLOGIC_lookup_logic (args[1], TALER_KYCLOGIC_lookup_logic (args[0],
&logic, &logic,
&pd, &pd,
&section_name)) &section_name))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Could not initiate KYC with provider `%s' (configuration error?)\n", "Could not initiate KYC with provider `%s' (configuration error?)\n",
args[1]); args[0]);
return TALER_MHD_reply_with_error (rc->connection, return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_NOT_FOUND, MHD_HTTP_NOT_FOUND,
TALER_EC_EXCHANGE_KYC_GENERIC_LOGIC_UNKNOWN, TALER_EC_EXCHANGE_KYC_GENERIC_LOGIC_UNKNOWN,
args[1]); args[0]);
} }
rs = GNUNET_new (struct ProofRequestState); rs = GNUNET_new (struct ProofRequestState);
rs->rc = rc; rs->rc = rc;
@ -796,7 +806,6 @@ handler_kyc_proof_get (
rs); rs);
rs->ph = logic->proof (logic->cls, rs->ph = logic->proof (logic->cls,
pd, pd,
&args[2],
rc->connection, rc->connection,
&h_payto, &h_payto,
kyc_row_id, kyc_row_id,
@ -1032,8 +1041,7 @@ handle_mhd_request (void *cls,
.url = "kyc-proof", .url = "kyc-proof",
.method = MHD_HTTP_METHOD_GET, .method = MHD_HTTP_METHOD_GET,
.handler.get = &handler_kyc_proof_get, .handler.get = &handler_kyc_proof_get,
.nargs = 128, .nargs = 1
.nargs_is_upper_bound = true
}, },
{ {
.url = "kyc-webhook", .url = "kyc-webhook",

View File

@ -154,8 +154,7 @@ TALER_EXCHANGE_kyc_proof (struct TALER_EXCHANGE_Handle *exchange,
if (NULL == args) if (NULL == args)
args = ""; args = "";
else else
GNUNET_assert ( (args[0] == '?') || GNUNET_assert (args[0] == '&');
(args[0] == '/') );
if (GNUNET_YES != if (GNUNET_YES !=
TEAH_handle_is_ready (exchange)) TEAH_handle_is_ready (exchange))
{ {
@ -172,9 +171,9 @@ TALER_EXCHANGE_kyc_proof (struct TALER_EXCHANGE_Handle *exchange,
sizeof (hstr)); sizeof (hstr));
*end = '\0'; *end = '\0';
GNUNET_asprintf (&arg_str, GNUNET_asprintf (&arg_str,
"/kyc-proof/%s/%s%s", "/kyc-proof/%s?state=%s%s",
hstr,
logic, logic,
hstr,
args); args);
} }
kph = GNUNET_new (struct TALER_EXCHANGE_KycProofHandle); kph = GNUNET_new (struct TALER_EXCHANGE_KycProofHandle);

View File

@ -207,10 +207,10 @@ main (int argc,
with_libeufin = GNUNET_YES; with_libeufin = GNUNET_YES;
cfgfile = CONFIG_FILE_NEXUS; cfgfile = CONFIG_FILE_NEXUS;
if (GNUNET_OK != if (GNUNET_OK !=
TALER_TESTING_prepare_nexus (CONFIG_FILE_NEXUS, TALER_TESTING_prepare_libeufin (CONFIG_FILE_NEXUS,
GNUNET_YES, GNUNET_YES,
"exchange-account-2", "exchange-account-2",
&bc)) &bc))
{ {
GNUNET_break (0); GNUNET_break (0);
return 77; return 77;

View File

@ -131,7 +131,6 @@ run (void *cls,
"withdraw-coin-1-lacking-kyc", "withdraw-coin-1-lacking-kyc",
"kyc-provider-test-oauth2", "kyc-provider-test-oauth2",
"pass", "pass",
"state",
MHD_HTTP_SEE_OTHER), MHD_HTTP_SEE_OTHER),
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1-with-kyc", TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1-with-kyc",
"create-reserve-1", "create-reserve-1",
@ -175,7 +174,6 @@ run (void *cls,
"track-deposit-kyc-ready", "track-deposit-kyc-ready",
"kyc-provider-test-oauth2", "kyc-provider-test-oauth2",
"bad", "bad",
"state",
MHD_HTTP_BAD_GATEWAY), MHD_HTTP_BAD_GATEWAY),
TALER_TESTING_cmd_oauth ("start-oauth-service", TALER_TESTING_cmd_oauth ("start-oauth-service",
6666), 6666),
@ -183,13 +181,11 @@ run (void *cls,
"track-deposit-kyc-ready", "track-deposit-kyc-ready",
"kyc-provider-test-oauth2", "kyc-provider-test-oauth2",
"bad", "bad",
"state",
MHD_HTTP_FORBIDDEN), MHD_HTTP_FORBIDDEN),
TALER_TESTING_cmd_proof_kyc_oauth2 ("proof-kyc-fail", TALER_TESTING_cmd_proof_kyc_oauth2 ("proof-kyc-fail",
"track-deposit-kyc-ready", "track-deposit-kyc-ready",
"kyc-provider-test-oauth2", "kyc-provider-test-oauth2",
"pass", "pass",
"state",
MHD_HTTP_SEE_OTHER), MHD_HTTP_SEE_OTHER),
CMD_EXEC_AGGREGATOR ("run-aggregator-after-kyc"), CMD_EXEC_AGGREGATOR ("run-aggregator-after-kyc"),
TALER_TESTING_cmd_check_bank_transfer ( TALER_TESTING_cmd_check_bank_transfer (
@ -216,7 +212,6 @@ run (void *cls,
"wallet-kyc-fail", "wallet-kyc-fail",
"kyc-provider-test-oauth2", "kyc-provider-test-oauth2",
"pass", "pass",
"state",
MHD_HTTP_SEE_OTHER), MHD_HTTP_SEE_OTHER),
TALER_TESTING_cmd_check_kyc_get ("wallet-kyc-check", TALER_TESTING_cmd_check_kyc_get ("wallet-kyc-check",
"wallet-kyc-fail", "wallet-kyc-fail",
@ -311,7 +306,6 @@ run (void *cls,
"purse-merge-into-reserve", "purse-merge-into-reserve",
"kyc-provider-test-oauth2", "kyc-provider-test-oauth2",
"pass", "pass",
"state",
MHD_HTTP_SEE_OTHER), MHD_HTTP_SEE_OTHER),
TALER_TESTING_cmd_purse_merge ( TALER_TESTING_cmd_purse_merge (
"purse-merge-into-reserve", "purse-merge-into-reserve",
@ -353,7 +347,6 @@ run (void *cls,
"purse-create-with-reserve", "purse-create-with-reserve",
"kyc-provider-test-oauth2", "kyc-provider-test-oauth2",
"pass", "pass",
"state",
MHD_HTTP_SEE_OTHER), MHD_HTTP_SEE_OTHER),
TALER_TESTING_cmd_purse_create_with_reserve ( TALER_TESTING_cmd_purse_create_with_reserve (
"purse-create-with-reserve", "purse-create-with-reserve",

View File

@ -43,11 +43,6 @@ struct KycProofGetState
*/ */
const char *code; const char *code;
/**
* State to pass.
*/
const char *state;
/** /**
* Logic section name to pass to `/kyc-proof/` handler. * Logic section name to pass to `/kyc-proof/` handler.
*/ */
@ -158,10 +153,12 @@ proof_kyc_run (void *cls,
TALER_TESTING_interpreter_fail (kps->is); TALER_TESTING_interpreter_fail (kps->is);
return; return;
} }
GNUNET_asprintf (&uargs, if (NULL == kps->code)
"?code=%s&state=%s", uargs = NULL;
kps->code, else
kps->state); GNUNET_asprintf (&uargs,
"&code=%s",
kps->code);
kps->kph = TALER_EXCHANGE_kyc_proof (is->exchange, kps->kph = TALER_EXCHANGE_kyc_proof (is->exchange,
h_payto, h_payto,
kps->logic, kps->logic,
@ -235,14 +232,12 @@ TALER_TESTING_cmd_proof_kyc_oauth2 (
const char *payment_target_reference, const char *payment_target_reference,
const char *logic_section, const char *logic_section,
const char *code, const char *code,
const char *state,
unsigned int expected_response_code) unsigned int expected_response_code)
{ {
struct KycProofGetState *kps; struct KycProofGetState *kps;
kps = GNUNET_new (struct KycProofGetState); kps = GNUNET_new (struct KycProofGetState);
kps->code = code; kps->code = code;
kps->state = state;
kps->logic = logic_section; kps->logic = logic_section;
kps->payment_target_reference = payment_target_reference; kps->payment_target_reference = payment_target_reference;
kps->expected_response_code = expected_response_code; kps->expected_response_code = expected_response_code;

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2018-2021 Taler Systems SA Copyright (C) 2018-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify TALER is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as it under the terms of the GNU General Public License as
@ -92,11 +92,10 @@ TALER_TESTING_run_libeufin (const struct TALER_TESTING_BankConfiguration *bc)
struct TALER_TESTING_LibeufinServices ret = { 0 }; struct TALER_TESTING_LibeufinServices ret = { 0 };
unsigned int iter; unsigned int iter;
char *curl_check_cmd; char *curl_check_cmd;
const char *db_conn = "jdbc:sqlite:/tmp/libeufin-exchange-test.sqlite3";
setenv ( setenv (
"LIBEUFIN_NEXUS_DB_CONNECTION", "LIBEUFIN_NEXUS_DB_CONNECTION",
db_conn, "jdbc:sqlite:/tmp/libeufin-exchange-test-nexusdb.sqlite3",
1); // not overwriting any potentially existing DB. 1); // not overwriting any potentially existing DB.
nexus_proc = GNUNET_OS_start_process ( nexus_proc = GNUNET_OS_start_process (
@ -146,8 +145,8 @@ TALER_TESTING_run_libeufin (const struct TALER_TESTING_BankConfiguration *bc)
fprintf (stderr, "\n"); fprintf (stderr, "\n");
setenv ( setenv (
"LIBEUFIN_SANDBOX_DB_CONNECTION", "LIBEUFIN_SANDBOX_DB_CONNECTION",
db_conn, "jdbc:sqlite:/tmp/libeufin-exchange-test-sandboxdb.sqlite3",
1); // not overwriting existing any potentially existing DB. 1); // not overwriting any potentially existing DB.
setenv ( setenv (
"LIBEUFIN_SANDBOX_ADMIN_PASSWORD", "LIBEUFIN_SANDBOX_ADMIN_PASSWORD",
"secret", "secret",
@ -299,10 +298,10 @@ TALER_TESTING_run_bank (const char *config_filename,
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_TESTING_prepare_nexus (const char *config_filename, TALER_TESTING_prepare_libeufin (const char *config_filename,
int reset_db, bool reset_db,
const char *config_section, const char *config_section,
struct TALER_TESTING_BankConfiguration *bc) struct TALER_TESTING_BankConfiguration *bc)
{ {
struct GNUNET_CONFIGURATION_Handle *cfg; struct GNUNET_CONFIGURATION_Handle *cfg;
unsigned long long port; unsigned long long port;
@ -355,9 +354,9 @@ TALER_TESTING_prepare_nexus (const char *config_filename,
GNUNET_NETWORK_test_port_free (IPPROTO_TCP, GNUNET_NETWORK_test_port_free (IPPROTO_TCP,
(uint16_t) port)) (uint16_t) port))
{ {
fprintf (stderr, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Required port %llu not available, skipping.\n", "Required port %llu not available, skipping.\n",
port); port);
GNUNET_break (0); GNUNET_break (0);
GNUNET_free (database); GNUNET_free (database);
GNUNET_CONFIGURATION_destroy (cfg); GNUNET_CONFIGURATION_destroy (cfg);
@ -365,12 +364,20 @@ TALER_TESTING_prepare_nexus (const char *config_filename,
} }
/* DB preparation */ /* DB preparation */
if (GNUNET_YES == reset_db) if (reset_db)
{ {
if (0 != system ("rm -f /tmp/libeufin-exchange-test.sqlite3")) if (0 != system ("rm -f /tmp/libeufin-exchange-test-nexusdb.sqlite3"))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to invoke db-removal command.\n"); "Failed to invoke db-removal command on nexusdb.\n");
GNUNET_free (database);
GNUNET_CONFIGURATION_destroy (cfg);
return GNUNET_SYSERR;
}
if (0 != system ("rm -f /tmp/libeufin-exchange-test-sandboxdb.sqlite3"))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to invoke db-removal command on sandboxdb.\n");
GNUNET_free (database); GNUNET_free (database);
GNUNET_CONFIGURATION_destroy (cfg); GNUNET_CONFIGURATION_destroy (cfg);
return GNUNET_SYSERR; return GNUNET_SYSERR;
@ -407,11 +414,14 @@ TALER_TESTING_prepare_nexus (const char *config_filename,
"Relying on nexus %s on port %u\n", "Relying on nexus %s on port %u\n",
bc->exchange_auth.wire_gateway_url, bc->exchange_auth.wire_gateway_url,
(unsigned int) port); (unsigned int) port);
GNUNET_log (GNUNET_ERROR_TYPE_INFO, "exchange payto: %s\n", GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"exchange payto: %s\n",
bc->exchange_payto); bc->exchange_payto);
GNUNET_log (GNUNET_ERROR_TYPE_INFO, "user42_payto: %s\n", GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"user42_payto: %s\n",
bc->user42_payto); bc->user42_payto);
GNUNET_log (GNUNET_ERROR_TYPE_INFO, "user42_payto: %s\n", GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"user42_payto: %s\n",
bc->user43_payto); bc->user43_payto);
return GNUNET_OK; return GNUNET_OK;
} }
@ -419,7 +429,7 @@ TALER_TESTING_prepare_nexus (const char *config_filename,
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_TESTING_prepare_bank (const char *config_filename, TALER_TESTING_prepare_bank (const char *config_filename,
int reset_db, bool reset_db,
const char *config_section, const char *config_section,
struct TALER_TESTING_BankConfiguration *bc) struct TALER_TESTING_BankConfiguration *bc)
{ {
@ -491,9 +501,9 @@ TALER_TESTING_prepare_bank (const char *config_filename,
GNUNET_NETWORK_test_port_free (IPPROTO_TCP, GNUNET_NETWORK_test_port_free (IPPROTO_TCP,
(uint16_t) port)) (uint16_t) port))
{ {
fprintf (stderr, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Required port %llu not available, skipping.\n", "Required port %llu not available, skipping.\n",
port); port);
GNUNET_break (0); GNUNET_break (0);
GNUNET_free (database); GNUNET_free (database);
GNUNET_CONFIGURATION_destroy (cfg); GNUNET_CONFIGURATION_destroy (cfg);
@ -501,7 +511,7 @@ TALER_TESTING_prepare_bank (const char *config_filename,
} }
/* DB preparation */ /* DB preparation */
if (GNUNET_YES == reset_db) if (reset_db)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Flushing bank database\n"); "Flushing bank database\n");