diff options
author | Christian Grothoff <christian@grothoff.org> | 2024-04-15 11:10:18 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2024-04-15 11:10:18 +0200 |
commit | 570bb0303239b9f64311e5f40cba24f5cfe81ee1 (patch) | |
tree | 11f97bfccc1bcef660afe92eb27805c907ec723b | |
parent | bae916ea62e8947092ab084a48bca721b30d6fef (diff) |
API extension for challenger 0.11
-rw-r--r-- | src/exchangedb/0002-kyc_attributes.sql | 10 | ||||
-rw-r--r-- | src/include/taler_mhd_lib.h | 272 | ||||
-rw-r--r-- | src/mhd/Makefile.am | 2 | ||||
-rw-r--r-- | src/mhd/mhd_legal.c | 1 | ||||
-rw-r--r-- | src/mhd/mhd_parsing.c | 62 | ||||
-rw-r--r-- | src/templating/templating_api.c | 13 |
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; |