work on kycaid plugin response generation logic

This commit is contained in:
Christian Grothoff 2022-08-16 21:04:51 +02:00
parent af97071ad6
commit c62792638b
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
19 changed files with 499 additions and 183 deletions

View File

@ -3,7 +3,15 @@ SUBDIRS = .
tmplpkgdatadir = $(prefix)/share/taler/exchange/templates/
dist_tmplpkgdata_DATA = \
test.en.must
bad_gateway.en.must \
kyc_provider_unauthorized.en.must \
kyc_provider_unexpected_reply.en.must \
kyc_interaction_failed.en.must \
kyc_provider_unpaid.en.must \
kyc_provider_internal_error.en.must \
kyc_user_failed.en.must \
kyc_provider_ratelimit.en.must \
kyc_provider_timeout.en.must
# %%.must: merchant-backoffice/%.html
# WTF: cp $< $@

View File

@ -0,0 +1,12 @@
<html>
<head>
<title>KYC server failure</title>
</head>
<body>
The KYC backend returned a malformed response, reproduced
below. Please inform the exchange operator about this failure.
<pre>
{{ kyc_server_reply }}
</pre>
</body>
</html>

View File

@ -0,0 +1,20 @@
<html>
<head>
<title>KYC authentication failed</title>
</head>
<body>
You failed the KYC check. See below for details.
<!-- {{kyc_logic}} indicates the type of KYC provider
which generated the reply; for now, only
"kycaid" is possible. Switch on the
{{kyc_logic}} to render results in a provider-specific
way. (or introduce new templates per provider?) -->
<!-- TODO: figure out exactly what the
format of 'verifications' is here
based on KYCAID documentation and parse
that here. -->
<pre>
{{ verifications }}
</pre>
</body>
</html>

View File

@ -0,0 +1,13 @@
<html>
<head>
<title>KYC server interaction failed</title>
</head>
<body>
The KYC backend returned a response indicating a problem with the exchange logic. Please inform the exchange operator about this failure.
<pre>
{{ kyc_http_status }}
{{ kyc_logic }}
{{ kyc_server_reply }}
</pre>
</body>
</html>

View File

@ -0,0 +1,13 @@
<html>
<head>
<title>KYC provider had an internal error</title>
</head>
<body>
The KYC backend had an internal error.
<pre>
{{ kyc_http_status }}
{{ kyc_logic }}
{{ kyc_server_reply }}
</pre>
</body>
</html>

View File

@ -0,0 +1,13 @@
<html>
<head>
<title>KYC provider rate limit reached</title>
</head>
<body>
The KYC backend interaction ran into a rate limit.
<pre>
{{ kyc_http_status }}
{{ kyc_logic }}
{{ kyc_server_reply }}
</pre>
</body>
</html>

View File

@ -0,0 +1,13 @@
<html>
<head>
<title>KYC provider timeout</title>
</head>
<body>
The KYC backend interaction ran into a timeout.
<pre>
{{ kyc_http_status }}
{{ kyc_logic }}
{{ kyc_server_reply }}
</pre>
</body>
</html>

View File

@ -0,0 +1,13 @@
<html>
<head>
<title>KYC server refused access</title>
</head>
<body>
The KYC backend refused the authorization code used by the exchange operator. Please inform the exchange operator about this failure.
<pre>
{{ kyc_http_status }}
{{ kyc_logic }}
{{ kyc_server_reply }}
</pre>
</body>
</html>

View File

@ -0,0 +1,13 @@
<html>
<head>
<title>KYC provider returned unexpected status code</title>
</head>
<body>
The KYC backend returned an unexpected status code.
<pre>
{{ kyc_http_status }}
{{ kyc_logic }}
{{ kyc_server_reply }}
</pre>
</body>
</html>

View File

@ -0,0 +1,13 @@
<html>
<head>
<title>KYC credit exhausted</title>
</head>
<body>
The KYC backend refused the process as the exchange operator's credit balance at the KYC provider is insufficient. Please inform the exchange operator about this failure.
<pre>
{{ kyc_http_status }}
{{ kyc_logic }}
{{ kyc_server_reply }}
</pre>
</body>
</html>

View File

@ -0,0 +1,20 @@
<html>
<head>
<title>KYC authentication failed</title>
</head>
<body>
You failed the KYC check. See below for details.
<!-- {{logic}} indicates the type of KYC provider
which generated the reply; for now, only
"kycaid" is possible. Switch on the
{{logic}} to render results in a provider-specific
way. (or introduce new templates per provider?) -->
<!-- TODO: figure out exactly what the
format of 'verifications' is here
based on KYCAID documentation and parse
that here. -->
<pre>
{{ verifications }}
</pre>
</body>
</html>

View File

View File

@ -24,6 +24,34 @@
#include <microhttpd.h>
/**
* Load a @a template and substitute using @a root, returning the result in a
* @a reply encoded suitable for the @a connection with the given @a
* http_status code. On errors, the @a http_status code
* is updated to reflect the type of error encoded in the
* @a reply.
*
* @param connection the connection we act upon
* @param[in,out] http_status code to use on success,
* set to alternative code on failure
* @param template basename of the template to load
* @param instance_id instance ID, used to compute static files URL
* @param taler_uri value for "Taler:" header to set, or NULL
* @param root JSON object to pass as the root context
* @param[out] reply where to write the response object
* @return #GNUNET_OK on success (reply queued), #GNUNET_NO if an error was queued,
* #GNUNET_SYSERR on failure (to queue an error)
*/
enum GNUNET_GenericReturnValue
TALER_TEMPLATING_build (struct MHD_Connection *connection,
unsigned int *http_status,
const char *template,
const char *instance_id,
const char *taler_uri,
json_t *root,
struct MHD_Response **reply);
/**
* Load a @a template and substitute using @a root, returning
* the result to the @a connection with the given

View File

@ -39,6 +39,7 @@ taler_exchange_kyc_tester_LDADD = \
libtalerkyclogic.la \
$(top_builddir)/src/mhd/libtalermhd.la \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/templating/libtalertemplating.la \
$(top_builddir)/src/util/libtalerutil.la \
-lmicrohttpd \
-lgnunetcurl \
@ -83,6 +84,7 @@ libtaler_plugin_kyclogic_kycaid_la_LDFLAGS = \
$(TALER_PLUGIN_LDFLAGS) \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/curl/libtalercurl.la \
$(top_builddir)/src/templating/libtalertemplating.la \
$(top_builddir)/src/util/libtalerutil.la \
-lgnunetutil \
-ljansson \

View File

@ -20,9 +20,10 @@
*/
#include "platform.h"
#include "taler_kyclogic_plugin.h"
#include <taler/taler_mhd_lib.h>
#include <taler/taler_curl_lib.h>
#include <taler/taler_json_lib.h>
#include "taler_mhd_lib.h"
#include "taler_curl_lib.h"
#include "taler_json_lib.h"
#include "taler_templating_lib.h"
#include <regex.h>
#include "taler_util.h"
@ -640,6 +641,43 @@ kycaid_proof_cancel (struct TALER_KYCLOGIC_ProofHandle *ph)
}
/**
* Call @a ph callback with HTTP response generated
* from @a template_name using the given @a template_data.
*
* @param http_status http response status to use
* @param template_name template to load and return
* @param[in] template_data data for the template, freed by this function!
*/
static void
proof_reply_with_template (struct TALER_KYCLOGIC_ProofHandle *ph,
unsigned int http_status,
const char *template_name,
json_t *template_data)
{
enum GNUNET_GenericReturnValue ret;
struct MHD_Response *resp;
ret = TALER_TEMPLATING_build (ph->connection,
&http_status,
template_name,
NULL, /* no instance */
NULL, /* no Taler URI */
template_data,
&resp);
json_decref (template_data);
if (GNUNET_SYSERR == ret)
http_status = 0;
ph->cb (ph->cb_cls,
TALER_KYCLOGIC_STATUS_PROVIDER_FAILED,
NULL, /* user id */
NULL, /* provider legi ID */
GNUNET_TIME_UNIT_ZERO_ABS, /* expiration */
http_status,
resp);
}
/**
* Function called when we're done processing the
* HTTP "/verifications/{verification_id}" request.
@ -684,18 +722,19 @@ handle_proof_finished (void *cls,
spec,
NULL, NULL))
{
json_t *template_data;
GNUNET_break_op (0);
json_dumpf (j,
stderr,
JSON_INDENT (2));
resp = NULL; // FIXME: generate response!
ph->cb (ph->cb_cls,
TALER_KYCLOGIC_STATUS_PROVIDER_FAILED,
NULL, /* user id */
NULL, /* provider legi ID */
GNUNET_TIME_UNIT_ZERO_ABS, /* expiration */
template_data = GNUNET_JSON_PACK (
GNUNET_JSON_pack_object_incref ("kyc_server_reply",
(json_t *) j));
proof_reply_with_template (ph,
MHD_HTTP_BAD_GATEWAY,
resp);
"bad_gateway",
template_data);
break;
}
/* FIXME: comment out, unless debugging ... */
@ -706,26 +745,35 @@ handle_proof_finished (void *cls,
JSON_INDENT (2));
if (verified)
{
resp = NULL; // FIXME: generate response!
// FIXME: or should we return an empty body? Redirect?
resp = TALER_MHD_make_json_steal (json_object ());
// FIXME: setup redirect?
expiration = GNUNET_TIME_relative_to_absolute (ph->pd->validity);
ph->cb (ph->cb_cls,
TALER_KYCLOGIC_STATUS_SUCCESS,
applicant_id,
verification_id,
expiration,
MHD_HTTP_OK,
MHD_HTTP_OK, // OK, or redirect???
resp);
}
else
{
resp = NULL; // FIXME: generate response!
ph->cb (ph->cb_cls,
TALER_KYCLOGIC_STATUS_USER_ABORTED,
applicant_id,
verification_id,
GNUNET_TIME_UNIT_ZERO_ABS,
json_t *template_data;
GNUNET_break_op (0);
json_dumpf (j,
stderr,
JSON_INDENT (2));
template_data = GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("kyc_logic",
"kycaid"),
GNUNET_JSON_pack_object_incref ("verifiations",
(json_t *) verifications));
proof_reply_with_template (ph,
MHD_HTTP_OK,
resp);
"kyc_user_failed",
template_data);
}
GNUNET_JSON_parse_free (spec);
}
@ -733,98 +781,132 @@ handle_proof_finished (void *cls,
case MHD_HTTP_BAD_REQUEST:
case MHD_HTTP_NOT_FOUND:
case MHD_HTTP_CONFLICT:
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"KYCAID failed with response %u:\n",
(unsigned int) response_code);
json_dumpf (j,
stderr,
JSON_INDENT (2));
resp = NULL; // FIXME: generate response!
ph->cb (ph->cb_cls,
TALER_KYCLOGIC_STATUS_PROVIDER_FAILED,
NULL, /* user id */
NULL, /* provider legi ID */
GNUNET_TIME_UNIT_ZERO_ABS, /* expiration */
MHD_HTTP_INTERNAL_SERVER_ERROR,
resp);
break;
case MHD_HTTP_UNAUTHORIZED:
case MHD_HTTP_PAYMENT_REQUIRED:
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Refused access with HTTP status code %u\n",
(unsigned int) response_code);
resp = NULL; // FIXME: generate response!
ph->cb (ph->cb_cls,
TALER_KYCLOGIC_STATUS_PROVIDER_FAILED,
NULL, /* user id */
NULL, /* provider legi ID */
GNUNET_TIME_UNIT_ZERO_ABS, /* expiration */
MHD_HTTP_NETWORK_AUTHENTICATION_REQUIRED,
resp);
break;
case MHD_HTTP_REQUEST_TIMEOUT:
resp = NULL; // FIXME: generate response!
ph->cb (ph->cb_cls,
TALER_KYCLOGIC_STATUS_PROVIDER_FAILED,
NULL, /* user id */
NULL, /* provider legi ID */
GNUNET_TIME_UNIT_ZERO_ABS, /* expiration */
MHD_HTTP_GATEWAY_TIMEOUT,
resp);
break;
case MHD_HTTP_UNPROCESSABLE_ENTITY: /* validation */
{
json_t *template_data;
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"KYCAID failed with response %u:\n",
(unsigned int) response_code);
json_dumpf (j,
stderr,
JSON_INDENT (2));
resp = NULL; // FIXME: generate response!
ph->cb (ph->cb_cls,
TALER_KYCLOGIC_STATUS_PROVIDER_FAILED,
NULL, /* user id */
NULL, /* provider legi ID */
GNUNET_TIME_UNIT_ZERO_ABS, /* expiration */
MHD_HTTP_BAD_GATEWAY,
resp);
template_data = GNUNET_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kyc_http_status",
response_code),
GNUNET_JSON_pack_string ("kyc_logic",
"kycaid"),
GNUNET_JSON_pack_object_incref ("kyc_server_reply",
(json_t *) j));
proof_reply_with_template (ph,
MHD_HTTP_INTERNAL_SERVER_ERROR,
"kyc_interaction_failed",
template_data);
break;
}
case MHD_HTTP_UNAUTHORIZED:
{
json_t *template_data;
template_data = GNUNET_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kyc_http_status",
response_code),
GNUNET_JSON_pack_string ("kyc_logic",
"kycaid"),
GNUNET_JSON_pack_object_incref ("kyc_server_reply",
(json_t *) j));
proof_reply_with_template (ph,
MHD_HTTP_INTERNAL_SERVER_ERROR,
"kyc_provider_unauthorized",
template_data);
break;
}
case MHD_HTTP_PAYMENT_REQUIRED:
{
json_t *template_data;
template_data = GNUNET_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kyc_http_status",
response_code),
GNUNET_JSON_pack_string ("kyc_logic",
"kycaid"),
GNUNET_JSON_pack_object_incref ("kyc_server_reply",
(json_t *) j));
proof_reply_with_template (ph,
MHD_HTTP_INTERNAL_SERVER_ERROR,
"kyc_provider_unpaid",
template_data);
break;
}
case MHD_HTTP_REQUEST_TIMEOUT:
{
json_t *template_data;
template_data = GNUNET_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kyc_http_status",
response_code),
GNUNET_JSON_pack_string ("kyc_logic",
"kycaid"),
GNUNET_JSON_pack_object_incref ("kyc_server_reply",
(json_t *) j));
proof_reply_with_template (ph,
MHD_HTTP_INTERNAL_SERVER_ERROR,
"kyc_provider_timeout",
template_data);
break;
}
case MHD_HTTP_TOO_MANY_REQUESTS:
resp = NULL; // FIXME: generate response!
ph->cb (ph->cb_cls,
TALER_KYCLOGIC_STATUS_PROVIDER_FAILED,
NULL, /* user id */
NULL, /* provider legi ID */
GNUNET_TIME_UNIT_ZERO_ABS, /* expiration */
MHD_HTTP_SERVICE_UNAVAILABLE,
resp);
{
json_t *template_data;
template_data = GNUNET_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kyc_http_status",
response_code),
GNUNET_JSON_pack_string ("kyc_logic",
"kycaid"),
GNUNET_JSON_pack_object_incref ("kyc_server_reply",
(json_t *) j));
proof_reply_with_template (ph,
MHD_HTTP_INTERNAL_SERVER_ERROR,
"kyc_provider_ratelimit",
template_data);
break;
}
case MHD_HTTP_INTERNAL_SERVER_ERROR:
resp = NULL; // FIXME: generate response!
ph->cb (ph->cb_cls,
TALER_KYCLOGIC_STATUS_PROVIDER_FAILED,
NULL, /* user id */
NULL, /* provider legi ID */
GNUNET_TIME_UNIT_ZERO_ABS, /* expiration */
MHD_HTTP_BAD_GATEWAY,
resp);
{
json_t *template_data;
template_data = GNUNET_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kyc_http_status",
response_code),
GNUNET_JSON_pack_string ("kyc_logic",
"kycaid"),
GNUNET_JSON_pack_object_incref ("kyc_server_reply",
(json_t *) j));
proof_reply_with_template (ph,
MHD_HTTP_INTERNAL_SERVER_ERROR,
"kyc_provider_internal_error",
template_data);
break;
}
default:
resp = NULL; // FIXME: generate response!
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected KYCAID response %u:\n",
(unsigned int) response_code);
json_dumpf (j,
stderr,
JSON_INDENT (2));
ph->cb (ph->cb_cls,
TALER_KYCLOGIC_STATUS_PROVIDER_FAILED,
NULL, /* user id */
NULL, /* provider legi ID */
GNUNET_TIME_UNIT_ZERO_ABS, /* expiration */
MHD_HTTP_BAD_GATEWAY,
resp);
{
json_t *template_data;
template_data = GNUNET_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kyc_http_status",
response_code),
GNUNET_JSON_pack_string ("kyc_logic",
"kycaid"),
GNUNET_JSON_pack_object_incref ("kyc_server_reply",
(json_t *) j));
proof_reply_with_template (ph,
MHD_HTTP_INTERNAL_SERVER_ERROR,
"kyc_provider_unexpected_reply",
template_data);
break;
}
}
kycaid_proof_cancel (ph);
}
@ -970,7 +1052,11 @@ handle_webhook_finished (void *cls,
json_dumpf (j,
stderr,
JSON_INDENT (2));
resp = NULL; // FIXME: generate response!
resp = TALER_MHD_MAKE_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kycaid_http_status",
response_code),
GNUNET_JSON_pack_object_incref ("kycaid_body",
(json_t *) j));
wh->cb (wh->cb_cls,
wh->legi_row,
&wh->h_payto,
@ -990,7 +1076,7 @@ handle_webhook_finished (void *cls,
JSON_INDENT (2));
if (verified)
{
resp = NULL; // FIXME: generate response!
resp = TALER_MHD_make_json_steal (json_object ());
expiration = GNUNET_TIME_relative_to_absolute (wh->pd->validity);
wh->cb (wh->cb_cls,
wh->legi_row,
@ -1004,7 +1090,7 @@ handle_webhook_finished (void *cls,
}
else
{
resp = NULL; // FIXME: generate response!
resp = TALER_MHD_make_json_steal (json_object ());
wh->cb (wh->cb_cls,
wh->legi_row,
&wh->h_payto,
@ -1027,7 +1113,9 @@ handle_webhook_finished (void *cls,
json_dumpf (j,
stderr,
JSON_INDENT (2));
resp = NULL; // FIXME: generate response!
resp = TALER_MHD_MAKE_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kycaid_http_status",
response_code));
wh->cb (wh->cb_cls,
wh->legi_row,
&wh->h_payto,
@ -1043,7 +1131,11 @@ handle_webhook_finished (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Refused access with HTTP status code %u\n",
(unsigned int) response_code);
resp = NULL; // FIXME: generate response!
resp = TALER_MHD_MAKE_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kycaid_http_status",
response_code),
GNUNET_JSON_pack_object_incref ("kycaid_body",
(json_t *) j));
wh->cb (wh->cb_cls,
wh->legi_row,
&wh->h_payto,
@ -1055,7 +1147,11 @@ handle_webhook_finished (void *cls,
resp);
break;
case MHD_HTTP_REQUEST_TIMEOUT:
resp = NULL; // FIXME: generate response!
resp = TALER_MHD_MAKE_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kycaid_http_status",
response_code),
GNUNET_JSON_pack_object_incref ("kycaid_body",
(json_t *) j));
wh->cb (wh->cb_cls,
wh->legi_row,
&wh->h_payto,
@ -1073,7 +1169,11 @@ handle_webhook_finished (void *cls,
json_dumpf (j,
stderr,
JSON_INDENT (2));
resp = NULL; // FIXME: generate response!
resp = TALER_MHD_MAKE_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kycaid_http_status",
response_code),
GNUNET_JSON_pack_object_incref ("kycaid_body",
(json_t *) j));
wh->cb (wh->cb_cls,
wh->legi_row,
&wh->h_payto,
@ -1085,7 +1185,11 @@ handle_webhook_finished (void *cls,
resp);
break;
case MHD_HTTP_TOO_MANY_REQUESTS:
resp = NULL; // FIXME: generate response!
resp = TALER_MHD_MAKE_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kycaid_http_status",
response_code),
GNUNET_JSON_pack_object_incref ("kycaid_body",
(json_t *) j));
wh->cb (wh->cb_cls,
wh->legi_row,
&wh->h_payto,
@ -1097,7 +1201,11 @@ handle_webhook_finished (void *cls,
resp);
break;
case MHD_HTTP_INTERNAL_SERVER_ERROR:
resp = NULL; // FIXME: generate response!
resp = TALER_MHD_MAKE_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kycaid_http_status",
response_code),
GNUNET_JSON_pack_object_incref ("kycaid_body",
(json_t *) j));
wh->cb (wh->cb_cls,
wh->legi_row,
&wh->h_payto,
@ -1109,7 +1217,11 @@ handle_webhook_finished (void *cls,
resp);
break;
default:
resp = NULL; // FIXME: generate response!
resp = TALER_MHD_MAKE_JSON_PACK (
GNUNET_JSON_pack_uint64 ("kycaid_http_status",
response_code),
GNUNET_JSON_pack_object_incref ("kycaid_body",
(json_t *) j));
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected KYCAID response %u:\n",
(unsigned int) response_code);
@ -1226,7 +1338,9 @@ kycaid_webhook (void *cls,
json_dumpf (body,
stderr,
JSON_INDENT (2));
wh->resp = NULL; // FIXME: generate response!
wh->resp = TALER_MHD_MAKE_JSON_PACK (
GNUNET_JSON_pack_object_incref ("webhook_body",
(json_t *) body));
wh->response_code = MHD_HTTP_BAD_REQUEST;
wh->task = GNUNET_SCHEDULER_add_now (&async_webhook_reply,
wh);
@ -1239,7 +1353,8 @@ kycaid_webhook (void *cls,
&wh->legi_row);
if (qs < 0)
{
wh->resp = NULL; // FIXME: generate response!
wh->resp = TALER_MHD_make_error (TALER_EC_GENERIC_DB_FETCH_FAILED,
"provider-legitimization-lookup");
wh->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
wh->task = GNUNET_SCHEDULER_add_now (&async_webhook_reply,
wh);
@ -1250,7 +1365,9 @@ kycaid_webhook (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Received webhook for unknown verification ID `%s'\n",
verification_id);
wh->resp = NULL; // FIXME: generate response!
wh->resp = TALER_MHD_make_error (
TALER_EC_EXCHANGE_KYC_PROOF_REQUEST_UNKNOWN,
verification_id);
wh->response_code = MHD_HTTP_NOT_FOUND;
wh->task = GNUNET_SCHEDULER_add_now (&async_webhook_reply,
wh);
@ -1263,8 +1380,10 @@ kycaid_webhook (void *cls,
if (NULL == eh)
{
GNUNET_break (0);
wh->resp = NULL; // FIXME: generate response!
wh->response_code = MHD_HTTP_BAD_REQUEST;
wh->resp = TALER_MHD_make_error (
TALER_EC_GENERIC_ALLOCATION_FAILURE,
verification_id);
wh->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
wh->task = GNUNET_SCHEDULER_add_now (&async_webhook_reply,
wh);
return wh;

View File

@ -20,8 +20,8 @@
*/
#include "platform.h"
#include "taler_kyclogic_plugin.h"
#include <taler/taler_mhd_lib.h>
#include <taler/taler_json_lib.h>
#include "taler_mhd_lib.h"
#include "taler_json_lib.h"
#include <regex.h>
#include "taler_util.h"

View File

@ -20,8 +20,8 @@
*/
#include "platform.h"
#include "taler_kyclogic_plugin.h"
#include <taler/taler_mhd_lib.h>
#include <taler/taler_json_lib.h>
#include "taler_mhd_lib.h"
#include "taler_json_lib.h"
#include <regex.h>
#include "taler_util.h"

View File

@ -27,6 +27,7 @@
#include <limits.h>
#include "taler_mhd_lib.h"
#include "taler_json_lib.h"
#include "taler_templating_lib.h"
#include "taler_crypto_lib.h"
#include "taler_kyclogic_lib.h"
#include "taler_kyclogic_plugin.h"
@ -1239,6 +1240,7 @@ do_shutdown (void *cls)
GNUNET_CURL_gnunet_rc_destroy (exchange_curl_rc);
exchange_curl_rc = NULL;
}
TALER_TEMPLATING_done ();
}
@ -1309,6 +1311,12 @@ run (void *cls,
(void) cls;
(void) args;
(void ) cfgfile;
if (GNUNET_OK !=
TALER_TEMPLATING_init ("exchange"))
{
GNUNET_break (0);
return;
}
if (print_h_payto)
{
char *s;
@ -1322,6 +1330,8 @@ run (void *cls,
}
TALER_MHD_setup (TALER_MHD_GO_NONE);
TEKT_cfg = config;
GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
NULL);
if (GNUNET_OK !=
TALER_KYCLOGIC_kyc_init (config))
{
@ -1329,8 +1339,6 @@ run (void *cls,
GNUNET_SCHEDULER_shutdown ();
return;
}
GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
NULL);
if (GNUNET_OK !=
exchange_serve_process_config ())
{

View File

@ -171,29 +171,15 @@ make_static_url (struct MHD_Connection *con,
}
/**
* Load a @a template and substitute using @a root, returning
* the result to the @a connection with the given
* @a http_status code.
*
* @param connection the connection we act upon
* @param http_status code to use on success
* @param template basename of the template to load
* @param instance_id instance ID, used to compute static files URL
* @param taler_uri value for "Taler:" header to set, or NULL
* @param root JSON object to pass as the root context
* @return #GNUNET_OK on success (reply queued), #GNUNET_NO if an error was queued,
* #GNUNET_SYSERR on failure (to queue an error)
*/
enum GNUNET_GenericReturnValue
TALER_TEMPLATING_reply (struct MHD_Connection *connection,
unsigned int http_status,
TALER_TEMPLATING_build (struct MHD_Connection *connection,
unsigned int *http_status,
const char *template,
const char *instance_id,
const char *taler_uri,
json_t *root)
json_t *root,
struct MHD_Response **reply)
{
struct MHD_Response *reply;
char *body;
size_t body_size;
@ -205,24 +191,27 @@ TALER_TEMPLATING_reply (struct MHD_Connection *connection,
template);
if (NULL == tmpl)
{
/* FIXME: should this not be an
internal failure? The language
missmatch is not critical here! */
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to load template `%s'\n",
template);
if (MHD_YES !=
TALER_MHD_reply_with_error (connection,
MHD_HTTP_NOT_ACCEPTABLE,
TALER_EC_GENERIC_FAILED_TO_LOAD_TEMPLATE,
template))
return GNUNET_SYSERR;
*http_status = MHD_HTTP_NOT_ACCEPTABLE;
*reply = TALER_MHD_make_error (TALER_EC_GENERIC_FAILED_TO_LOAD_TEMPLATE,
template);
return GNUNET_NO;
}
/* Add default values to the context */
if (NULL != instance_id)
{
char *static_url = make_static_url (connection,
instance_id);
json_object_set (root,
GNUNET_break (0 ==
json_object_set_new (root,
"static_url",
json_string (static_url));
json_string (static_url)));
GNUNET_free (static_url);
}
if (0 !=
@ -235,12 +224,9 @@ TALER_TEMPLATING_reply (struct MHD_Connection *connection,
"mustach failed on template `%s' with error %d\n",
template,
eno);
if (MHD_YES !=
TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_FAILED_TO_EXPAND_TEMPLATE,
template))
return GNUNET_SYSERR;
*http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
*reply = TALER_MHD_make_error (TALER_EC_GENERIC_FAILED_TO_EXPAND_TEMPLATE,
template);
return GNUNET_NO;
}
}
@ -255,10 +241,10 @@ TALER_TEMPLATING_reply (struct MHD_Connection *connection,
compressed = TALER_MHD_body_compress ((void **) &body,
&body_size);
}
reply = MHD_create_response_from_buffer (body_size,
*reply = MHD_create_response_from_buffer (body_size,
body,
MHD_RESPMEM_MUST_FREE);
if (NULL == reply)
if (NULL == *reply)
{
GNUNET_break (0);
return GNUNET_SYSERR;
@ -266,12 +252,13 @@ TALER_TEMPLATING_reply (struct MHD_Connection *connection,
if (compressed)
{
if (MHD_NO ==
MHD_add_response_header (reply,
MHD_add_response_header (*reply,
MHD_HTTP_HEADER_CONTENT_ENCODING,
"deflate"))
{
GNUNET_break (0);
MHD_destroy_response (reply);
MHD_destroy_response (*reply);
*reply = NULL;
return GNUNET_SYSERR;
}
}
@ -280,26 +267,47 @@ TALER_TEMPLATING_reply (struct MHD_Connection *connection,
/* Add standard headers */
if (NULL != taler_uri)
GNUNET_break (MHD_NO !=
MHD_add_response_header (reply,
MHD_add_response_header (*reply,
"Taler",
taler_uri));
GNUNET_break (MHD_NO !=
MHD_add_response_header (reply,
MHD_add_response_header (*reply,
MHD_HTTP_HEADER_CONTENT_TYPE,
"text/html"));
return GNUNET_OK;
}
/* Actually return reply */
enum GNUNET_GenericReturnValue
TALER_TEMPLATING_reply (struct MHD_Connection *connection,
unsigned int http_status,
const char *template,
const char *instance_id,
const char *taler_uri,
json_t *root)
{
enum GNUNET_GenericReturnValue res;
struct MHD_Response *reply;
MHD_RESULT ret;
res = TALER_TEMPLATING_build (connection,
&http_status,
template,
instance_id,
taler_uri,
root,
&reply);
if (GNUNET_SYSERR == res)
return res;
ret = MHD_queue_response (connection,
http_status,
reply);
MHD_destroy_response (reply);
if (MHD_NO == ret)
return GNUNET_SYSERR;
}
return GNUNET_OK;
return (res == GNUNET_OK)
? GNUNET_OK
: GNUNET_NO;
}