diff options
author | Christian Grothoff <christian@grothoff.org> | 2024-09-10 15:47:31 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2024-09-10 15:47:31 +0200 |
commit | a8f851315ceb958ae7e1ee730f38384b5dab0799 (patch) | |
tree | 2a21a8f3067a78865b37861e5f6a8ddadcdf886e /src/backend/taler-merchant-httpd_private-post-orders.c | |
parent | 044c308a71b692977b02556cf9633fb5bb2f094a (diff) |
add logic to enforce hard limit on order creation
Diffstat (limited to 'src/backend/taler-merchant-httpd_private-post-orders.c')
-rw-r--r-- | src/backend/taler-merchant-httpd_private-post-orders.c | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c b/src/backend/taler-merchant-httpd_private-post-orders.c index 8a02625b..4db271ff 100644 --- a/src/backend/taler-merchant-httpd_private-post-orders.c +++ b/src/backend/taler-merchant-httpd_private-post-orders.c @@ -441,6 +441,13 @@ struct OrderContext * @e order. */ struct TALER_Amount max_stefan_fee; + + /** + * Maximum amount that could be paid over all + * available exchanges. Used to determine if this + * order creation requests exceeds legal limits. + */ + struct TALER_Amount total_exchange_limit; } set_exchanges; /** @@ -1910,13 +1917,25 @@ get_acceptable (void *cls, unsigned int priority = 42; /* make compiler happy */ json_t *j_exchange; enum GNUNET_GenericReturnValue res; - - res = TMH_exchange_check_debit (exchange, - oc->add_payment_details.wm); + struct TALER_Amount max_amount; + + max_amount = oc->parse_order.brutto; + res = TMH_exchange_check_debit ( + oc->hc->instance->settings.id, + exchange, + oc->add_payment_details.wm, + &max_amount); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Exchange %s evaluated at %d\n", url, res); + if (TALER_amount_is_zero (&max_amount)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Exchange %s deposit limit is zero, skipping it\n", + url); + return; + } switch (res) { case GNUNET_OK: @@ -1936,11 +1955,18 @@ get_acceptable (void *cls, priority = 768; /* stale, no accounts yet */ break; } + GNUNET_break (0 <= + TALER_amount_add ( + &oc->set_exchanges.total_exchange_limit, + &oc->set_exchanges.total_exchange_limit, + &max_amount)); j_exchange = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("url", url), GNUNET_JSON_pack_uint64 ("priority", priority), + TALER_JSON_pack_amount ("max_contribution", + &max_amount), GNUNET_JSON_pack_data_auto ("master_pub", TMH_EXCHANGES_get_master_pub (exchange))); GNUNET_assert (NULL != j_exchange); @@ -2052,6 +2078,10 @@ set_exchanges (struct OrderContext *oc) { oc->set_exchanges.exchanges = json_array (); GNUNET_assert (NULL != oc->set_exchanges.exchanges); + GNUNET_assert ( + GNUNET_OK == + TALER_amount_set_zero (oc->parse_order.brutto.currency, + &oc->set_exchanges.total_exchange_limit)); TMH_exchange_get_trusted (&get_exchange_keys, oc); } @@ -2089,6 +2119,20 @@ set_exchanges (struct OrderContext *oc) oc->add_payment_details.wm->wire_method); return false; } + if (1 == + TALER_amount_cmp (&oc->parse_order.brutto, + &oc->set_exchanges.total_exchange_limit)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Cannot create order: %s is the sum of hard limits from supported exchanges\n", + TALER_amount2s (&oc->set_exchanges.total_exchange_limit)); + reply_with_error ( + oc, + MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS, + TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_AMOUNT_EXCEEDS_LEGAL_LIMITS, + oc->add_payment_details.wm->wire_method); + return false; + } if (! oc->set_exchanges.exchange_good) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |