summaryrefslogtreecommitdiff
path: root/src/lib/exchange_api_transfers_get.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/exchange_api_transfers_get.c')
-rw-r--r--src/lib/exchange_api_transfers_get.c215
1 files changed, 97 insertions, 118 deletions
diff --git a/src/lib/exchange_api_transfers_get.c b/src/lib/exchange_api_transfers_get.c
index b9a9db941..c558fb42e 100644
--- a/src/lib/exchange_api_transfers_get.c
+++ b/src/lib/exchange_api_transfers_get.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2021 Taler Systems SA
+ Copyright (C) 2014-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -38,9 +38,9 @@ struct TALER_EXCHANGE_TransfersGetHandle
{
/**
- * The connection to exchange this request handle will use
+ * The keys of the exchange this request handle will use
*/
- struct TALER_EXCHANGE_Handle *exchange;
+ struct TALER_EXCHANGE_Keys *keys;
/**
* The url for this request.
@@ -84,25 +84,34 @@ check_transfers_get_response_ok (
struct TALER_EXCHANGE_TransfersGetHandle *wdh,
const json_t *json)
{
- json_t *details_j;
- struct TALER_EXCHANGE_TransferData td;
+ const json_t *details_j;
struct TALER_Amount total_expected;
struct TALER_MerchantPublicKeyP merchant_pub;
+ struct TALER_EXCHANGE_TransfersGetResponse tgr = {
+ .hr.reply = json,
+ .hr.http_status = MHD_HTTP_OK
+ };
+ struct TALER_EXCHANGE_TransferData *td
+ = &tgr.details.ok.td;
struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_amount_any ("total", &td.total_amount),
- TALER_JSON_spec_amount_any ("wire_fee", &td.wire_fee),
- GNUNET_JSON_spec_fixed_auto ("merchant_pub", &merchant_pub),
- GNUNET_JSON_spec_fixed_auto ("h_payto", &td.h_payto),
- GNUNET_JSON_spec_timestamp ("execution_time", &td.execution_time),
- GNUNET_JSON_spec_json ("deposits", &details_j),
- GNUNET_JSON_spec_fixed_auto ("exchange_sig", &td.exchange_sig),
- GNUNET_JSON_spec_fixed_auto ("exchange_pub", &td.exchange_pub),
+ TALER_JSON_spec_amount_any ("total",
+ &td->total_amount),
+ TALER_JSON_spec_amount_any ("wire_fee",
+ &td->wire_fee),
+ GNUNET_JSON_spec_fixed_auto ("merchant_pub",
+ &merchant_pub),
+ GNUNET_JSON_spec_fixed_auto ("h_payto",
+ &td->h_payto),
+ GNUNET_JSON_spec_timestamp ("execution_time",
+ &td->execution_time),
+ GNUNET_JSON_spec_array_const ("deposits",
+ &details_j),
+ GNUNET_JSON_spec_fixed_auto ("exchange_sig",
+ &td->exchange_sig),
+ GNUNET_JSON_spec_fixed_auto ("exchange_pub",
+ &td->exchange_pub),
GNUNET_JSON_spec_end ()
};
- struct TALER_EXCHANGE_HttpResponse hr = {
- .reply = json,
- .http_status = MHD_HTTP_OK
- };
if (GNUNET_OK !=
GNUNET_JSON_parse (json,
@@ -113,32 +122,30 @@ check_transfers_get_response_ok (
return GNUNET_SYSERR;
}
if (GNUNET_OK !=
- TALER_amount_set_zero (td.total_amount.currency,
+ TALER_amount_set_zero (td->total_amount.currency,
&total_expected))
{
GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
if (GNUNET_OK !=
TALER_EXCHANGE_test_signing_key (
- TALER_EXCHANGE_get_keys (wdh->exchange),
- &td.exchange_pub))
+ wdh->keys,
+ &td->exchange_pub))
{
GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
- td.details_length = json_array_size (details_j);
+ td->details_length = json_array_size (details_j);
{
struct GNUNET_HashContext *hash_context;
struct TALER_TrackTransferDetails *details;
- details = GNUNET_new_array (td.details_length,
+ details = GNUNET_new_array (td->details_length,
struct TALER_TrackTransferDetails);
- td.details = details;
+ td->details = details;
hash_context = GNUNET_CRYPTO_hash_context_start ();
- for (unsigned int i = 0; i<td.details_length; i++)
+ for (unsigned int i = 0; i<td->details_length; i++)
{
struct TALER_TrackTransferDetails *detail = &details[i];
struct json_t *detail_j = json_array_get (details_j, i);
@@ -146,21 +153,27 @@ check_transfers_get_response_ok (
GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
&detail->h_contract_terms),
GNUNET_JSON_spec_fixed_auto ("coin_pub", &detail->coin_pub),
- TALER_JSON_spec_amount_any ("deposit_value", &detail->coin_value),
- TALER_JSON_spec_amount_any ("deposit_fee", &detail->coin_fee),
+ TALER_JSON_spec_amount ("deposit_value",
+ total_expected.currency,
+ &detail->coin_value),
+ TALER_JSON_spec_amount ("deposit_fee",
+ total_expected.currency,
+ &detail->coin_fee),
+ GNUNET_JSON_spec_mark_optional (
+ TALER_JSON_spec_amount ("refund_total",
+ total_expected.currency,
+ &detail->refund_total),
+ NULL),
GNUNET_JSON_spec_end ()
};
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_set_zero (td->total_amount.currency,
+ &detail->refund_total));
if ( (GNUNET_OK !=
GNUNET_JSON_parse (detail_j,
spec_detail,
NULL, NULL)) ||
- (GNUNET_OK !=
- TALER_amount_cmp_currency (&total_expected,
- &detail->coin_value)) ||
- (GNUNET_OK !=
- TALER_amount_cmp_currency (&total_expected,
- &detail->coin_fee)) ||
(0 >
TALER_amount_add (&total_expected,
&total_expected,
@@ -172,51 +185,35 @@ check_transfers_get_response_ok (
{
GNUNET_break_op (0);
GNUNET_CRYPTO_hash_context_abort (hash_context);
- GNUNET_JSON_parse_free (spec);
GNUNET_free (details);
return GNUNET_SYSERR;
}
/* build up big hash for signature checking later */
- {
- struct TALER_WireDepositDetailP dd;
-
- dd.h_contract_terms = detail->h_contract_terms;
- dd.execution_time = GNUNET_TIME_timestamp_hton (td.execution_time);
- dd.coin_pub = detail->coin_pub;
- TALER_amount_hton (&dd.deposit_value,
- &detail->coin_value);
- TALER_amount_hton (&dd.deposit_fee,
- &detail->coin_fee);
- GNUNET_CRYPTO_hash_context_read (hash_context,
- &dd,
- sizeof (dd));
- }
+ TALER_exchange_online_wire_deposit_append (
+ hash_context,
+ &detail->h_contract_terms,
+ td->execution_time,
+ &detail->coin_pub,
+ &detail->coin_value,
+ &detail->coin_fee);
}
/* Check signature */
{
- struct TALER_WireDepositDataPS wdp = {
- .purpose.purpose = htonl (
- TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT),
- .purpose.size = htonl (sizeof (wdp)),
- .merchant_pub = merchant_pub,
- .h_payto = td.h_payto
- };
+ struct GNUNET_HashCode h_details;
- TALER_amount_hton (&wdp.total,
- &td.total_amount);
- TALER_amount_hton (&wdp.wire_fee,
- &td.wire_fee);
GNUNET_CRYPTO_hash_context_finish (hash_context,
- &wdp.h_details);
+ &h_details);
if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (
- TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT,
- &wdp,
- &td.exchange_sig.eddsa_signature,
- &td.exchange_pub.eddsa_pub))
+ TALER_exchange_online_wire_deposit_verify (
+ &td->total_amount,
+ &td->wire_fee,
+ &merchant_pub,
+ &td->h_payto,
+ &h_details,
+ &td->exchange_pub,
+ &td->exchange_sig))
{
GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
GNUNET_free (details);
return GNUNET_SYSERR;
}
@@ -225,29 +222,24 @@ check_transfers_get_response_ok (
if (0 >
TALER_amount_subtract (&total_expected,
&total_expected,
- &td.wire_fee))
+ &td->wire_fee))
{
GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
GNUNET_free (details);
return GNUNET_SYSERR;
}
if (0 !=
TALER_amount_cmp (&total_expected,
- &td.total_amount))
+ &td->total_amount))
{
GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
GNUNET_free (details);
return GNUNET_SYSERR;
}
wdh->cb (wdh->cb_cls,
- &hr,
- &td);
+ &tgr);
GNUNET_free (details);
}
- GNUNET_JSON_parse_free (spec);
- TALER_EXCHANGE_transfers_get_cancel (wdh);
return GNUNET_OK;
}
@@ -267,100 +259,85 @@ handle_transfers_get_finished (void *cls,
{
struct TALER_EXCHANGE_TransfersGetHandle *wdh = cls;
const json_t *j = response;
- struct TALER_EXCHANGE_HttpResponse hr = {
- .reply = j,
- .http_status = (unsigned int) response_code
+ struct TALER_EXCHANGE_TransfersGetResponse tgr = {
+ .hr.reply = j,
+ .hr.http_status = (unsigned int) response_code
};
wdh->job = NULL;
switch (response_code)
{
case 0:
- hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
break;
case MHD_HTTP_OK:
if (GNUNET_OK ==
check_transfers_get_response_ok (wdh,
j))
+ {
+ TALER_EXCHANGE_transfers_get_cancel (wdh);
return;
+ }
GNUNET_break_op (0);
- hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- hr.http_status = 0;
+ tgr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+ tgr.hr.http_status = 0;
break;
case MHD_HTTP_BAD_REQUEST:
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
- hr.ec = TALER_JSON_get_error_code (j);
- hr.hint = TALER_JSON_get_error_hint (j);
+ tgr.hr.ec = TALER_JSON_get_error_code (j);
+ tgr.hr.hint = TALER_JSON_get_error_hint (j);
break;
case MHD_HTTP_FORBIDDEN:
/* Nothing really to verify, exchange says one of the signatures is
invalid; as we checked them, this should never happen, we
should pass the JSON reply to the application */
- hr.ec = TALER_JSON_get_error_code (j);
- hr.hint = TALER_JSON_get_error_hint (j);
+ tgr.hr.ec = TALER_JSON_get_error_code (j);
+ tgr.hr.hint = TALER_JSON_get_error_hint (j);
break;
case MHD_HTTP_NOT_FOUND:
/* Exchange does not know about transaction;
we should pass the reply to the application */
- hr.ec = TALER_JSON_get_error_code (j);
- hr.hint = TALER_JSON_get_error_hint (j);
+ tgr.hr.ec = TALER_JSON_get_error_code (j);
+ tgr.hr.hint = TALER_JSON_get_error_hint (j);
break;
case MHD_HTTP_INTERNAL_SERVER_ERROR:
/* Server had an internal issue; we should retry, but this API
leaves this to the application */
- hr.ec = TALER_JSON_get_error_code (j);
- hr.hint = TALER_JSON_get_error_hint (j);
+ tgr.hr.ec = TALER_JSON_get_error_code (j);
+ tgr.hr.hint = TALER_JSON_get_error_hint (j);
break;
default:
/* unexpected response code */
GNUNET_break_op (0);
- hr.ec = TALER_JSON_get_error_code (j);
- hr.hint = TALER_JSON_get_error_hint (j);
+ tgr.hr.ec = TALER_JSON_get_error_code (j);
+ tgr.hr.hint = TALER_JSON_get_error_hint (j);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u/%d for transfers get\n",
(unsigned int) response_code,
- (int) hr.ec);
+ (int) tgr.hr.ec);
break;
}
wdh->cb (wdh->cb_cls,
- &hr,
- NULL);
+ &tgr);
TALER_EXCHANGE_transfers_get_cancel (wdh);
}
-/**
- * Query the exchange about which transactions were combined
- * to create a wire transfer.
- *
- * @param exchange exchange to query
- * @param wtid raw wire transfer identifier to get information about
- * @param cb callback to call
- * @param cb_cls closure for @a cb
- * @return handle to cancel operation
- */
struct TALER_EXCHANGE_TransfersGetHandle *
TALER_EXCHANGE_transfers_get (
- struct TALER_EXCHANGE_Handle *exchange,
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
const struct TALER_WireTransferIdentifierRawP *wtid,
TALER_EXCHANGE_TransfersGetCallback cb,
void *cb_cls)
{
struct TALER_EXCHANGE_TransfersGetHandle *wdh;
- struct GNUNET_CURL_Context *ctx;
CURL *eh;
char arg_str[sizeof (struct TALER_WireTransferIdentifierRawP) * 2 + 32];
- if (GNUNET_YES !=
- TEAH_handle_is_ready (exchange))
- {
- GNUNET_break (0);
- return NULL;
- }
-
wdh = GNUNET_new (struct TALER_EXCHANGE_TransfersGetHandle);
- wdh->exchange = exchange;
wdh->cb = cb;
wdh->cb_cls = cb_cls;
@@ -376,11 +353,12 @@ TALER_EXCHANGE_transfers_get (
*end = '\0';
GNUNET_snprintf (arg_str,
sizeof (arg_str),
- "/transfers/%s",
+ "transfers/%s",
wtid_str);
}
- wdh->url = TEAH_path_to_url (wdh->exchange,
- arg_str);
+ wdh->url = TALER_url_join (url,
+ arg_str,
+ NULL);
if (NULL == wdh->url)
{
GNUNET_free (wdh);
@@ -394,7 +372,7 @@ TALER_EXCHANGE_transfers_get (
GNUNET_free (wdh);
return NULL;
}
- ctx = TEAH_handle_to_context (exchange);
+ wdh->keys = TALER_EXCHANGE_keys_incref (keys);
wdh->job = GNUNET_CURL_job_add_with_ct_json (ctx,
eh,
&handle_transfers_get_finished,
@@ -419,6 +397,7 @@ TALER_EXCHANGE_transfers_get_cancel (
wdh->job = NULL;
}
GNUNET_free (wdh->url);
+ TALER_EXCHANGE_keys_decref (wdh->keys);
GNUNET_free (wdh);
}