summaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd_private-post-orders.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/taler-merchant-httpd_private-post-orders.c')
-rw-r--r--src/backend/taler-merchant-httpd_private-post-orders.c123
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,