diff options
author | ms <ms@taler.net> | 2021-07-21 20:57:55 +0200 |
---|---|---|
committer | ms <ms@taler.net> | 2021-07-21 20:57:55 +0200 |
commit | 365bdde11b4286a54bc41ec744c1540e768b2e75 (patch) | |
tree | fcc469d09100cb7b2cb58527e1c89fb40914baab /src | |
parent | 39695b7f95bfe33bd2a9f63f2527d83427196c9a (diff) | |
download | merchant-365bdde11b4286a54bc41ec744c1540e768b2e75.tar.gz merchant-365bdde11b4286a54bc41ec744c1540e768b2e75.tar.bz2 merchant-365bdde11b4286a54bc41ec744c1540e768b2e75.zip |
more checks on the order object
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/taler-merchant-httpd_private-post-orders.c | 173 |
1 files changed, 120 insertions, 53 deletions
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c b/src/backend/taler-merchant-httpd_private-post-orders.c index fcd54e71..d4812715 100644 --- a/src/backend/taler-merchant-httpd_private-post-orders.c +++ b/src/backend/taler-merchant-httpd_private-post-orders.c @@ -661,15 +661,21 @@ patch_order (struct MHD_Connection *connection, const char *fulfillment_url = NULL; const char *merchant_base_url = NULL; json_t *jmerchant = NULL; + json_t *delivery_location = NULL; struct TALER_Amount max_wire_fee = { 0 }; struct TALER_Amount max_fee = { 0 }; uint32_t wire_fee_amortization = 0; struct GNUNET_TIME_Absolute timestamp = { 0 }; + struct GNUNET_TIME_Absolute delivery_date = { 0 }; struct GNUNET_TIME_Absolute refund_deadline = GNUNET_TIME_UNIT_FOREVER_ABS; struct GNUNET_TIME_Absolute pay_deadline = { 0 }; struct GNUNET_TIME_Absolute wire_deadline = GNUNET_TIME_UNIT_FOREVER_ABS; + /* auto_refund only needs to be type-checked, + * mostly because in GNUnet relative times can't + * be negative. */ + struct GNUNET_TIME_Relative auto_refund; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string ("merchant_base_url", @@ -704,6 +710,16 @@ patch_order (struct MHD_Connection *connection, GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_uint32 ("wire_fee_amortization", &wire_fee_amortization)), + GNUNET_JSON_spec_mark_optional ( + TALER_JSON_spec_absolute_time ("delivery_date", + &delivery_date)), + GNUNET_JSON_spec_mark_optional ( + TALER_JSON_spec_relative_time ("auto_refund", + &auto_refund)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_json ("delivery_location", + &delivery_location)), + GNUNET_JSON_spec_end () }; enum GNUNET_GenericReturnValue ret; @@ -810,6 +826,8 @@ patch_order (struct MHD_Connection *connection, } } + /* Check soundness of refund deadline, and that a timestamp + * is actually present. */ { struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); @@ -827,21 +845,35 @@ patch_order (struct MHD_Connection *connection, if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us == refund_deadline.abs_value_us) { - refund_deadline = GNUNET_TIME_relative_to_absolute (refund_delay); - - (void) GNUNET_TIME_round_abs (&refund_deadline); if (0 == refund_delay.rel_value_us) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Refund delay is zero, no refunds are possible for this order\n"); refund_deadline = now; /* if delay was 0, ensure that refund_deadline == timestamp */ } + else + { + refund_deadline = GNUNET_TIME_relative_to_absolute (refund_delay); + (void) GNUNET_TIME_round_abs (&refund_deadline); + } + GNUNET_assert (0 == json_object_set_new (order, "refund_deadline", GNUNET_JSON_from_time_abs ( refund_deadline))); } + if ((0 != delivery_date.abs_value_us) && + (delivery_date.abs_value_us < now.abs_value_us) ) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_BAD_REQUEST, + // FIXME: need appropriate error code. + TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_REFUND_AFTER_WIRE_DEADLINE, + NULL); + } } if (0 == pay_deadline.abs_value_us) @@ -864,12 +896,12 @@ patch_order (struct MHD_Connection *connection, GNUNET_TIME_relative_max (settings->default_wire_transfer_delay, refund_delay)); wire_deadline = GNUNET_TIME_absolute_max (refund_deadline, - wire_deadline); - (void) GNUNET_TIME_round_abs (&t); + t); + (void) GNUNET_TIME_round_abs (&wire_deadline); GNUNET_assert (0 == json_object_set_new (order, "wire_transfer_deadline", - GNUNET_JSON_from_time_abs (t))); + GNUNET_JSON_from_time_abs (wire_deadline))); } if (wire_deadline.abs_value_us < refund_deadline.abs_value_us) { @@ -891,6 +923,20 @@ patch_order (struct MHD_Connection *connection, TALER_JSON_from_amount (&settings->default_max_wire_fee))); } + else + { + if (0 != + strcasecmp (max_wire_fee.currency, + TMH_currency)) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_CONFLICT, + TALER_EC_GENERIC_CURRENCY_MISMATCH, + TMH_currency); + } + } if (GNUNET_OK != TALER_amount_is_valid (&max_fee)) @@ -902,6 +948,20 @@ patch_order (struct MHD_Connection *connection, TALER_JSON_from_amount (&settings->default_max_deposit_fee))); } + else + { + if (0 != + strcasecmp (max_fee.currency, + TMH_currency)) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_CONFLICT, + TALER_EC_GENERIC_CURRENCY_MISMATCH, + TMH_currency); + } + } if (0 == wire_fee_amortization) { @@ -912,7 +972,6 @@ patch_order (struct MHD_Connection *connection, json_integer ((json_int_t) settings->default_wire_fee_amortization))); } - if (NULL == merchant_base_url) { char *url; @@ -925,7 +984,17 @@ patch_order (struct MHD_Connection *connection, json_string (url))); GNUNET_free (url); } - + else if (('\0' == *merchant_base_url) || + ('/' != merchant_base_url[strlen(merchant_base_url) - 1])) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_PROPOSAL_PARSE_ERROR, + "merchant_base_url is not valid"); + } + /* Fill in merchant information if necessary */ if (NULL != jmerchant) { @@ -936,51 +1005,41 @@ patch_order (struct MHD_Connection *connection, TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_PROPOSAL_PARSE_ERROR, "'merchant' field already set, but must be provided by backend"); } - else + jmerchant = json_pack("{s:s}", + "name", settings->name); + GNUNET_assert (NULL != jmerchant); { - jmerchant = json_object (); - GNUNET_assert (NULL != jmerchant); - GNUNET_assert (0 == - json_object_set_new (jmerchant, - "name", - json_string (settings->name))); - GNUNET_assert (0 == - json_object_set_new (jmerchant, - "instance", - json_string (settings->id))); - { - json_t *loca; + json_t *loca; - /* Handle merchant address */ - loca = settings->address; - if (NULL != loca) - { - loca = json_deep_copy (loca); - GNUNET_assert (0 == - json_object_set_new (jmerchant, - "address", - loca)); - } - } + /* Handle merchant address */ + loca = settings->address; + if (NULL != loca) { - json_t *locj; + loca = json_deep_copy (loca); + GNUNET_assert (0 == + json_object_set_new (jmerchant, + "address", + loca)); + } + } + { + json_t *locj; - /* Handle merchant jurisdiction */ - locj = settings->jurisdiction; - if (NULL != locj) - { - locj = json_deep_copy (locj); - GNUNET_assert (0 == - json_object_set_new (jmerchant, - "jurisdiction", - locj)); - } + /* Handle merchant jurisdiction */ + locj = settings->jurisdiction; + if (NULL != locj) + { + locj = json_deep_copy (locj); + GNUNET_assert (0 == + json_object_set_new (jmerchant, + "jurisdiction", + locj)); } - GNUNET_assert (0 == - json_object_set_new (order, - "merchant", - jmerchant)); - } /* needed to synthesize merchant info */ + } + GNUNET_assert (0 == + json_object_set_new (order, + "merchant", + jmerchant)); /* add fields to the contract that the backend should provide */ GNUNET_assert (0 == @@ -1007,18 +1066,26 @@ patch_order (struct MHD_Connection *connection, } /* sanity check result */ { - struct GNUNET_HashCode hc; - - if (GNUNET_OK != - TALER_JSON_contract_hash (order, - &hc)) + struct GNUNET_HashCode h_control; + + switch (TALER_JSON_contract_hash (order, + &h_control)) { + case GNUNET_SYSERR: GNUNET_break (0); return TALER_MHD_reply_with_error ( connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_FAILED_COMPUTE_JSON_HASH, "could not compute hash of patched order"); + + case GNUNET_NO: + GNUNET_break_op (0); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_FAILED_COMPUTE_JSON_HASH, + "order contained unallowed values"); } } return execute_order (connection, |