diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index 671e7908b..c69be57e4 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -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 $< $@
diff --git a/contrib/bad_gateway.en.must b/contrib/bad_gateway.en.must
new file mode 100644
index 000000000..f177db900
--- /dev/null
+++ b/contrib/bad_gateway.en.must
@@ -0,0 +1,12 @@
+
+
+KYC server failure
+
+
+The KYC backend returned a malformed response, reproduced
+below. Please inform the exchange operator about this failure.
+
+{{ kyc_server_reply }}
+
+
+
\ No newline at end of file
diff --git a/contrib/kyc_failed.en.must b/contrib/kyc_failed.en.must
new file mode 100644
index 000000000..c1e27a821
--- /dev/null
+++ b/contrib/kyc_failed.en.must
@@ -0,0 +1,20 @@
+
+
+KYC authentication failed
+
+
+You failed the KYC check. See below for details.
+
+
+
+{{ verifications }}
+
+
+
\ No newline at end of file
diff --git a/contrib/kyc_interaction_failed.en.must b/contrib/kyc_interaction_failed.en.must
new file mode 100644
index 000000000..504cd09c9
--- /dev/null
+++ b/contrib/kyc_interaction_failed.en.must
@@ -0,0 +1,13 @@
+
+
+KYC server interaction failed
+
+
+The KYC backend returned a response indicating a problem with the exchange logic. Please inform the exchange operator about this failure.
+
+{{ kyc_http_status }}
+{{ kyc_logic }}
+{{ kyc_server_reply }}
+
+
+
diff --git a/contrib/kyc_provider_internal_error.en.must b/contrib/kyc_provider_internal_error.en.must
new file mode 100644
index 000000000..37d1e0f3a
--- /dev/null
+++ b/contrib/kyc_provider_internal_error.en.must
@@ -0,0 +1,13 @@
+
+
+KYC provider had an internal error
+
+
+The KYC backend had an internal error.
+
+{{ kyc_http_status }}
+{{ kyc_logic }}
+{{ kyc_server_reply }}
+
+
+
diff --git a/contrib/kyc_provider_ratelimit.en.must b/contrib/kyc_provider_ratelimit.en.must
new file mode 100644
index 000000000..77917c0b3
--- /dev/null
+++ b/contrib/kyc_provider_ratelimit.en.must
@@ -0,0 +1,13 @@
+
+
+KYC provider rate limit reached
+
+
+The KYC backend interaction ran into a rate limit.
+
+{{ kyc_http_status }}
+{{ kyc_logic }}
+{{ kyc_server_reply }}
+
+
+
diff --git a/contrib/kyc_provider_timeout.en.must b/contrib/kyc_provider_timeout.en.must
new file mode 100644
index 000000000..c1ad79b34
--- /dev/null
+++ b/contrib/kyc_provider_timeout.en.must
@@ -0,0 +1,13 @@
+
+
+KYC provider timeout
+
+
+The KYC backend interaction ran into a timeout.
+
+{{ kyc_http_status }}
+{{ kyc_logic }}
+{{ kyc_server_reply }}
+
+
+
diff --git a/contrib/kyc_provider_unauthorized.en.must b/contrib/kyc_provider_unauthorized.en.must
new file mode 100644
index 000000000..9b4858178
--- /dev/null
+++ b/contrib/kyc_provider_unauthorized.en.must
@@ -0,0 +1,13 @@
+
+
+KYC server refused access
+
+
+The KYC backend refused the authorization code used by the exchange operator. Please inform the exchange operator about this failure.
+
+{{ kyc_http_status }}
+{{ kyc_logic }}
+{{ kyc_server_reply }}
+
+
+
diff --git a/contrib/kyc_provider_unexpected_reply.en.must b/contrib/kyc_provider_unexpected_reply.en.must
new file mode 100644
index 000000000..b3df670a4
--- /dev/null
+++ b/contrib/kyc_provider_unexpected_reply.en.must
@@ -0,0 +1,13 @@
+
+
+KYC provider returned unexpected status code
+
+
+The KYC backend returned an unexpected status code.
+
+{{ kyc_http_status }}
+{{ kyc_logic }}
+{{ kyc_server_reply }}
+
+
+
diff --git a/contrib/kyc_provider_unpaid.en.must b/contrib/kyc_provider_unpaid.en.must
new file mode 100644
index 000000000..65fa4f9b7
--- /dev/null
+++ b/contrib/kyc_provider_unpaid.en.must
@@ -0,0 +1,13 @@
+
+
+KYC credit exhausted
+
+
+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.
+
+{{ kyc_http_status }}
+{{ kyc_logic }}
+{{ kyc_server_reply }}
+
+
+
diff --git a/contrib/kyc_user_failed.en.must b/contrib/kyc_user_failed.en.must
new file mode 100644
index 000000000..54a4637c4
--- /dev/null
+++ b/contrib/kyc_user_failed.en.must
@@ -0,0 +1,20 @@
+
+
+KYC authentication failed
+
+
+You failed the KYC check. See below for details.
+
+
+
+{{ verifications }}
+
+
+
\ No newline at end of file
diff --git a/contrib/test.en.must b/contrib/test.en.must
deleted file mode 100644
index e69de29bb..000000000
diff --git a/src/include/taler_templating_lib.h b/src/include/taler_templating_lib.h
index bad200f50..9cce84f5a 100644
--- a/src/include/taler_templating_lib.h
+++ b/src/include/taler_templating_lib.h
@@ -24,6 +24,34 @@
#include
+/**
+ * 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
diff --git a/src/kyclogic/Makefile.am b/src/kyclogic/Makefile.am
index 53c0660a0..9f034731c 100644
--- a/src/kyclogic/Makefile.am
+++ b/src/kyclogic/Makefile.am
@@ -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 \
diff --git a/src/kyclogic/plugin_kyclogic_kycaid.c b/src/kyclogic/plugin_kyclogic_kycaid.c
index acfcb0e03..5c56bcf48 100644
--- a/src/kyclogic/plugin_kyclogic_kycaid.c
+++ b/src/kyclogic/plugin_kyclogic_kycaid.c
@@ -20,9 +20,10 @@
*/
#include "platform.h"
#include "taler_kyclogic_plugin.h"
-#include
-#include
-#include
+#include "taler_mhd_lib.h"
+#include "taler_curl_lib.h"
+#include "taler_json_lib.h"
+#include "taler_templating_lib.h"
#include
#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 */
- MHD_HTTP_BAD_GATEWAY,
- resp);
+ 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,
+ "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,
- MHD_HTTP_OK,
- resp);
+ 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,
+ "kyc_user_failed",
+ template_data);
}
GNUNET_JSON_parse_free (spec);
}
@@ -733,97 +781,131 @@ 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 */
- 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);
- break;
+ {
+ 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));
+ 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);
- break;
+ {
+ 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);
- break;
+ {
+ 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);
- break;
+ {
+ 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;
diff --git a/src/kyclogic/plugin_kyclogic_oauth2.c b/src/kyclogic/plugin_kyclogic_oauth2.c
index b9384e8ff..da7ddfc31 100644
--- a/src/kyclogic/plugin_kyclogic_oauth2.c
+++ b/src/kyclogic/plugin_kyclogic_oauth2.c
@@ -20,8 +20,8 @@
*/
#include "platform.h"
#include "taler_kyclogic_plugin.h"
-#include
-#include
+#include "taler_mhd_lib.h"
+#include "taler_json_lib.h"
#include
#include "taler_util.h"
diff --git a/src/kyclogic/plugin_kyclogic_template.c b/src/kyclogic/plugin_kyclogic_template.c
index aefa4a62f..4a21882b8 100644
--- a/src/kyclogic/plugin_kyclogic_template.c
+++ b/src/kyclogic/plugin_kyclogic_template.c
@@ -20,8 +20,8 @@
*/
#include "platform.h"
#include "taler_kyclogic_plugin.h"
-#include
-#include
+#include "taler_mhd_lib.h"
+#include "taler_json_lib.h"
#include
#include "taler_util.h"
diff --git a/src/kyclogic/taler-exchange-kyc-tester.c b/src/kyclogic/taler-exchange-kyc-tester.c
index 9d75b3ec8..740fcda7a 100644
--- a/src/kyclogic/taler-exchange-kyc-tester.c
+++ b/src/kyclogic/taler-exchange-kyc-tester.c
@@ -27,6 +27,7 @@
#include
#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 ())
{
diff --git a/src/templating/templating_api.c b/src/templating/templating_api.c
index 50356e45a..38a2d3e31 100644
--- a/src/templating/templating_api.c
+++ b/src/templating/templating_api.c
@@ -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,
- "static_url",
- json_string (static_url));
+
+ GNUNET_break (0 ==
+ json_object_set_new (root,
+ "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,
- body,
- MHD_RESPMEM_MUST_FREE);
- if (NULL == reply)
+ *reply = MHD_create_response_from_buffer (body_size,
+ body,
+ MHD_RESPMEM_MUST_FREE);
+ 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,29 +267,50 @@ 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"));
-
- /* Actually return reply */
- {
- MHD_RESULT ret;
-
- ret = MHD_queue_response (connection,
- http_status,
- reply);
- MHD_destroy_response (reply);
- if (MHD_NO == ret)
- return GNUNET_SYSERR;
- }
return GNUNET_OK;
}
+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 (res == GNUNET_OK)
+ ? GNUNET_OK
+ : GNUNET_NO;
+}
+
+
/**
* Function called with a template's filename.
*