diff options
Diffstat (limited to 'src/backend/taler-merchant-httpd_private-get-orders.c')
-rw-r--r-- | src/backend/taler-merchant-httpd_private-get-orders.c | 282 |
1 files changed, 134 insertions, 148 deletions
diff --git a/src/backend/taler-merchant-httpd_private-get-orders.c b/src/backend/taler-merchant-httpd_private-get-orders.c index d4f74184..4c6a104e 100644 --- a/src/backend/taler-merchant-httpd_private-get-orders.c +++ b/src/backend/taler-merchant-httpd_private-get-orders.c @@ -225,6 +225,23 @@ cleanup (void *ctx) /** + * Closure for #process_refunds_cb(). + */ +struct ProcessRefundsClosure +{ + /** + * Place where we accumulate the refunds. + */ + struct TALER_Amount total_refund_amount; + + /** + * Set to an error code if something goes wrong. + */ + enum TALER_ErrorCode ec; +}; + + +/** * Function called with information about a refund. * It is responsible for summing up the refund amount. * @@ -249,11 +266,20 @@ process_refunds_cb (void *cls, const struct TALER_Amount *refund_amount, bool pending) { - struct TALER_Amount *total_refund_amount = cls; + struct ProcessRefundsClosure *prc = cls; + if (GNUNET_OK != + TALER_amount_cmp_currency (&prc->total_refund_amount, + refund_amount)) + { + /* Database error, refunds in mixed currency in DB. Not OK! */ + prc->ec = TALER_EC_GENERIC_DB_INVARIANT_FAILURE; + GNUNET_break (0); + return; + } GNUNET_assert (0 <= - TALER_amount_add (total_refund_amount, - total_refund_amount, + TALER_amount_add (&prc->total_refund_amount, + &prc->total_refund_amount, refund_amount)); } @@ -316,14 +342,12 @@ add_order (void *cls, { /* First try to find the order in the contracts */ uint64_t os; - bool paid = false; qs = TMH_db->lookup_contract_terms (TMH_db->cls, po->instance_id, order_id, &contract_terms, &os, - &paid, NULL); if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) GNUNET_break (os == order_serial); @@ -361,9 +385,8 @@ add_order (void *cls, { struct GNUNET_TIME_Timestamp rd; struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_amount ("amount", - TMH_currency, - &order_amount), + TALER_JSON_spec_amount_any ("amount", + &order_amount), GNUNET_JSON_spec_timestamp ("refund_deadline", &rd), GNUNET_JSON_spec_string ("summary", @@ -383,19 +406,33 @@ add_order (void *cls, return; } + if (TALER_amount_is_zero (&order_amount) && + (po->of.wired != TALER_EXCHANGE_YNA_ALL) ) + { + /* If we are actually filtering by wire status, + and the order was over an amount of zero, + do not return it as wire status is not + exactly meaningful for orders over zero. */ + json_decref (contract_terms); + GNUNET_free (order_id); + return; + } + if (GNUNET_TIME_absolute_is_future (rd.abs_time) && paid) { - struct TALER_Amount refund_amount; + struct ProcessRefundsClosure prc = { + .ec = TALER_EC_NONE + }; GNUNET_assert (GNUNET_OK == - TALER_amount_set_zero (TMH_currency, - &refund_amount)); + TALER_amount_set_zero (order_amount.currency, + &prc.total_refund_amount)); qs = TMH_db->lookup_refunds_detailed (TMH_db->cls, po->instance_id, &h_contract_terms, &process_refunds_cb, - &refund_amount); + &prc); if (0 > qs) { GNUNET_break (0); @@ -404,7 +441,15 @@ add_order (void *cls, GNUNET_free (order_id); return; } - if (0 > TALER_amount_cmp (&refund_amount, + if (TALER_EC_NONE != prc.ec) + { + GNUNET_break (0); + po->result = prc.ec; + json_decref (contract_terms); + GNUNET_free (order_id); + return; + } + if (0 > TALER_amount_cmp (&prc.total_refund_amount, &order_amount)) refundable = true; } @@ -602,7 +647,6 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh, { struct TMH_PendingOrder *po = hc->ctx; enum GNUNET_DB_QueryStatus qs; - struct TALER_MERCHANTDB_OrderFilter of; if (NULL != po) { @@ -622,11 +666,19 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh, GNUNET_JSON_pack_array_incref ("orders", po->pa)); } + po = GNUNET_new (struct TMH_PendingOrder); + hc->ctx = po; + hc->cc = &cleanup; + po->con = connection; + po->pa = json_array (); + GNUNET_assert (NULL != po->pa); + po->instance_id = hc->instance->settings.id; + po->mi = hc->instance; if (! (TALER_arg_to_yna (connection, "paid", TALER_EXCHANGE_YNA_ALL, - &of.paid)) ) + &po->of.paid)) ) return TALER_MHD_reply_with_error (connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PARAMETER_MALFORMED, @@ -634,7 +686,7 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh, if (! (TALER_arg_to_yna (connection, "refunded", TALER_EXCHANGE_YNA_ALL, - &of.refunded)) ) + &po->of.refunded)) ) return TALER_MHD_reply_with_error (connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PARAMETER_MALFORMED, @@ -642,49 +694,28 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh, if (! (TALER_arg_to_yna (connection, "wired", TALER_EXCHANGE_YNA_ALL, - &of.wired)) ) + &po->of.wired)) ) return TALER_MHD_reply_with_error (connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PARAMETER_MALFORMED, "wired"); + po->of.delta = -20; + /* deprecated in protocol v12 */ + TALER_MHD_parse_request_snumber (connection, + "delta", + &po->of.delta); + /* since protocol v12 */ + TALER_MHD_parse_request_snumber (connection, + "limit", + &po->of.delta); + if ( (-MAX_DELTA > po->of.delta) || + (po->of.delta > MAX_DELTA) ) { - const char *delta_str; - - delta_str = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "delta"); - if (NULL == delta_str) - { - of.delta = -20; - } - else - { - char dummy; - long long ll; - - if (1 != - sscanf (delta_str, - "%lld%c", - &ll, - &dummy)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "delta"); - } - of.delta = (int64_t) ll; - if ( (-MAX_DELTA > of.delta) || - (of.delta > MAX_DELTA) ) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "delta"); - } - } + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "delta"); } { const char *date_s_str; @@ -694,10 +725,10 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh, "date_s"); if (NULL == date_s_str) { - if (of.delta > 0) - of.date = GNUNET_TIME_UNIT_ZERO_TS; + if (po->of.delta > 0) + po->of.date = GNUNET_TIME_UNIT_ZERO_TS; else - of.date = GNUNET_TIME_UNIT_FOREVER_TS; + po->of.date = GNUNET_TIME_UNIT_FOREVER_TS; } else { @@ -717,9 +748,9 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh, "date_ms"); } - of.date = GNUNET_TIME_absolute_to_timestamp ( + po->of.date = GNUNET_TIME_absolute_to_timestamp ( GNUNET_TIME_absolute_from_s (ll)); - if (GNUNET_TIME_absolute_is_never (of.date.abs_time)) + if (GNUNET_TIME_absolute_is_never (po->of.date.abs_time)) { GNUNET_break_op (0); return TALER_MHD_reply_with_error (connection, @@ -729,99 +760,56 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh, } } } + if (po->of.delta > 0) + po->of.start_row = 0; + else + po->of.start_row = INT64_MAX; + /* deprecated in protocol v12 */ + TALER_MHD_parse_request_number (connection, + "start", + &po->of.start_row); + /* since protocol v12 */ + TALER_MHD_parse_request_number (connection, + "offset", + &po->of.start_row); + if (INT64_MAX < po->of.start_row) { - const char *start_row_str; - - start_row_str = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "start"); - if (NULL == start_row_str) - { - if (of.delta > 0) - of.start_row = 0; - else - of.start_row = INT64_MAX; - } - else - { - char dummy; - unsigned long long ull; - - if (1 != - sscanf (start_row_str, - "%llu%c", - &ull, - &dummy)) - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "start"); - of.start_row = (uint64_t) ull; - if (INT64_MAX < of.start_row) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "start"); - } - } + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "start"); } + po->of.session_id + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "session_id"); + po->of.fulfillment_url + = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "fulfillment_url"); + TALER_MHD_parse_request_timeout (connection, + &po->long_poll_timeout); + if (GNUNET_TIME_absolute_is_never (po->long_poll_timeout)) { - const char *timeout_ms_str; - - timeout_ms_str = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "timeout_ms"); - if (NULL == timeout_ms_str) - { - of.timeout = GNUNET_TIME_UNIT_ZERO; - } - else - { - char dummy; - unsigned long long ull; - - if (1 != - sscanf (timeout_ms_str, - "%llu%c", - &ull, - &dummy)) - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "timeout_ms"); - of.timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, - ull); - if (GNUNET_TIME_relative_is_forever (of.timeout)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "timeout_ms"); - } - } - - if ( (0 >= of.delta) && - (! GNUNET_TIME_relative_is_zero (of.timeout)) ) - { - GNUNET_break_op (0); - of.timeout = GNUNET_TIME_UNIT_ZERO; - } + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "timeout_ms"); + } + po->of.timeout = GNUNET_TIME_absolute_get_remaining (po->long_poll_timeout); + if ( (0 >= po->of.delta) && + (GNUNET_TIME_absolute_is_future (po->long_poll_timeout)) ) + { + GNUNET_break_op (0); + po->of.timeout = GNUNET_TIME_UNIT_ZERO; + po->long_poll_timeout = GNUNET_TIME_UNIT_ZERO_ABS; } - po = GNUNET_new (struct TMH_PendingOrder); - hc->ctx = po; - hc->cc = &cleanup; - po->con = connection; - po->pa = json_array (); - GNUNET_assert (NULL != po->pa); - po->instance_id = hc->instance->settings.id; - po->mi = hc->instance; qs = TMH_db->lookup_orders (TMH_db->cls, po->instance_id, - &of, + &po->of, &add_order, po); if (0 > qs) @@ -838,7 +826,7 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh, NULL); } if ( (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) && - (! GNUNET_TIME_relative_is_zero (of.timeout)) ) + (GNUNET_TIME_absolute_is_future (po->long_poll_timeout)) ) { struct TMH_MerchantInstance *mi = hc->instance; @@ -849,8 +837,6 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh, po->hn = GNUNET_CONTAINER_heap_insert (order_timeout_heap, po, po->long_poll_timeout.abs_value_us); - po->long_poll_timeout = GNUNET_TIME_relative_to_absolute (of.timeout); - po->of = of; GNUNET_CONTAINER_DLL_insert (mi->po_head, mi->po_tail, po); |