-implement more of the KYC handlers
This commit is contained in:
parent
fa30a132a5
commit
778a402d07
@ -1 +1 @@
|
||||
Subproject commit ca56accac72b6ce050a38d36172390b14100a538
|
||||
Subproject commit 8c7d9be40ba627348da3e01b91b4f1d3cc78631f
|
@ -37,7 +37,7 @@
|
||||
* @param body JSON body to add to @e ctx
|
||||
* @return #GNUNET_OK on success #GNUNET_SYSERR on failure
|
||||
*/
|
||||
int
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_curl_easy_post (struct TALER_CURL_PostContext *ctx,
|
||||
CURL *eh,
|
||||
const json_t *body)
|
||||
|
@ -123,6 +123,7 @@ taler_exchange_httpd_LDADD = \
|
||||
-lgnunetutil \
|
||||
-lgnunetjson \
|
||||
-ljansson \
|
||||
-lcurl \
|
||||
-lz \
|
||||
$(XLIB)
|
||||
|
||||
|
@ -102,3 +102,7 @@ KYC_MODE = NONE
|
||||
|
||||
# KYC Client secret used to obtain access tokens.
|
||||
# KYC_OAUTH2_CLIENT_SECRET =
|
||||
|
||||
# Where to redirect clients after successful
|
||||
# authorization?
|
||||
# KYC_OAUTH_POST_URL = https://bank.com/
|
||||
|
@ -102,6 +102,11 @@ struct TALER_EXCHANGEDB_Plugin *TEH_plugin;
|
||||
*/
|
||||
char *TEH_currency;
|
||||
|
||||
/**
|
||||
* Our base URL.
|
||||
*/
|
||||
char *TEH_base_url;
|
||||
|
||||
/**
|
||||
* Default timeout in seconds for HTTP requests.
|
||||
*/
|
||||
@ -134,6 +139,17 @@ static unsigned long long req_count;
|
||||
*/
|
||||
static unsigned long long req_max;
|
||||
|
||||
/**
|
||||
* Context for all CURL operations (useful to the event loop)
|
||||
*/
|
||||
struct GNUNET_CURL_Context *TEH_curl_ctx;
|
||||
|
||||
/**
|
||||
* Context for integrating #exchange_curl_ctx with the
|
||||
* GNUnet event loop.
|
||||
*/
|
||||
static struct GNUNET_CURL_RescheduleContext *exchange_curl_rc;
|
||||
|
||||
|
||||
/**
|
||||
* Signature of functions that handle operations on coins.
|
||||
@ -1203,6 +1219,19 @@ parse_kyc_oauth_cfg (void)
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
TEH_kyc_config.details.oauth2.client_secret = s;
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_get_value_string (TEH_cfg,
|
||||
"exchange-kyc-oauth2",
|
||||
"KYC_OAUTH2_POST_URL",
|
||||
&s))
|
||||
{
|
||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||
"exchange-kyc-oauth2",
|
||||
"KYC_OAUTH2_POST_URL");
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
TEH_kyc_config.details.oauth2.post_kyc_redirect_url = s;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
@ -1301,6 +1330,26 @@ exchange_serve_process_config (void)
|
||||
"CURRENCY");
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_get_value_string (TEH_cfg,
|
||||
"exchange",
|
||||
"BASE_URL",
|
||||
&TEH_base_url))
|
||||
{
|
||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||
"exchange",
|
||||
"BASE_URL");
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (! TALER_url_valid_charset (TEH_base_url))
|
||||
{
|
||||
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
|
||||
"exchange",
|
||||
"BASE_URL",
|
||||
"invalid URL");
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
if (TEH_KYC_NONE != TEH_kyc_config.mode)
|
||||
{
|
||||
if (GNUNET_YES ==
|
||||
@ -1593,11 +1642,26 @@ do_shutdown (void *cls)
|
||||
mhd = TALER_MHD_daemon_stop ();
|
||||
TEH_resume_keys_requests (true);
|
||||
TEH_reserves_get_cleanup ();
|
||||
TEH_kyc_proof_cleanup ();
|
||||
if (NULL != mhd)
|
||||
MHD_stop_daemon (mhd);
|
||||
TEH_WIRE_done ();
|
||||
TEH_keys_finished ();
|
||||
TALER_EXCHANGEDB_plugin_unload (TEH_plugin);
|
||||
if (NULL != TEH_plugin)
|
||||
{
|
||||
TALER_EXCHANGEDB_plugin_unload (TEH_plugin);
|
||||
TEH_plugin = NULL;
|
||||
}
|
||||
if (NULL != TEH_curl_ctx)
|
||||
{
|
||||
GNUNET_CURL_fini (TEH_curl_ctx);
|
||||
TEH_curl_ctx = NULL;
|
||||
}
|
||||
if (NULL != exchange_curl_rc)
|
||||
{
|
||||
GNUNET_CURL_gnunet_rc_destroy (exchange_curl_rc);
|
||||
exchange_curl_rc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1655,6 +1719,17 @@ run (void *cls,
|
||||
}
|
||||
|
||||
TEH_load_terms (TEH_cfg);
|
||||
TEH_curl_ctx
|
||||
= GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
|
||||
&exchange_curl_rc);
|
||||
if (NULL == TEH_curl_ctx)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
global_ret = EXIT_FAILURE;
|
||||
GNUNET_SCHEDULER_shutdown ();
|
||||
return;
|
||||
}
|
||||
exchange_curl_rc = GNUNET_CURL_gnunet_rc_create (TEH_curl_ctx);
|
||||
GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
|
||||
NULL);
|
||||
fh = TALER_MHD_bind (TEH_cfg,
|
||||
|
@ -105,6 +105,12 @@ struct TEH_KycOptions
|
||||
*/
|
||||
char *client_secret;
|
||||
|
||||
/**
|
||||
* Where to redirect clients after the
|
||||
* Web-based KYC process is done?
|
||||
*/
|
||||
char *post_kyc_redirect_url;
|
||||
|
||||
} oauth2;
|
||||
|
||||
} details;
|
||||
@ -162,11 +168,20 @@ extern struct TALER_EXCHANGEDB_Plugin *TEH_plugin;
|
||||
*/
|
||||
extern char *TEH_currency;
|
||||
|
||||
/**
|
||||
* Our (externally visible) base URL.
|
||||
*/
|
||||
extern char *TEH_base_url;
|
||||
|
||||
/**
|
||||
* Are we shutting down?
|
||||
*/
|
||||
extern volatile bool MHD_terminating;
|
||||
|
||||
/**
|
||||
* Context for all CURL operations (useful to the event loop)
|
||||
*/
|
||||
extern struct GNUNET_CURL_Context *TEH_curl_ctx;
|
||||
|
||||
/**
|
||||
* @brief Struct describing an URL and the handler for it.
|
||||
|
@ -381,7 +381,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
|
||||
sizeof (deposit));
|
||||
deposit.coin.coin_pub = *coin_pub;
|
||||
{
|
||||
int res;
|
||||
enum GNUNET_GenericReturnValue res;
|
||||
|
||||
res = TALER_MHD_parse_json_data (connection,
|
||||
root,
|
||||
|
@ -1345,7 +1345,7 @@ get_date_string (struct GNUNET_TIME_Absolute at,
|
||||
* @param[in,out] response the response to modify
|
||||
* @return #GNUNET_OK on success
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
setup_general_response_headers (const struct TEH_KeyStateHandle *ksh,
|
||||
struct MHD_Response *response)
|
||||
{
|
||||
|
@ -143,12 +143,31 @@ TEH_handler_kyc_check (
|
||||
return res;
|
||||
if (! kcc.kyc.ok)
|
||||
{
|
||||
char *url;
|
||||
char *redirect_uri;
|
||||
char *redirect_uri_encoded;
|
||||
|
||||
GNUNET_assert (TEH_KYC_OAUTH2 == TEH_kyc_config.mode);
|
||||
return TALER_MHD_REPLY_JSON_PACK (
|
||||
GNUNET_asprintf (&redirect_uri,
|
||||
"%s/kyc-proof/%llu",
|
||||
TEH_base_url,
|
||||
payment_target_uuid);
|
||||
redirect_uri_encoded = TALER_urlencode (redirect_uri);
|
||||
GNUNET_free (redirect_uri);
|
||||
GNUNET_asprintf (&url,
|
||||
"%s/login?client_id=%s&redirect_uri=%s",
|
||||
TEH_kyc_config.details.oauth2.url,
|
||||
TEH_kyc_config.details.oauth2.client_id,
|
||||
redirect_uri_encoded);
|
||||
GNUNET_free (redirect_uri_encoded);
|
||||
|
||||
res = TALER_MHD_REPLY_JSON_PACK (
|
||||
rc->connection,
|
||||
MHD_HTTP_ACCEPTED,
|
||||
GNUNET_JSON_pack_string ("kyc_url",
|
||||
TEH_kyc_config.details.oauth2.url));
|
||||
url));
|
||||
GNUNET_free (url);
|
||||
return res;
|
||||
}
|
||||
{
|
||||
struct TALER_ExchangePublicKeyP pub;
|
||||
|
@ -36,9 +36,99 @@
|
||||
struct KycProofContext
|
||||
{
|
||||
|
||||
/**
|
||||
* Kept in a DLL while suspended.
|
||||
*/
|
||||
struct KycProofContext *next;
|
||||
|
||||
/**
|
||||
* Kept in a DLL while suspended.
|
||||
*/
|
||||
struct KycProofContext *prev;
|
||||
|
||||
/**
|
||||
* Details about the connection we are processing.
|
||||
*/
|
||||
struct TEH_RequestContext *rc;
|
||||
|
||||
/**
|
||||
* Handle for the OAuth 2.0 CURL request.
|
||||
*/
|
||||
struct GNUNET_CURL_Job *job;
|
||||
|
||||
/**
|
||||
* OAuth 2.0 authorization code.
|
||||
*/
|
||||
const char *authorization_code;
|
||||
|
||||
/**
|
||||
* OAuth 2.0 token URL we are using for the
|
||||
* request.
|
||||
*/
|
||||
char *token_url;
|
||||
|
||||
/**
|
||||
* Body of the POST request.
|
||||
*/
|
||||
char *post_body;
|
||||
|
||||
/**
|
||||
* Payment target this is about.
|
||||
*/
|
||||
unsigned long long payment_target_uuid;
|
||||
|
||||
/**
|
||||
* HTTP response to return.
|
||||
*/
|
||||
struct MHD_Response *response;
|
||||
|
||||
/**
|
||||
* HTTP response code to return.
|
||||
*/
|
||||
unsigned int response_code;
|
||||
|
||||
/**
|
||||
* #GNUNET_YES if we are suspended,
|
||||
* #GNUNET_NO if not.
|
||||
* #GNUNET_SYSERR if we had some error.
|
||||
*/
|
||||
enum GNUNET_GenericReturnValue suspended;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Contexts are kept in a DLL while suspended.
|
||||
*/
|
||||
static struct KycProofContext *kpc_head;
|
||||
|
||||
/**
|
||||
* Contexts are kept in a DLL while suspended.
|
||||
*/
|
||||
static struct KycProofContext *kpc_tail;
|
||||
|
||||
|
||||
void
|
||||
TEH_kyc_proof_cleanup (void)
|
||||
{
|
||||
struct KycProofContext *kpc;
|
||||
|
||||
while (NULL != (kpc = kpc_head))
|
||||
{
|
||||
if (NULL != kpc->job)
|
||||
{
|
||||
GNUNET_CURL_job_cancel (kpc->job);
|
||||
kpc->job = NULL;
|
||||
}
|
||||
GNUNET_CONTAINER_DLL_remove (kpc_head,
|
||||
kpc_tail,
|
||||
kpc);
|
||||
kpc->suspended = GNUNET_NO;
|
||||
MHD_resume_connection (kpc->rc->connection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function implementing database transaction to check proof's KYC status.
|
||||
* Runs the transaction logic; IF it returns a non-error code, the transaction
|
||||
@ -54,14 +144,185 @@ struct KycProofContext
|
||||
* @return transaction status
|
||||
*/
|
||||
static enum GNUNET_DB_QueryStatus
|
||||
proof_kyc_check (void *cls,
|
||||
struct MHD_Connection *connection,
|
||||
MHD_RESULT *mhd_ret)
|
||||
persist_kyc_ok (void *cls,
|
||||
struct MHD_Connection *connection,
|
||||
MHD_RESULT *mhd_ret)
|
||||
{
|
||||
struct KycProofContext *kpc = cls;
|
||||
|
||||
(void) kpc; // FIXME: do work here!
|
||||
return -2;
|
||||
return TEH_plugin->set_kyc_ok (TEH_plugin->cls,
|
||||
kpc->payment_target_uuid);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* After we are done with the CURL interaction we
|
||||
* need to update our database state.
|
||||
*
|
||||
* @param cls our `struct KycProofContext`
|
||||
* @param response_code HTTP response code from server, 0 on hard error
|
||||
* @param response in JSON, NULL if response was not in JSON format
|
||||
*/
|
||||
static void
|
||||
handle_curl_login_finished (void *cls,
|
||||
long response_code,
|
||||
const void *response)
|
||||
{
|
||||
struct KycProofContext *kpc = cls;
|
||||
const json_t *j = response;
|
||||
|
||||
kpc->job = NULL;
|
||||
switch (response_code)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
{
|
||||
const char *access_token;
|
||||
const char *token_type;
|
||||
uint64_t expires_in_s;
|
||||
const char *refresh_token;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_string ("access_token",
|
||||
&access_token),
|
||||
GNUNET_JSON_spec_string ("token_type",
|
||||
&token_type),
|
||||
GNUNET_JSON_spec_uint64 ("expires_in",
|
||||
&expires_in_s),
|
||||
GNUNET_JSON_spec_string ("refresh_token",
|
||||
&refresh_token),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
{
|
||||
enum GNUNET_GenericReturnValue res;
|
||||
const char *emsg;
|
||||
unsigned int line;
|
||||
|
||||
res = GNUNET_JSON_parse (j,
|
||||
spec,
|
||||
&emsg,
|
||||
&line);
|
||||
if (GNUNET_OK != res)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
kpc->response
|
||||
= TALER_MHD_make_error (
|
||||
TALER_EC_EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE,
|
||||
"Unexpected response from KYC gateway");
|
||||
kpc->response_code
|
||||
= MHD_HTTP_BAD_GATEWAY;
|
||||
MHD_resume_connection (kpc->rc->connection);
|
||||
TALER_MHD_daemon_trigger ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (0 != strcasecmp (token_type,
|
||||
"bearer"))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
kpc->response
|
||||
= TALER_MHD_make_error (
|
||||
TALER_EC_EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE,
|
||||
"Unexpected token type in response from KYC gateway");
|
||||
kpc->response_code
|
||||
= MHD_HTTP_BAD_GATEWAY;
|
||||
MHD_resume_connection (kpc->rc->connection);
|
||||
TALER_MHD_daemon_trigger ();
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: Here we might want to keep something to persist in the DB, and
|
||||
possibly use the access_token to download information we should
|
||||
persist; then continue! */
|
||||
|
||||
MHD_resume_connection (kpc->rc->connection);
|
||||
TALER_MHD_daemon_trigger ();
|
||||
return;
|
||||
}
|
||||
default:
|
||||
{
|
||||
const char *msg;
|
||||
const char *desc;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_string ("error",
|
||||
&msg),
|
||||
GNUNET_JSON_spec_string ("error_description",
|
||||
&desc),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
{
|
||||
enum GNUNET_GenericReturnValue res;
|
||||
const char *emsg;
|
||||
unsigned int line;
|
||||
|
||||
res = GNUNET_JSON_parse (j,
|
||||
spec,
|
||||
&emsg,
|
||||
&line);
|
||||
if (GNUNET_OK != res)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
kpc->response
|
||||
= TALER_MHD_make_error (
|
||||
TALER_EC_EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE,
|
||||
"Unexpected response from KYC gateway");
|
||||
kpc->response_code
|
||||
= MHD_HTTP_BAD_GATEWAY;
|
||||
MHD_resume_connection (kpc->rc->connection);
|
||||
TALER_MHD_daemon_trigger ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* case TALER_EC_EXCHANGE_KYC_PROOF_BACKEND_AUTHORZATION_FAILED,
|
||||
we MAY want to in the future look at the requested content type
|
||||
and possibly respond in JSON if indicated. */
|
||||
{
|
||||
char *reply;
|
||||
|
||||
GNUNET_asprintf (&reply,
|
||||
"<html><head><title>%s</title></head><body><h1>%s</h1><p>%s</p></body></html>",
|
||||
msg,
|
||||
msg,
|
||||
desc);
|
||||
kpc->response
|
||||
= MHD_create_response_from_buffer (strlen (reply),
|
||||
reply,
|
||||
MHD_RESPMEM_MUST_COPY);
|
||||
GNUNET_assert (NULL != kpc->response);
|
||||
GNUNET_free (reply);
|
||||
}
|
||||
kpc->response_code = MHD_HTTP_FORBIDDEN;
|
||||
MHD_resume_connection (kpc->rc->connection);
|
||||
TALER_MHD_daemon_trigger ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function called to clean up a context.
|
||||
*
|
||||
* @param rc request context
|
||||
*/
|
||||
static void
|
||||
clean_kpc (struct TEH_RequestContext *rc)
|
||||
{
|
||||
struct KycProofContext *kpc = rc->rh_ctx;
|
||||
|
||||
if (NULL != kpc->job)
|
||||
{
|
||||
GNUNET_CURL_job_cancel (kpc->job);
|
||||
kpc->job = NULL;
|
||||
}
|
||||
if (NULL != kpc->response)
|
||||
{
|
||||
MHD_destroy_response (kpc->response);
|
||||
kpc->response = NULL;
|
||||
}
|
||||
GNUNET_free (kpc->post_body);
|
||||
GNUNET_free (kpc->token_url);
|
||||
GNUNET_free (kpc);
|
||||
}
|
||||
|
||||
|
||||
@ -70,44 +331,188 @@ TEH_handler_kyc_proof (
|
||||
struct TEH_RequestContext *rc,
|
||||
const char *const args[])
|
||||
{
|
||||
struct KycProofContext kpc;
|
||||
MHD_RESULT res;
|
||||
enum GNUNET_GenericReturnValue ret;
|
||||
unsigned long long payment_target_uuid;
|
||||
char dummy;
|
||||
struct KycProofContext *kpc = rc->rh_ctx;
|
||||
|
||||
if (1 !=
|
||||
sscanf (args[0],
|
||||
"%llu%c",
|
||||
&payment_target_uuid,
|
||||
&dummy))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return TALER_MHD_reply_with_error (rc->connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"payment_target_uuid");
|
||||
if (NULL == kpc)
|
||||
{ /* first time */
|
||||
char dummy;
|
||||
|
||||
kpc = GNUNET_new (struct KycProofContext);
|
||||
kpc->rc = rc;
|
||||
rc->rh_ctx = kpc;
|
||||
rc->rh_cleaner = &clean_kpc;
|
||||
|
||||
if (1 !=
|
||||
sscanf (args[0],
|
||||
"%llu%c",
|
||||
&kpc->payment_target_uuid,
|
||||
&dummy))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return TALER_MHD_reply_with_error (rc->connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"payment_target_uuid");
|
||||
}
|
||||
kpc->authorization_code
|
||||
= MHD_lookup_connection_value (rc->connection,
|
||||
MHD_GET_ARGUMENT_KIND,
|
||||
"code");
|
||||
if (NULL == kpc->authorization_code)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return TALER_MHD_reply_with_error (rc->connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"code");
|
||||
}
|
||||
if (TEH_KYC_NONE == TEH_kyc_config.mode)
|
||||
return TALER_MHD_reply_static (
|
||||
rc->connection,
|
||||
MHD_HTTP_NO_CONTENT,
|
||||
NULL,
|
||||
NULL,
|
||||
0);
|
||||
|
||||
{
|
||||
CURL *eh;
|
||||
|
||||
eh = curl_easy_init ();
|
||||
if (NULL == eh)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TALER_MHD_reply_with_error (rc->connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_GENERIC_ALLOCATION_FAILURE,
|
||||
"curl_easy_init");
|
||||
}
|
||||
GNUNET_asprintf (&kpc->token_url,
|
||||
"%s/token",
|
||||
TEH_kyc_config.details.oauth2.url);
|
||||
GNUNET_assert (CURLE_OK ==
|
||||
curl_easy_setopt (eh,
|
||||
CURLOPT_URL,
|
||||
kpc->token_url));
|
||||
GNUNET_assert (CURLE_OK ==
|
||||
curl_easy_setopt (eh,
|
||||
CURLOPT_POST,
|
||||
1));
|
||||
{
|
||||
char *client_id;
|
||||
char *redirect_uri;
|
||||
char *client_secret;
|
||||
char *authorization_code;
|
||||
|
||||
client_id = curl_easy_escape (eh,
|
||||
TEH_kyc_config.details.oauth2.client_id,
|
||||
0);
|
||||
GNUNET_assert (NULL != client_id);
|
||||
{
|
||||
char *request_uri;
|
||||
|
||||
GNUNET_asprintf (&request_uri,
|
||||
"%s/login?client_id=%s",
|
||||
TEH_kyc_config.details.oauth2.url,
|
||||
TEH_kyc_config.details.oauth2.client_id);
|
||||
redirect_uri = curl_easy_escape (eh,
|
||||
request_uri,
|
||||
0);
|
||||
GNUNET_free (request_uri);
|
||||
}
|
||||
GNUNET_assert (NULL != redirect_uri);
|
||||
client_secret = curl_easy_escape (eh,
|
||||
TEH_kyc_config.details.oauth2.
|
||||
client_secret,
|
||||
0);
|
||||
GNUNET_assert (NULL != client_secret);
|
||||
authorization_code = curl_easy_escape (eh,
|
||||
kpc->authorization_code,
|
||||
0);
|
||||
GNUNET_assert (NULL != authorization_code);
|
||||
GNUNET_asprintf (&kpc->post_body,
|
||||
"client_id=%s&redirect_uri=%s&client_secret=%s&code=%s&grant_type=authorization_code",
|
||||
client_id,
|
||||
redirect_uri,
|
||||
client_secret,
|
||||
authorization_code);
|
||||
curl_free (authorization_code);
|
||||
curl_free (client_secret);
|
||||
curl_free (redirect_uri);
|
||||
curl_free (client_id);
|
||||
}
|
||||
GNUNET_assert (CURLE_OK ==
|
||||
curl_easy_setopt (eh,
|
||||
CURLOPT_POSTFIELDS,
|
||||
kpc->post_body));
|
||||
GNUNET_assert (CURLE_OK ==
|
||||
curl_easy_setopt (eh,
|
||||
CURLOPT_FOLLOWLOCATION,
|
||||
1L));
|
||||
/* limit MAXREDIRS to 5 as a simple security measure against
|
||||
a potential infinite loop caused by a malicious target */
|
||||
GNUNET_assert (CURLE_OK ==
|
||||
curl_easy_setopt (eh,
|
||||
CURLOPT_MAXREDIRS,
|
||||
5L));
|
||||
|
||||
kpc->job = GNUNET_CURL_job_add (TEH_curl_ctx,
|
||||
eh,
|
||||
&handle_curl_login_finished,
|
||||
kpc);
|
||||
kpc->suspended = GNUNET_YES;
|
||||
GNUNET_CONTAINER_DLL_insert (kpc_head,
|
||||
kpc_tail,
|
||||
kpc);
|
||||
MHD_suspend_connection (rc->connection);
|
||||
return MHD_YES;
|
||||
}
|
||||
}
|
||||
|
||||
if (1 || (TEH_KYC_NONE == TEH_kyc_config.mode))
|
||||
return TALER_MHD_reply_static (
|
||||
rc->connection,
|
||||
MHD_HTTP_NO_CONTENT,
|
||||
NULL,
|
||||
NULL,
|
||||
0);
|
||||
ret = TEH_DB_run_transaction (rc->connection,
|
||||
"check proof kyc",
|
||||
&res,
|
||||
&proof_kyc_check,
|
||||
&kpc);
|
||||
if (GNUNET_SYSERR == ret)
|
||||
if (NULL != kpc->response)
|
||||
{
|
||||
/* handle _failed_ resumed cases */
|
||||
return MHD_queue_response (rc->connection,
|
||||
kpc->response_code,
|
||||
kpc->response);
|
||||
}
|
||||
|
||||
/* _successfully_ resumed case */
|
||||
{
|
||||
MHD_RESULT res;
|
||||
enum GNUNET_GenericReturnValue ret;
|
||||
|
||||
ret = TEH_DB_run_transaction (kpc->rc->connection,
|
||||
"check proof kyc",
|
||||
&res,
|
||||
&persist_kyc_ok,
|
||||
kpc);
|
||||
if (GNUNET_SYSERR == ret)
|
||||
return res;
|
||||
}
|
||||
|
||||
{
|
||||
struct MHD_Response *response;
|
||||
MHD_RESULT res;
|
||||
|
||||
response = MHD_create_response_from_buffer (0,
|
||||
"",
|
||||
MHD_RESPMEM_PERSISTENT);
|
||||
if (NULL == response)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return MHD_NO;
|
||||
}
|
||||
GNUNET_break (MHD_YES ==
|
||||
MHD_add_response_header (
|
||||
response,
|
||||
MHD_HTTP_HEADER_LOCATION,
|
||||
TEH_kyc_config.details.oauth2.post_kyc_redirect_url));
|
||||
res = MHD_queue_response (rc->connection,
|
||||
MHD_HTTP_SEE_OTHER,
|
||||
response);
|
||||
MHD_destroy_response (response);
|
||||
return res;
|
||||
return TALER_MHD_REPLY_JSON_PACK (
|
||||
rc->connection,
|
||||
MHD_HTTP_OK,
|
||||
GNUNET_JSON_pack_uint64 ("42",
|
||||
42));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,6 +25,14 @@
|
||||
#include "taler-exchange-httpd.h"
|
||||
|
||||
|
||||
/**
|
||||
* Shutdown kyc-proof subsystem. Resumes all suspended long-polling clients
|
||||
* and cleans up data structures.
|
||||
*/
|
||||
void
|
||||
TEH_kyc_proof_cleanup (void);
|
||||
|
||||
|
||||
/**
|
||||
* Handle a "/kyc-proof" request.
|
||||
*
|
||||
|
@ -360,6 +360,12 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" LIMIT 1;",
|
||||
1),
|
||||
#if FIXME_DD23
|
||||
/* Used in #postgres_set_kyc_ok() */
|
||||
GNUNET_PQ_make_prepare ("set_kyc_ok",
|
||||
"UPDATE wire_targets"
|
||||
" SET kyc_ok=TRUE"
|
||||
" WHERE wire_target_serial_id=$1",
|
||||
1),
|
||||
/* Used in #postgres_get_kyc_status() */
|
||||
GNUNET_PQ_make_prepare ("get_kyc_status",
|
||||
"SELECT"
|
||||
@ -3555,6 +3561,31 @@ postgres_reserves_get (void *cls,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the KYC status to "OK" for a bank account.
|
||||
*
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param payment_target_uuid which account has been checked
|
||||
* @param ... possibly additional data to persist (TODO)
|
||||
* @return transaction status
|
||||
*/
|
||||
static enum GNUNET_DB_QueryStatus
|
||||
postgres_set_kyc_ok (void *cls,
|
||||
uint64_t payment_target_uuid,
|
||||
...)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_uint64 (&payment_target_uuid),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
|
||||
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
|
||||
"set_kyc_ok",
|
||||
params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the KYC status for a bank account.
|
||||
*
|
||||
@ -11261,6 +11292,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
|
||||
plugin->iterate_auditor_denominations =
|
||||
&postgres_iterate_auditor_denominations;
|
||||
plugin->reserves_get = &postgres_reserves_get;
|
||||
plugin->set_kyc_ok = &postgres_set_kyc_ok;
|
||||
plugin->get_kyc_status = &postgres_get_kyc_status;
|
||||
plugin->select_kyc_status = &postgres_select_kyc_status;
|
||||
plugin->inselect_wallet_kyc_status = &postgres_inselect_wallet_kyc_status;
|
||||
|
@ -59,7 +59,7 @@ struct TALER_CURL_PostContext
|
||||
* @param body JSON body to add to @e ctx
|
||||
* @return #GNUNET_OK on success #GNUNET_SYSERR on failure
|
||||
*/
|
||||
int
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_curl_easy_post (struct TALER_CURL_PostContext *ctx,
|
||||
CURL *eh,
|
||||
const json_t *body);
|
||||
|
@ -2360,6 +2360,20 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
struct TALER_EXCHANGEDB_KycStatus *kyc);
|
||||
|
||||
|
||||
/**
|
||||
* Set the KYC status to "OK" for a bank account.
|
||||
*
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param payment_target_uuid which account has been checked
|
||||
* @param ... possibly additional data to persist (TODO)
|
||||
* @return transaction status
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
(*set_kyc_ok)(void *cls,
|
||||
uint64_t payment_target_uuid,
|
||||
...);
|
||||
|
||||
|
||||
/**
|
||||
* Get the KYC status for a bank account.
|
||||
*
|
||||
|
@ -82,7 +82,7 @@ struct TALER_EXCHANGE_LinkHandle
|
||||
* @param[out] pub where to return the public key for the coin
|
||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
||||
const json_t *json,
|
||||
uint32_t coin_num,
|
||||
@ -175,7 +175,7 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
||||
* @param json json reply with the data for one coin
|
||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
parse_link_ok (struct TALER_EXCHANGE_LinkHandle *lh,
|
||||
const json_t *json)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user