aboutsummaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd_private-post-orders.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-09-10 15:47:31 +0200
committerChristian Grothoff <christian@grothoff.org>2024-09-10 15:47:31 +0200
commita8f851315ceb958ae7e1ee730f38384b5dab0799 (patch)
tree2a21a8f3067a78865b37861e5f6a8ddadcdf886e /src/backend/taler-merchant-httpd_private-post-orders.c
parent044c308a71b692977b02556cf9633fb5bb2f094a (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.c50
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,