aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-04-15 11:10:18 +0200
committerChristian Grothoff <christian@grothoff.org>2024-04-15 11:10:18 +0200
commit570bb0303239b9f64311e5f40cba24f5cfe81ee1 (patch)
tree11f97bfccc1bcef660afe92eb27805c907ec723b
parentbae916ea62e8947092ab084a48bca721b30d6fef (diff)
API extension for challenger 0.11
-rw-r--r--src/exchangedb/0002-kyc_attributes.sql10
-rw-r--r--src/include/taler_mhd_lib.h272
-rw-r--r--src/mhd/Makefile.am2
-rw-r--r--src/mhd/mhd_legal.c1
-rw-r--r--src/mhd/mhd_parsing.c62
-rw-r--r--src/templating/templating_api.c13
6 files changed, 218 insertions, 142 deletions
diff --git a/src/exchangedb/0002-kyc_attributes.sql b/src/exchangedb/0002-kyc_attributes.sql
index 897aff561..66f3fc315 100644
--- a/src/exchangedb/0002-kyc_attributes.sql
+++ b/src/exchangedb/0002-kyc_attributes.sql
@@ -107,16 +107,6 @@ BEGIN
' ADD CONSTRAINT ' || table_name || '_serial_key '
'UNIQUE (kyc_attributes_serial_id)'
);
- -- The legitimization_serial is a foreign key.
- -- But, due to partitioning by h_payto, we can not simply reference
- -- the serial id of the legitimization_processes. Thus, the following
- -- is commented out.
- -- EXECUTE FORMAT (
- -- 'ALTER TABLE ' || table_name ||
- -- ' ADD CONSTRAINT ' || table_name || '_foreign_legitimization_processes'
- -- ' FOREIGN KEY (legitimization_serial) '
- -- ' REFERENCES legitimization_processes (legitimization_process_serial_id)' -- ON DELETE CASCADE
- -- );
-- To search similar users (e.g. during AML checks)
EXECUTE FORMAT (
'CREATE INDEX ' || table_name || '_similarity_index '
diff --git a/src/include/taler_mhd_lib.h b/src/include/taler_mhd_lib.h
index d93bc1e14..57d041758 100644
--- a/src/include/taler_mhd_lib.h
+++ b/src/include/taler_mhd_lib.h
@@ -173,8 +173,8 @@ TALER_MHD_reply_json_pack (struct MHD_Connection *connection,
* @return MHD result code
*/
#define TALER_MHD_REPLY_JSON_PACK(connection,response_code,...) \
- TALER_MHD_reply_json_steal (connection, GNUNET_JSON_PACK (__VA_ARGS__), \
- response_code)
+ TALER_MHD_reply_json_steal (connection, GNUNET_JSON_PACK (__VA_ARGS__), \
+ response_code)
/**
@@ -259,7 +259,7 @@ TALER_MHD_make_json_pack (const char *fmt,
* @return MHD response object
*/
#define TALER_MHD_MAKE_JSON_PACK(...) \
- TALER_MHD_make_json_steal (GNUNET_JSON_PACK (__VA_ARGS__))
+ TALER_MHD_make_json_steal (GNUNET_JSON_PACK (__VA_ARGS__))
/**
@@ -270,8 +270,8 @@ TALER_MHD_make_json_pack (const char *fmt,
* @return packer array entries (two!)
*/
#define TALER_MHD_PACK_EC(ec) \
- GNUNET_JSON_pack_uint64 ("code", ec), \
- GNUNET_JSON_pack_string ("hint", TALER_ErrorCode_get_hint (ec))
+ GNUNET_JSON_pack_uint64 ("code", ec), \
+ GNUNET_JSON_pack_string ("hint", TALER_ErrorCode_get_hint (ec))
/**
* Create a response indicating an internal error.
@@ -462,19 +462,19 @@ TALER_MHD_parse_request_arg_timeout (struct MHD_Connection *connection,
* the current time plus the value given under "timeout_ms" otherwise
*/
#define TALER_MHD_parse_request_timeout(connection,expiration) \
- do { \
- switch (TALER_MHD_parse_request_arg_timeout (connection, \
- expiration)) \
- { \
- case GNUNET_SYSERR: \
- GNUNET_break (0); \
- return MHD_NO; \
- case GNUNET_NO: \
- GNUNET_break_op (0); \
- case GNUNET_OK: \
- break; \
- } \
- } while (0)
+ do { \
+ switch (TALER_MHD_parse_request_arg_timeout (connection, \
+ expiration)) \
+ { \
+ case GNUNET_SYSERR: \
+ GNUNET_break (0); \
+ return MHD_NO; \
+ case GNUNET_NO: \
+ GNUNET_break_op (0); \
+ case GNUNET_OK: \
+ break; \
+ } \
+ } while (0)
/**
@@ -505,20 +505,20 @@ TALER_MHD_parse_request_arg_number (struct MHD_Connection *connection,
* unchanged if value was not specified
*/
#define TALER_MHD_parse_request_number(connection,name,off) \
- do { \
- switch (TALER_MHD_parse_request_arg_number (connection, \
- name, \
- off)) \
- { \
- case GNUNET_SYSERR: \
- GNUNET_break (0); \
- return MHD_NO; \
- case GNUNET_NO: \
- GNUNET_break_op (0); \
- case GNUNET_OK: \
- break; \
- } \
- } while (0)
+ do { \
+ switch (TALER_MHD_parse_request_arg_number (connection, \
+ name, \
+ off)) \
+ { \
+ case GNUNET_SYSERR: \
+ GNUNET_break (0); \
+ return MHD_NO; \
+ case GNUNET_NO: \
+ GNUNET_break_op (0); \
+ case GNUNET_OK: \
+ break; \
+ } \
+ } while (0)
/**
@@ -549,20 +549,20 @@ TALER_MHD_parse_request_arg_snumber (struct MHD_Connection *connection,
* unchanged if value was not specified
*/
#define TALER_MHD_parse_request_snumber(connection,name,val) \
- do { \
- switch (TALER_MHD_parse_request_arg_snumber (connection, \
- name, \
- val)) \
- { \
- case GNUNET_SYSERR: \
- GNUNET_break (0); \
- return MHD_NO; \
- case GNUNET_NO: \
- GNUNET_break_op (0); \
- case GNUNET_OK: \
- break; \
- } \
- } while (0)
+ do { \
+ switch (TALER_MHD_parse_request_arg_snumber (connection, \
+ name, \
+ val)) \
+ { \
+ case GNUNET_SYSERR: \
+ GNUNET_break (0); \
+ return MHD_NO; \
+ case GNUNET_NO: \
+ GNUNET_break_op (0); \
+ case GNUNET_OK: \
+ break; \
+ } \
+ } while (0)
/**
@@ -593,20 +593,42 @@ TALER_MHD_parse_request_arg_amount (struct MHD_Connection *connection,
* unchanged if value was not specified
*/
#define TALER_MHD_parse_request_amount(connection,name,val) \
- do { \
- switch (TALER_MHD_parse_request_arg_amount (connection, \
- name, \
- val)) \
- { \
- case GNUNET_SYSERR: \
- GNUNET_break (0); \
- return MHD_NO; \
- case GNUNET_NO: \
- GNUNET_break_op (0); \
- case GNUNET_OK: \
- break; \
- } \
- } while (0)
+ do { \
+ switch (TALER_MHD_parse_request_arg_amount (connection, \
+ name, \
+ val)) \
+ { \
+ case GNUNET_SYSERR: \
+ GNUNET_break (0); \
+ return MHD_NO; \
+ case GNUNET_NO: \
+ GNUNET_break_op (0); \
+ case GNUNET_OK: \
+ break; \
+ } \
+ } while (0)
+
+
+/**
+ * Determines which of the given choices is preferred
+ * by the client. Parses an HTTP header such as
+ * "Accept:" or "Language:" to find entries matching
+ * the list of strings given in the variadic argument
+ * list. Returns the index of the preferred choice.
+ *
+ * @param connection HTTP request handle
+ * @param header type of HTTP header to evaluate
+ * @param ... NULL-terminated list of choices to
+ * check for in the header
+ * @return -1 if none of the given choices is in
+ * the header, -2 if the header is missing,
+ * otherwise index of preferred choice in
+ * the varargs list
+ */
+int
+TALER_MHD_check_accept (struct MHD_Connection *connection,
+ const char *header,
+ ...);
/**
@@ -670,28 +692,28 @@ TALER_MHD_parse_request_header_data (struct MHD_Connection *connection,
* #GNUNET_SYSERR on internal error (error response could not be sent)
*/
#define TALER_MHD_parse_request_arg_auto(connection,name,val,required) \
- do { \
- bool p; \
- switch (TALER_MHD_parse_request_arg_data (connection, name, \
- val, sizeof (*val), &p)) \
- { \
- case GNUNET_SYSERR: \
- GNUNET_break (0); \
- return MHD_NO; \
- case GNUNET_NO: \
- GNUNET_break_op (0); \
- return MHD_YES; \
- case GNUNET_OK: \
- if (required & (! p)) \
- return TALER_MHD_reply_with_error ( \
- connection, \
- MHD_HTTP_BAD_REQUEST, \
- TALER_EC_GENERIC_PARAMETER_MISSING, \
- name); \
- required = p; \
- break; \
- } \
- } while (0)
+ do { \
+ bool p; \
+ switch (TALER_MHD_parse_request_arg_data (connection, name, \
+ val, sizeof (*val), &p)) \
+ { \
+ case GNUNET_SYSERR: \
+ GNUNET_break (0); \
+ return MHD_NO; \
+ case GNUNET_NO: \
+ GNUNET_break_op (0); \
+ return MHD_YES; \
+ case GNUNET_OK: \
+ if (required & (! p)) \
+ return TALER_MHD_reply_with_error ( \
+ connection, \
+ MHD_HTTP_BAD_REQUEST, \
+ TALER_EC_GENERIC_PARAMETER_MISSING, \
+ name); \
+ required = p; \
+ break; \
+ } \
+ } while (0)
/**
@@ -706,10 +728,10 @@ TALER_MHD_parse_request_header_data (struct MHD_Connection *connection,
* #GNUNET_SYSERR on internal error (error response could not be sent)
*/
#define TALER_MHD_parse_request_arg_auto_t(connection,name,val) \
- do { \
- bool b = true; \
- TALER_MHD_parse_request_arg_auto (connection,name,val,b); \
- } while (0)
+ do { \
+ bool b = true; \
+ TALER_MHD_parse_request_arg_auto (connection,name,val,b); \
+ } while (0)
/**
* Extract fixed-size base32crockford encoded data from request.
@@ -725,28 +747,28 @@ TALER_MHD_parse_request_header_data (struct MHD_Connection *connection,
* #GNUNET_SYSERR on internal error (error response could not be sent)
*/
#define TALER_MHD_parse_request_header_auto(connection,name,val,required) \
- do { \
- bool p; \
- switch (TALER_MHD_parse_request_header_data (connection, name, \
- val, sizeof (*val), &p)) \
- { \
- case GNUNET_SYSERR: \
- GNUNET_break (0); \
- return MHD_NO; \
- case GNUNET_NO: \
- GNUNET_break_op (0); \
- return MHD_YES; \
- case GNUNET_OK: \
- if (required & (! p)) \
- return TALER_MHD_reply_with_error ( \
- connection, \
- MHD_HTTP_BAD_REQUEST, \
- TALER_EC_GENERIC_PARAMETER_MISSING, \
- name); \
- required = p; \
- break; \
- } \
- } while (0)
+ do { \
+ bool p; \
+ switch (TALER_MHD_parse_request_header_data (connection, name, \
+ val, sizeof (*val), &p)) \
+ { \
+ case GNUNET_SYSERR: \
+ GNUNET_break (0); \
+ return MHD_NO; \
+ case GNUNET_NO: \
+ GNUNET_break_op (0); \
+ return MHD_YES; \
+ case GNUNET_OK: \
+ if (required & (! p)) \
+ return TALER_MHD_reply_with_error ( \
+ connection, \
+ MHD_HTTP_BAD_REQUEST, \
+ TALER_EC_GENERIC_PARAMETER_MISSING, \
+ name); \
+ required = p; \
+ break; \
+ } \
+ } while (0)
/**
@@ -761,10 +783,10 @@ TALER_MHD_parse_request_header_data (struct MHD_Connection *connection,
* #GNUNET_SYSERR on internal error (error response could not be sent)
*/
#define TALER_MHD_parse_request_header_auto_t(connection,name,val) \
- do { \
- bool b = true; \
- TALER_MHD_parse_request_header_auto (connection,name,val,b); \
- } while (0)
+ do { \
+ bool b = true; \
+ TALER_MHD_parse_request_header_auto (connection,name,val,b); \
+ } while (0)
/**
@@ -795,19 +817,19 @@ TALER_MHD_check_content_length_ (struct MHD_Connection *connection,
* @param max_len maximum allowed content length
*/
#define TALER_MHD_check_content_length(connection,max_len) \
- do { \
- switch (TALER_MHD_check_content_length_ (connection, max_len)) \
- { \
- case GNUNET_SYSERR: \
- GNUNET_break (0); \
- return MHD_NO; \
- case GNUNET_NO: \
- GNUNET_break_op (0); \
- return MHD_YES; \
- case GNUNET_OK: \
- break; \
- } \
- } while (0)
+ do { \
+ switch (TALER_MHD_check_content_length_ (connection, max_len)) \
+ { \
+ case GNUNET_SYSERR: \
+ GNUNET_break (0); \
+ return MHD_NO; \
+ case GNUNET_NO: \
+ GNUNET_break_op (0); \
+ return MHD_YES; \
+ case GNUNET_OK: \
+ break; \
+ } \
+ } while (0)
/**
diff --git a/src/mhd/Makefile.am b/src/mhd/Makefile.am
index d36bba42f..cd3fe7701 100644
--- a/src/mhd/Makefile.am
+++ b/src/mhd/Makefile.am
@@ -16,7 +16,7 @@ libtalermhd_la_SOURCES = \
mhd_responses.c \
mhd_run.c
libtalermhd_la_LDFLAGS = \
- -version-info 2:0:2 \
+ -version-info 3:0:3 \
-no-undefined
libtalermhd_la_LIBADD = \
$(top_builddir)/src/json/libtalerjson.la \
diff --git a/src/mhd/mhd_legal.c b/src/mhd/mhd_legal.c
index 9630452eb..8353a6901 100644
--- a/src/mhd/mhd_legal.c
+++ b/src/mhd/mhd_legal.c
@@ -131,6 +131,7 @@ mime_matches (const char *accept_pattern,
if ( (NULL == da) ||
(NULL == dm) )
return (0 == strcmp ("*", accept_pattern));
+ // FIXME: use TALER_MHD_check_accept() here!
/* FIXME: eventually, we might want to parse the "q=$FLOAT"
part after the ';' and figure out which one is the
best/preferred match instead of returning a boolean... */
diff --git a/src/mhd/mhd_parsing.c b/src/mhd/mhd_parsing.c
index 2c3312cf2..771319bd5 100644
--- a/src/mhd/mhd_parsing.c
+++ b/src/mhd/mhd_parsing.c
@@ -508,4 +508,66 @@ TALER_MHD_check_content_length_ (struct MHD_Connection *connection,
}
+int
+TALER_MHD_check_accept (struct MHD_Connection *connection,
+ const char *header,
+ ...)
+{
+ bool ret = false;
+ const char *accept;
+ char *a;
+ char *saveptr;
+
+ accept = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ header);
+ if (NULL == accept)
+ return -2; /* no Accept header set */
+
+ a = GNUNET_strdup (accept);
+ for (char *t = strtok_r (a, ",", &saveptr);
+ NULL != t;
+ t = strtok_r (NULL, ",", &saveptr))
+ {
+ char *end;
+
+ /* skip leading whitespace */
+ while (isspace ((unsigned char) t[0]))
+ t++;
+ /* trim of ';q=' parameter and everything after space */
+ /* FIXME: eventually, we might want to parse the "q=$FLOAT"
+ part after the ';' and figure out which one is the
+ best/preferred match instead of returning a boolean... */
+ end = strchr (t, ';');
+ if (NULL != end)
+ *end = '\0';
+ end = strchr (t, ' ');
+ if (NULL != end)
+ *end = '\0';
+ {
+ va_list ap;
+ int off = 0;
+ const char *val;
+
+ va_start (ap,
+ header);
+ while (NULL != (val = va_arg (ap,
+ const char *)))
+ {
+ if (0 == strcasecmp (val,
+ t))
+ {
+ ret = off;
+ break;
+ }
+ off++;
+ }
+ va_end (ap);
+ }
+ }
+ GNUNET_free (a);
+ return ret;
+}
+
+
/* end of mhd_parsing.c */
diff --git a/src/templating/templating_api.c b/src/templating/templating_api.c
index 3bda7de55..88a17c682 100644
--- a/src/templating/templating_api.c
+++ b/src/templating/templating_api.c
@@ -221,7 +221,7 @@ TALER_TEMPLATING_build (struct MHD_Connection *connection,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to load template `%s'\n",
template);
- *http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
+ *http_status = MHD_HTTP_NOT_ACCEPTABLE;
*reply = TALER_MHD_make_error (TALER_EC_GENERIC_FAILED_TO_LOAD_TEMPLATE,
template);
return GNUNET_NO;
@@ -432,11 +432,12 @@ load_template (void *cls,
MHD_RESULT
-TALER_TEMPLATING_reply_error (struct MHD_Connection *connection,
- const char *template_basename,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- const char *detail)
+TALER_TEMPLATING_reply_error (
+ struct MHD_Connection *connection,
+ const char *template_basename,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const char *detail)
{
json_t *data;
enum GNUNET_GenericReturnValue ret;