diff options
author | Christian Grothoff <christian@grothoff.org> | 2021-08-04 18:11:35 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2021-08-04 18:11:35 +0200 |
commit | 99eb36e490f5f0ca16cb451941ca873b03016b27 (patch) | |
tree | 9da20e4ef9dd7b5b1e9a860afc92c55b431df648 | |
parent | 977c3d47538d071e2b37599bb71c0fae3ad36d44 (diff) |
-implement #6953 + #6948
m--------- | contrib/merchant-backoffice | 0 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_helper.c | 166 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_helper.h | 40 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_private-post-orders.c | 38 |
4 files changed, 235 insertions, 9 deletions
diff --git a/contrib/merchant-backoffice b/contrib/merchant-backoffice -Subproject 03c8c9b794905878175d07366267bdc01c3795b +Subproject fe987187e178816d42ed12178d430c8771cb5a7 diff --git a/src/backend/taler-merchant-httpd_helper.c b/src/backend/taler-merchant-httpd_helper.c index 374751d1..585a491a 100644 --- a/src/backend/taler-merchant-httpd_helper.c +++ b/src/backend/taler-merchant-httpd_helper.c @@ -92,11 +92,173 @@ TMH_payto_uri_array_valid (const json_t *payto_uris) bool TMH_location_object_valid (const json_t *location) { - return true; // FIXME + const char *country; + const char *subdivision; + const char *district; + const char *town; + const char *town_loc; + const char *postcode; + const char *street; + const char *building; + const char *building_no; + json_t *lines = NULL; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("country", + &country)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("country_subdivision", + &subdivision)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("district", + &district)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("town", + &town)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("town_location", + &town_loc)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("post_code", + &postcode)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("street", + &street)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("building_name", + &building)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("building_number", + &building_no)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_json ("address_lines", + &lines)), + GNUNET_JSON_spec_end () + }; + const char *ename; + unsigned int eline; + + if (GNUNET_OK != + GNUNET_JSON_parse (location, + spec, + &ename, + &eline)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Invalid location for field %s\n", + ename); + return false; + } + if (NULL != lines) + { + size_t idx; + json_t *line; + + if (! json_is_array (lines)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Invalid location for field %s\n", + "lines"); + return false; + } + json_array_foreach (lines, idx, line) + { + if (! json_is_string (line)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Invalid address line #%u in location\n", + (unsigned int) idx); + return false; + } + } + } + return true; +} + + +bool +TMH_products_array_valid (const json_t *products) +{ + const json_t *product; + size_t idx; + bool valid = true; + + if (! json_is_array (products)) + return false; + json_array_foreach ((json_t *) products, idx, product) + { + const char *product_id; + const char *description; + json_t *description_i18n = NULL; + uint64_t quantity; + const char *unit; + struct TALER_Amount price; + const char *image_data_url = NULL; + json_t *taxes = NULL; + struct GNUNET_TIME_Absolute delivery_date; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("product_id", + &product_id)), + GNUNET_JSON_spec_string ("description", + &description), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_json ("description_i18n", + &description_i18n)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_uint64 ("quantity", + &quantity)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("unit", + &unit)), + GNUNET_JSON_spec_mark_optional ( + TALER_JSON_spec_amount ("price", + TMH_currency, + &price)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("image", + &image_data_url)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_json ("taxes", + &taxes)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_absolute_time ("delivery_date", + &delivery_date)), + GNUNET_JSON_spec_end () + }; + const char *ename; + unsigned int eline; + + if (GNUNET_OK != + GNUNET_JSON_parse (product, + spec, + &ename, + &eline)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Invalid product #%u for field %s\n", + (unsigned int) idx, + ename); + return false; + } + if ( (NULL != image_data_url) && + (! TMH_image_data_url_valid (image_data_url)) ) + valid = false; + if ( (NULL != taxes) && + (! TMH_taxes_array_valid (taxes)) ) + valid = false; + if ( (NULL != description_i18n) && + (! TALER_JSON_check_i18n (description_i18n)) ) + valid = false; + GNUNET_JSON_parse_free (spec); + if (! valid) + break; + } + + return valid; } -// FIXME bool TMH_image_data_url_valid (const char *image_data_url) { diff --git a/src/backend/taler-merchant-httpd_helper.h b/src/backend/taler-merchant-httpd_helper.h index 4c353942..dc7c08b1 100644 --- a/src/backend/taler-merchant-httpd_helper.h +++ b/src/backend/taler-merchant-httpd_helper.h @@ -38,21 +38,55 @@ TMH_payto_uri_array_valid (const json_t *payto_uris); /** - * FIXME. + * Check if @a taxes is an array of valid Taxes in the sense of + * Taler's API definition. + * + * @param taxes array to check + * @return true if @a taxes is an array and all + * entries are valid Taxes. */ bool TMH_taxes_array_valid (const json_t *taxes); -// FIXME +/** + * Check if @a location is a valid Location object in the sense of Taler's API + * definition. + * + * @param location object to check + * @return true if @a location is an object + * representing a Location. + */ bool TMH_location_object_valid (const json_t *location); -// FIXME +/** + * Check if @a products is an array of valid Product(s) in the sense of + * Taler's API definition. + * + * @param products array to check + * @return true if @a products is an array and all + * entries are valid Products. + */ +bool +TMH_products_array_valid (const json_t *products); + + +/** + * Check if @a image_data_url is a valid image + * data URL. Does not validate the actual payload, + * only the syntax and that it properly claims to + * be an image. + * + * @param image_data_url string to check + * @return true if @a image_data_url is a data + * URL with an "image/" mime-type + */ bool TMH_image_data_url_valid (const char *image_data_url); + /** * Setup new wire method for the given @ payto_uri. * diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c b/src/backend/taler-merchant-httpd_private-post-orders.c index 403036af..5a10e449 100644 --- a/src/backend/taler-merchant-httpd_private-post-orders.c +++ b/src/backend/taler-merchant-httpd_private-post-orders.c @@ -327,10 +327,13 @@ execute_order (struct MHD_Connection *connection, struct TALER_Amount total; const char *order_id; const char *summary; + const char *fulfillment_msg = NULL; json_t *products; json_t *merchant; + json_t *summary_i18n = NULL; + json_t *fulfillment_i18n = NULL; struct GNUNET_TIME_Absolute timestamp; - struct GNUNET_TIME_Absolute refund_deadline; + struct GNUNET_TIME_Absolute refund_deadline = { 0 }; struct GNUNET_TIME_Absolute wire_transfer_deadline; struct GNUNET_TIME_Absolute pay_deadline; struct GNUNET_JSON_Specification spec[] = { @@ -348,10 +351,20 @@ execute_order (struct MHD_Connection *connection, &products), GNUNET_JSON_spec_json ("merchant", &merchant), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_json ("summary_i18n", + &summary_i18n)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("fulfillment_message", + &fulfillment_msg)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_json ("fulfillment_message_i18n", + &fulfillment_i18n)), TALER_JSON_spec_absolute_time ("timestamp", ×tamp), - TALER_JSON_spec_absolute_time ("refund_deadline", - &refund_deadline), + GNUNET_JSON_spec_mark_optional ( + TALER_JSON_spec_absolute_time ("refund_deadline", + &refund_deadline)), TALER_JSON_spec_absolute_time ("pay_deadline", &pay_deadline), TALER_JSON_spec_absolute_time ("wire_transfer_deadline", @@ -387,6 +400,23 @@ execute_order (struct MHD_Connection *connection, "order:products"); } + if (! TALER_JSON_check_i18n (fulfillment_i18n)) + { + GNUNET_JSON_parse_free (spec); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "order:fulfillment_i18n"); + } + if (! TALER_JSON_check_i18n (summary_i18n)) + { + GNUNET_JSON_parse_free (spec); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "order:summary_i18n"); + } + /* Test if we already have an order with this id */ { struct TALER_ClaimTokenP token; @@ -1169,7 +1199,7 @@ merge_inventory (struct MHD_Connection *connection, "products", json_array ())); } - else if (! json_is_array (jprod)) + else if (! TMH_products_array_valid (jprod)) { return TALER_MHD_reply_with_error (connection, MHD_HTTP_BAD_REQUEST, |