aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/exchange-lib/exchange_api_payback.c35
-rw-r--r--src/exchange-lib/test_exchange_api.c5
-rw-r--r--src/exchange/taler-exchange-httpd_db.c1
-rw-r--r--src/include/taler_exchange_service.h3
4 files changed, 42 insertions, 2 deletions
diff --git a/src/exchange-lib/exchange_api_payback.c b/src/exchange-lib/exchange_api_payback.c
index eff459693..30cd55cba 100644
--- a/src/exchange-lib/exchange_api_payback.c
+++ b/src/exchange-lib/exchange_api_payback.c
@@ -54,6 +54,11 @@ struct TALER_EXCHANGE_PaybackHandle
char *json_enc;
/**
+ * Denomination key of the coin.
+ */
+ const struct TALER_EXCHANGE_DenomPublicKey *pk;
+
+ /**
* Handle for the request.
*/
struct GNUNET_CURL_Job *job;
@@ -181,6 +186,35 @@ handle_payback_finished (void *cls,
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
break;
+ case MHD_HTTP_FORBIDDEN:
+ {
+ /* Insufficient funds, proof attached */
+ json_t *history;
+ struct TALER_Amount total;
+ const struct TALER_EXCHANGE_DenomPublicKey *dki;
+
+ dki = ph->pk;
+ history = json_object_get (json,
+ "history");
+ if (GNUNET_OK !=
+ TALER_EXCHANGE_verify_coin_history (dki->fee_deposit.currency,
+ &ph->coin_pub,
+ history,
+ &total))
+ {
+ GNUNET_break_op (0);
+ response_code = 0;
+ }
+ ph->cb (ph->cb_cls,
+ response_code,
+ TALER_JSON_get_error_code (json),
+ &total,
+ GNUNET_TIME_UNIT_FOREVER_ABS,
+ NULL,
+ json);
+ TALER_EXCHANGE_payback_cancel (ph);
+ return;
+ }
case MHD_HTTP_UNAUTHORIZED:
/* Nothing really to verify, exchange says one of the signatures is
invalid; as we checked them, this should never happen, we
@@ -277,6 +311,7 @@ TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange,
ph = GNUNET_new (struct TALER_EXCHANGE_PaybackHandle);
ph->coin_pub = pr.coin_pub;
ph->exchange = exchange;
+ ph->pk = pk;
ph->cb = payback_cb;
ph->cb_cls = payback_cb_cls;
ph->url = MAH_path_to_url (exchange, "/payback");
diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c
index 5b64e79bd..fb0c93eb1 100644
--- a/src/exchange-lib/test_exchange_api.c
+++ b/src/exchange-lib/test_exchange_api.c
@@ -3501,6 +3501,11 @@ run (void *cls)
.expected_response_code = MHD_HTTP_OK,
.details.payback.ref = "payback-withdraw-coin-2a",
.details.payback.amount = "EUR:0.5" },
+ { .oc = OC_PAYBACK,
+ .label = "payback-2b",
+ .expected_response_code = MHD_HTTP_FORBIDDEN,
+ .details.payback.ref = "payback-withdraw-coin-2a",
+ .details.payback.amount = "EUR:0.5" },
{ .oc = OC_DEPOSIT,
.label = "payback-deposit-revoked",
.expected_response_code = MHD_HTTP_NOT_FOUND,
diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c
index 57be19708..d7f91c892 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -2396,7 +2396,6 @@ TEH_DB_execute_payback (struct MHD_Connection *connection,
if ( (0 == amount.fraction) &&
(0 == amount.value) )
{
- GNUNET_break_op (0);
TEH_plugin->rollback (TEH_plugin->cls,
session);
ret = TEH_RESPONSE_reply_coin_insufficient_funds (connection,
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
index bd8e281d3..c097dff1a 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -1403,7 +1403,8 @@ struct TALER_EXCHANGE_PaybackHandle;
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
* 0 if the exchange's reply is bogus (fails to follow the protocol)
* @param ec taler-specific error code, #TALER_EC_NONE on success
- * @param amount amount the exchange will wire back for this coin
+ * @param amount amount the exchange will wire back for this coin,
+ * on error the total balance remaining, or NULL
* @param timestamp what time did the exchange receive the /payback request
* @param reserve_pub public key of the reserve receiving the payback
* @param full_response full response from the exchange (for logging, in case of errors)