diff options
author | Florian Dold <florian@dold.me> | 2021-07-21 18:54:46 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2021-07-21 18:54:54 +0200 |
commit | 963adec62961ec04d0a3bd3496c9880c87782164 (patch) | |
tree | adf0dcbe768dded522144f966879a5d3a9782532 /src | |
parent | 9f4283e61b44f33351f979dea74a1bd73cb50e82 (diff) |
start with refactoring private_post-orders
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/taler-merchant-httpd_private-post-orders.c | 123 |
1 files changed, 65 insertions, 58 deletions
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c b/src/backend/taler-merchant-httpd_private-post-orders.c index ad7cef4b..fcd54e71 100644 --- a/src/backend/taler-merchant-httpd_private-post-orders.c +++ b/src/backend/taler-merchant-httpd_private-post-orders.c @@ -724,7 +724,7 @@ patch_order (struct MHD_Connection *connection, { char buf[256]; time_t timer; - struct tm*tm_info; + struct tm *tm_info; size_t off; uint64_t rand; char *last; @@ -741,9 +741,11 @@ patch_order (struct MHD_Connection *connection, NULL); } off = strftime (buf, - sizeof (buf), + sizeof (buf) - 1, "%Y.%j", tm_info); + /* Check for error state of strftime */ + GNUNET_assert (0 != off); buf[off++] = '-'; rand = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); @@ -751,8 +753,10 @@ patch_order (struct MHD_Connection *connection, sizeof (uint64_t), &buf[off], sizeof (buf) - off); + GNUNET_assert (NULL != last); *last = '\0'; jbuf = json_string (buf); + GNUNET_assert (NULL != jbuf); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Assigning order ID `%s' server-side\n", buf); @@ -776,6 +780,18 @@ patch_order (struct MHD_Connection *connection, /* replace ${ORDER_ID} with the real order_id */ char *nurl; + /* We only allow one placeholder */ + if (strstr (pos + strlen ("${ORDER_ID}"), + "${ORDER_ID}")) + { + /* FIXME: free anything? */ + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "fulfillment_url"); + } + GNUNET_asprintf (&nurl, "%.*s%s%s", /* first output URL until ${ORDER_ID} */ @@ -1051,6 +1067,7 @@ add_payment_details (struct MHD_Connection *connection, struct TMH_WireMethod *wm; wm = hc->instance->wm_head; + /* Locate wire method that has a matching payment target */ while ( (NULL != wm) && ( (! wm->active) || ( (NULL != payment_target) && @@ -1100,7 +1117,7 @@ add_payment_details (struct MHD_Connection *connection, * @param[in,out] order order to process (can be modified) * @param claim_token token to use for access control * @param refund_delay time window where it is possible to ask a refund - * @param payment_target bank account that should receive the payment + * @param payment_target RFC8905 payment target type to find a matching merchant account * @param inventory_products_length length of the @a inventory_products array * @param inventory_products array of products to add to @a order from our inventory * @param uuids_length length of the @a uuids array @@ -1120,16 +1137,31 @@ merge_inventory (struct MHD_Connection *connection, unsigned int uuids_length, const struct GNUNET_Uuid uuids[]) { - if (NULL == json_object_get (order, - "products")) + /** + * inventory_products => instructions to add products to contract terms + * order.products => contains products that are not from the backend-managed inventory. + */ + GNUNET_assert (NULL != order); { - GNUNET_assert (NULL != order); - GNUNET_assert (0 == - json_object_set_new (order, - "products", - json_array ())); + json_t *jprod = json_object_get (order, + "products"); + if (NULL == jprod) + { + GNUNET_assert (0 == + json_object_set_new (order, + "products", + json_array ())); + } + else if (! json_is_array (jprod)) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "order.products"); + } } + /* Populate products from inventory product array and database */ { json_t *np = json_array (); @@ -1150,6 +1182,7 @@ merge_inventory (struct MHD_Connection *connection, switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); http_status = MHD_HTTP_INTERNAL_SERVER_ERROR; ec = TALER_EC_GENERIC_DB_FETCH_FAILED; break; @@ -1197,6 +1230,7 @@ merge_inventory (struct MHD_Connection *connection, } GNUNET_free (pd.description); GNUNET_free (pd.unit); + GNUNET_free (pd.image); json_decref (pd.address); } /* merge into existing products list */ @@ -1251,26 +1285,29 @@ TMH_private_post_orders (const struct TMH_RequestHandler *rh, json_t *uuid; struct GNUNET_Uuid *uuids = NULL; struct TALER_ClaimTokenP claim_token; + bool create_token = true; /* default */ struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_json ("order", &order), GNUNET_JSON_spec_mark_optional ( + TALER_JSON_spec_relative_time ("refund_delay", + &refund_delay)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("payment_target", + &payment_target)), + GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_json ("inventory_products", &ip)), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_json ("lock_uuids", &uuid)), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("payment_target", - &payment_target)), - GNUNET_JSON_spec_mark_optional ( - TALER_JSON_spec_relative_time ("refund_delay", - &refund_delay)), + GNUNET_JSON_spec_bool ("create_token", + &create_token)), GNUNET_JSON_spec_end () }; enum GNUNET_GenericReturnValue ret; struct GNUNET_HashCode h_post_data; - bool create_token = true; /* default */ (void) rh; ret = TALER_MHD_parse_json_data (connection, @@ -1280,33 +1317,11 @@ TMH_private_post_orders (const struct TMH_RequestHandler *rh, return (GNUNET_NO == ret) ? MHD_YES : MHD_NO; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Refund delay is %llu\n", (unsigned long long) refund_delay.rel_value_us); - /* parse and handle the create_token (optionally given) */ - if (NULL != json_object_get (hc->request_body, - "create_token")) - { - struct GNUNET_JSON_Specification ispec[] = { - GNUNET_JSON_spec_bool ("create_token", - &create_token), - GNUNET_JSON_spec_end () - }; - enum GNUNET_GenericReturnValue ret; - - (void) rh; - ret = TALER_MHD_parse_json_data (connection, - hc->request_body, - ispec); - if (GNUNET_OK != ret) - { - GNUNET_JSON_parse_free (spec); - return (GNUNET_NO == ret) - ? MHD_YES - : MHD_NO; - } - } if (create_token) { GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, @@ -1323,13 +1338,13 @@ TMH_private_post_orders (const struct TMH_RequestHandler *rh, /* Compute h_post_data (for idempotency check) */ { - char *wire_enc; - char *input; + char *req_body_enc; - if (NULL == (wire_enc = json_dumps (hc->request_body, - JSON_ENCODE_ANY - | JSON_COMPACT - | JSON_SORT_KEYS))) + /* Dump normalized JSON to string. */ + if (NULL == (req_body_enc = json_dumps (hc->request_body, + JSON_ENCODE_ANY + | JSON_COMPACT + | JSON_SORT_KEYS))) { GNUNET_break (0); GNUNET_JSON_parse_free (spec); @@ -1338,18 +1353,10 @@ TMH_private_post_orders (const struct TMH_RequestHandler *rh, TALER_EC_GENERIC_ALLOCATION_FAILURE, "request body normalization for hashing"); } - /* We include the full request: JSON body and the create_token and - refund_delay arguments */ - GNUNET_asprintf (&input, - "%s-%llu-%d\n", - wire_enc, - (unsigned long long) refund_delay.rel_value_us, - create_token ? 1 : 0); - free (wire_enc); - GNUNET_CRYPTO_hash (input, - strlen (input), + GNUNET_CRYPTO_hash (req_body_enc, + strlen (req_body_enc), &h_post_data); - GNUNET_free (input); + GNUNET_free (req_body_enc); } /* parse the inventory_products (optionally given) */ @@ -1444,12 +1451,12 @@ TMH_private_post_orders (const struct TMH_RequestHandler *rh, GNUNET_array_grow (uuids, uuids_len, 0); + GNUNET_JSON_parse_free (spec); GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "UUID parsing failed at #%u: %s:%u\n", i, error_name, error_line); - GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error (connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PARAMETER_MALFORMED, |