summaryrefslogtreecommitdiff
path: root/src/exchange-lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange-lib')
-rw-r--r--src/exchange-lib/Makefile.am3
-rw-r--r--src/exchange-lib/exchange_api_deposit.c4
-rw-r--r--src/exchange-lib/exchange_api_reserve.c15
-rw-r--r--src/exchange-lib/exchange_api_wire.c475
-rw-r--r--src/exchange-lib/test_exchange_api.c80
-rw-r--r--src/exchange-lib/test_exchange_api.conf78
-rw-r--r--src/exchange-lib/test_exchange_api_home/.config/taler/account-1.json5
-rw-r--r--src/exchange-lib/test_exchange_api_home/.config/taler/account-2.json5
-rw-r--r--src/exchange-lib/test_exchange_api_home/.config/taler/x-taler-bank.json5
-rw-r--r--src/exchange-lib/test_exchange_api_keys_cherry_picking.conf64
-rw-r--r--src/exchange-lib/test_exchange_api_keys_cherry_picking_extended.conf2
-rw-r--r--src/exchange-lib/test_exchange_api_new.c99
-rw-r--r--src/exchange-lib/testing_api_cmd_deposit.c52
-rw-r--r--src/exchange-lib/testing_api_cmd_exec_wirewatch.c1
-rw-r--r--src/exchange-lib/testing_api_cmd_payback.c41
-rw-r--r--src/exchange-lib/testing_api_cmd_refund.c11
-rw-r--r--src/exchange-lib/testing_api_cmd_track.c64
-rw-r--r--src/exchange-lib/testing_api_cmd_wire.c129
-rw-r--r--src/exchange-lib/testing_api_helpers.c74
-rw-r--r--src/exchange-lib/testing_api_trait_json.c76
-rw-r--r--src/exchange-lib/testing_api_trait_string.c48
21 files changed, 694 insertions, 637 deletions
diff --git a/src/exchange-lib/Makefile.am b/src/exchange-lib/Makefile.am
index 5e0833b31..57c935088 100644
--- a/src/exchange-lib/Makefile.am
+++ b/src/exchange-lib/Makefile.am
@@ -61,6 +61,7 @@ libtalertesting_la_SOURCES = \
testing_api_trait_coin_priv.c \
testing_api_trait_denom_pub.c \
testing_api_trait_denom_sig.c \
+ testing_api_trait_json.c \
testing_api_trait_process.c \
testing_api_trait_reserve_priv.c \
testing_api_trait_number.c \
@@ -69,8 +70,8 @@ libtalertesting_la_SOURCES = \
testing_api_trait_key_peer.c \
testing_api_trait_wtid.c \
testing_api_trait_amount.c
-
libtalertesting_la_LIBADD = \
+ $(top_builddir)/src/wire/libtalerwire.la \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/util/libtalerutil.la \
$(top_builddir)/src/bank-lib/libtalerfakebank.la \
diff --git a/src/exchange-lib/exchange_api_deposit.c b/src/exchange-lib/exchange_api_deposit.c
index 76e3e4da9..7e499a434 100644
--- a/src/exchange-lib/exchange_api_deposit.c
+++ b/src/exchange-lib/exchange_api_deposit.c
@@ -416,8 +416,8 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange,
MAH_handle_is_ready (exchange));
/* initialize h_wire */
if (GNUNET_OK !=
- TALER_JSON_hash (wire_details,
- &h_wire))
+ TALER_JSON_wire_signature_hash (wire_details,
+ &h_wire))
{
GNUNET_break (0);
return NULL;
diff --git a/src/exchange-lib/exchange_api_reserve.c b/src/exchange-lib/exchange_api_reserve.c
index 72429d4e8..86a83fdb0 100644
--- a/src/exchange-lib/exchange_api_reserve.c
+++ b/src/exchange-lib/exchange_api_reserve.c
@@ -139,7 +139,7 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange,
if (0 == strcasecmp (type,
"DEPOSIT"))
{
- json_t *wire_account;
+ const char *wire_url;
void *wire_reference;
size_t wire_reference_size;
struct GNUNET_TIME_Absolute timestamp;
@@ -150,8 +150,8 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange,
&wire_reference_size),
GNUNET_JSON_spec_absolute_time ("timestamp",
&timestamp),
- GNUNET_JSON_spec_json ("sender_account_details",
- &wire_account),
+ GNUNET_JSON_spec_string ("sender_account_url",
+ &wire_url),
GNUNET_JSON_spec_end()
};
@@ -173,7 +173,7 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange,
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- rhistory[off].details.in_details.sender_account_details = wire_account;
+ rhistory[off].details.in_details.sender_url = GNUNET_strdup (wire_url);
rhistory[off].details.in_details.wire_reference = wire_reference;
rhistory[off].details.in_details.wire_reference_size = wire_reference_size;
rhistory[off].details.in_details.timestamp = timestamp;
@@ -361,8 +361,8 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange,
TALER_amount_hton (&rcc.closing_amount,
&amount);
if (GNUNET_OK !=
- TALER_JSON_hash (rhistory[off].details.close_details.receiver_account_details,
- &rcc.h_wire))
+ TALER_JSON_wire_signature_hash (rhistory[off].details.close_details.receiver_account_details,
+ &rcc.h_wire))
{
GNUNET_break (0);
return GNUNET_SYSERR;
@@ -440,8 +440,7 @@ free_rhistory (struct TALER_EXCHANGE_ReserveHistory *rhistory,
{
case TALER_EXCHANGE_RTT_DEPOSIT:
GNUNET_free_non_null (rhistory[i].details.in_details.wire_reference);
- if (NULL != rhistory[i].details.in_details.sender_account_details)
- json_decref (rhistory[i].details.in_details.sender_account_details);
+ GNUNET_free_non_null (rhistory[i].details.in_details.sender_url);
break;
case TALER_EXCHANGE_RTT_WITHDRAWAL:
break;
diff --git a/src/exchange-lib/exchange_api_wire.c b/src/exchange-lib/exchange_api_wire.c
index f1056fdd2..12789b2bc 100644
--- a/src/exchange-lib/exchange_api_wire.c
+++ b/src/exchange-lib/exchange_api_wire.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014, 2015, 2016 Inria and GNUnet e.V.
+ Copyright (C) 2014-2018 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
@@ -27,6 +27,7 @@
#include <gnunet/gnunet_curl_lib.h>
#include "taler_exchange_service.h"
#include "taler_json_lib.h"
+#include "taler_wire_lib.h"
#include "taler_signatures.h"
#include "taler_wire_plugin.h"
#include "exchange_api_handle.h"
@@ -63,66 +64,133 @@ struct TALER_EXCHANGE_WireHandle
*/
void *cb_cls;
+};
+
+
+/**
+ * List of wire fees by method.
+ */
+struct FeeMap
+{
/**
- * Set to the "methods" JSON array returned by the
- * /wire request.
+ * Next entry in list.
*/
- json_t *methods;
+ struct FeeMap *next;
/**
- * Current iteration offset in the @e methods array.
+ * Wire method this fee structure is for.
*/
- unsigned int methods_off;
+ char *method;
+ /**
+ * Array of wire fees, also linked list, but allocated
+ * only once.
+ */
+ struct TALER_EXCHANGE_WireAggregateFees *fee_list;
};
/**
- * Verify that the signature on the "200 OK" response
- * for /wire/METHOD from the exchange is valid.
+ * Frees @a fm.
*
- * @param wh wire handle with key material
- * @param method method to verify the reply for
- * @param json json reply with the signature
- * @return #GNUNET_SYSERR if @a json is invalid,
- * #GNUNET_NO if the method is unknown,
- * #GNUNET_OK if the json is valid
+ * @param fm memory to release
*/
-static int
-verify_wire_method_signature_ok (const struct TALER_EXCHANGE_WireHandle *wh,
- const char *method,
- const json_t *json)
+static void
+free_fees (struct FeeMap *fm)
{
- const struct TALER_EXCHANGE_Keys *key_state;
- struct TALER_WIRE_Plugin *plugin;
- char *lib_name;
- char *emsg;
- enum TALER_ErrorCode ec;
-
- key_state = TALER_EXCHANGE_get_keys (wh->exchange);
- (void) GNUNET_asprintf (&lib_name,
- "libtaler_plugin_wire_%s",
- method);
- plugin = GNUNET_PLUGIN_load (lib_name,
- NULL);
- if (NULL == plugin)
+ while (NULL != fm)
{
- GNUNET_free (lib_name);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Wire transfer method `%s' not supported\n",
- method);
- return GNUNET_NO;
+ struct FeeMap *fe = fm->next;
+
+ GNUNET_free (fm->fee_list);
+ GNUNET_free (fm->method);
+ GNUNET_free (fm);
+ fm = fe;
+ }
+}
+
+
+/**
+ * Parse wire @a fees and return map.
+ *
+ * @param fees json AggregateTransferFee to parse
+ * @return NULL on error
+ */
+static struct FeeMap *
+parse_fees (json_t *fees)
+{
+ struct FeeMap *fm = NULL;
+ const char *key;
+ json_t *fee_array;
+
+ json_object_foreach (fees, key, fee_array) {
+ struct FeeMap *fe = GNUNET_new (struct FeeMap);
+ int len;
+ unsigned int idx;
+ json_t *fee;
+
+ if (0 == (len = json_array_size (fee_array)))
+ {
+ GNUNET_break_op (0);
+ GNUNET_free (fe);
+ continue; /* skip */
+ }
+ fe->method = GNUNET_strdup (key);
+ fe->next = fm;
+ fe->fee_list = GNUNET_new_array (len,
+ struct TALER_EXCHANGE_WireAggregateFees);
+ fm = fe;
+ json_array_foreach (fee_array, idx, fee)
+ {
+ struct TALER_EXCHANGE_WireAggregateFees *wa = &fe->fee_list[idx];
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_fixed_auto ("sig",
+ &wa->master_sig),
+ TALER_JSON_spec_amount ("wire_fee",
+ &wa->wire_fee),
+ TALER_JSON_spec_amount ("closing_fee",
+ &wa->closing_fee),
+ GNUNET_JSON_spec_absolute_time ("start_date",
+ &wa->start_date),
+ GNUNET_JSON_spec_absolute_time ("end_date",
+ &wa->end_date),
+ GNUNET_JSON_spec_end()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (fee,
+ spec,
+ NULL,
+ NULL))
+ {
+ GNUNET_break_op (0);
+ free_fees (fm);
+ return NULL;
+ }
+ if (idx < len)
+ wa->next = &fe->fee_list[idx + 1];
+ }
}
- plugin->library_name = lib_name;
- ec = plugin->wire_validate (plugin->cls,
- json,
- &key_state->master_pub,
- &emsg);
- GNUNET_free_non_null (emsg);
- GNUNET_PLUGIN_unload (lib_name,
- plugin);
- GNUNET_free (lib_name);
- return (TALER_EC_NONE == ec) ? GNUNET_OK : GNUNET_SYSERR;
+ return fm;
+}
+
+
+/**
+ * Find fee by @a method.
+ *
+ * @param fm map to look in
+ * @param method key to look for
+ * @return NULL if fee is not specified in @a fm
+ */
+static const struct TALER_EXCHANGE_WireAggregateFees *
+lookup_fee (const struct FeeMap *fm,
+ const char *method)
+{
+ for (;NULL != fm; fm = fm->next)
+ if (0 == strcasecmp (fm->method,
+ method))
+ return fm->fee_list;
+ return NULL;
}
@@ -140,70 +208,131 @@ handle_wire_finished (void *cls,
const json_t *json)
{
struct TALER_EXCHANGE_WireHandle *wh = cls;
- json_t *keep = NULL;
+ enum TALER_ErrorCode ec;
wh->job = NULL;
+ ec = TALER_EC_NONE;
switch (response_code)
{
case 0:
break;
case MHD_HTTP_OK:
{
- const struct TALER_EXCHANGE_Keys *keys;
- const struct TALER_MasterPublicKeyP *master_pub;
- const char *key;
- json_t *method;
- int ret;
-
- /* We 'keep' methods that we support and that are well-formed;
- we fail (by setting response_code=0) if any method that we do
- support fails to verify. */
- keep = json_object ();
- json_object_foreach ((json_t *) json, key, method) {
- ret = verify_wire_method_signature_ok (wh,
- key,
- method);
- if (GNUNET_SYSERR == ret)
- {
- /* bogus reply */
- GNUNET_break_op (0);
- response_code = 0;
- }
- /* GNUNET_NO: not understood by us, simply skip! */
- if (GNUNET_OK == ret)
- {
- /* supported and valid, keep! */
- json_object_set (keep,
- key,
- method);
- }
- }
- /* check fees */
- keys = TALER_EXCHANGE_get_keys (wh->exchange);
- if (NULL == keys)
- master_pub = NULL;
- else
- master_pub = &keys->master_pub;
+ json_t *accounts;
+ json_t *fees;
+ int num_accounts;
+ struct FeeMap *fm;
+ const struct TALER_EXCHANGE_Keys *key_state;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_json ("accounts", &accounts),
+ GNUNET_JSON_spec_json ("fees", &fees),
+ GNUNET_JSON_spec_end()
+ };
+
if (GNUNET_OK !=
- TALER_EXCHANGE_wire_get_fees (master_pub,
- keep,
- NULL,
- NULL))
+ GNUNET_JSON_parse (json,
+ spec,
+ NULL, NULL))
{
/* bogus reply */
GNUNET_break_op (0);
response_code = 0;
+ ec = TALER_EC_SERVER_JSON_INVALID;
+ break;
}
- if (0 != response_code)
+ if (0 == (num_accounts = json_array_size (accounts)))
{
- /* all supported methods were valid, use 'keep' for 'json' */
+ /* bogus reply */
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ response_code = 0;
+ ec = TALER_EC_SERVER_JSON_INVALID;
break;
}
- /* some supported methods were invalid, release 'keep', preserve
- full 'json' for application-level error handling. */
- json_decref (keep);
- keep = NULL;
- }
+ if (NULL == (fm = parse_fees (fees)))
+ {
+ /* bogus reply */
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ response_code = 0;
+ ec = TALER_EC_SERVER_JSON_INVALID;
+ break;
+ }
+
+ key_state = TALER_EXCHANGE_get_keys (wh->exchange);
+ /* parse accounts */
+ {
+ struct TALER_EXCHANGE_WireAccount was[num_accounts];
+
+ for (unsigned int i=0;i<num_accounts;i++)
+ {
+ struct TALER_EXCHANGE_WireAccount *wa = &was[i];
+ json_t *account;
+ struct GNUNET_JSON_Specification spec_account[] = {
+ GNUNET_JSON_spec_string ("url", &wa->url),
+ GNUNET_JSON_spec_string ("salt", &wa->salt),
+ GNUNET_JSON_spec_fixed_auto ("master_sig", &wa->master_sig),
+ GNUNET_JSON_spec_end()
+ };
+ char *method;
+
+ account = json_array_get (accounts,
+ i);
+ if (GNUNET_OK !=
+ TALER_JSON_wire_signature_check (account,
+ &key_state->master_pub))
+ {
+ /* bogus reply */
+ GNUNET_break_op (0);
+ response_code = 0;
+ ec = TALER_EC_SERVER_SIGNATURE_INVALID;
+ break;
+ }
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (account,
+ spec_account,
+ NULL, NULL))
+ {
+ /* bogus reply */
+ GNUNET_break_op (0);
+ response_code = 0;
+ ec = TALER_EC_SERVER_JSON_INVALID;
+ break;
+ }
+ if (NULL == (method = TALER_WIRE_payto_get_method (wa->url)))
+ {
+ /* bogus reply */
+ GNUNET_break_op (0);
+ response_code = 0;
+ ec = TALER_EC_SERVER_JSON_INVALID;
+ break;
+ }
+ if (NULL == (wa->fees = lookup_fee (fm,
+ method)))
+ {
+ /* bogus reply */
+ GNUNET_break_op (0);
+ response_code = 0;
+ ec = TALER_EC_SERVER_JSON_INVALID;
+ GNUNET_free (method);
+ break;
+ }
+ GNUNET_free (method);
+ } /* end 'for all accounts */
+ if ( (0 != response_code) &&
+ (NULL != wh->cb) )
+ {
+ wh->cb (wh->cb_cls,
+ response_code,
+ TALER_EC_NONE,
+ num_accounts,
+ was);
+ wh->cb = NULL;
+ }
+ } /* end of 'parse accounts */
+ free_fees (fm);
+ GNUNET_JSON_parse_free (spec);
+ } /* end of MHD_HTTP_OK */
break;
case MHD_HTTP_BAD_REQUEST:
/* This should never happen, either us or the exchange is buggy
@@ -226,12 +355,12 @@ handle_wire_finished (void *cls,
response_code = 0;
break;
}
- wh->cb (wh->cb_cls,
- response_code,
- TALER_JSON_get_error_code (json),
- (NULL != keep) ? keep : json);
- if (NULL != keep)
- json_decref (keep);
+ if (NULL != wh->cb)
+ wh->cb (wh->cb_cls,
+ response_code,
+ (0 == response_code) ? ec : TALER_JSON_get_error_code (json),
+ 0,
+ NULL);
TALER_EXCHANGE_wire_cancel (wh);
}
@@ -306,157 +435,9 @@ TALER_EXCHANGE_wire_cancel (struct TALER_EXCHANGE_WireHandle *wh)
GNUNET_CURL_job_cancel (wh->job);
wh->job = NULL;
}
- if (NULL != wh->methods)
- {
- json_decref (wh->methods);
- wh->methods = NULL;
- }
GNUNET_free (wh->url);
GNUNET_free (wh);
}
-/**
- * Parse wire @a fee and store the result in @a af.
- *
- * @param[out] af where to write the result
- * @param fee json AggregateTransferFee to parse
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
- */
-static int
-parse_json_fees (struct TALER_EXCHANGE_WireAggregateFees *af,
- json_t *fee)
-{
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("sig",
- &af->master_sig),
- TALER_JSON_spec_amount ("wire_fee",
- &af->wire_fee),
- TALER_JSON_spec_amount ("closing_fee",
- &af->closing_fee),
- GNUNET_JSON_spec_absolute_time ("start_date",
- &af->start_date),
- GNUNET_JSON_spec_absolute_time ("end_date",
- &af->end_date),
- GNUNET_JSON_spec_end()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (fee,
- spec,
- NULL,
- NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Check the #TALER_SIGNATURE_MASTER_WIRE_FEES signature.
- *
- * @param af record to check
- * @param wire_method wire method to check against
- * @param master_pub expected signing key
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
- */
-static int
-check_sig (const struct TALER_EXCHANGE_WireAggregateFees *af,
- const char *wire_method,
- const struct TALER_MasterPublicKeyP *master_pub)
-{
- struct TALER_MasterWireFeePS wp;
-
- wp.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES);
- wp.purpose.size = htonl (sizeof (wp));
- GNUNET_CRYPTO_hash (wire_method,
- strlen (wire_method) + 1,
- &wp.h_wire_method);
- wp.start_date = GNUNET_TIME_absolute_hton (af->start_date);
- wp.end_date = GNUNET_TIME_absolute_hton (af->end_date);
- TALER_amount_hton (&wp.wire_fee,
- &af->wire_fee);
- TALER_amount_hton (&wp.closing_fee,
- &af->closing_fee);
- return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_FEES,
- &wp.purpose,
- &af->master_sig.eddsa_signature,
- &master_pub->eddsa_pub);
-}
-
-
-/**
- * Obtain information about wire fees encoded in @a obj
- * by wire method.
- *
- * @param master_pub public key to use to verify signatures, NULL to not verify
- * @param obj wire information as encoded in the #TALER_EXCHANGE_WireResultCallback
- * @param cb callback to invoke for the fees
- * @param cb_cls closure for @a cb
- * @return #GNUNET_OK in success, #GNUNET_SYSERR if @a obj is ill-formed
- */
-int
-TALER_EXCHANGE_wire_get_fees (const struct TALER_MasterPublicKeyP *master_pub,
- const json_t *obj,
- TALER_EXCHANGE_WireFeeCallback cb,
- void *cb_cls)
-{
- const char *wire_method;
- json_t *value;
-
- json_object_foreach (((json_t *) obj), wire_method, value)
- {
- json_t *fees;
- size_t num_fees;
-
- fees = json_object_get (value, "fees");
- if ( (NULL == fees) ||
- (! json_is_array (fees)) )
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- num_fees = json_array_size (fees);
- if (num_fees > 1024)
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- {
- struct TALER_EXCHANGE_WireAggregateFees af[num_fees + 1];
-
- for (size_t i=0;i<num_fees;i++)
- {
- af[i].next = &af[i+1];
- if (GNUNET_OK !=
- parse_json_fees (&af[i],
- json_array_get (fees,
- i)))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- if ( (NULL != master_pub) &&
- (GNUNET_OK !=
- check_sig (&af[i],
- wire_method,
- master_pub)) )
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- }
- af[num_fees - 1].next = NULL;
- if (NULL != cb)
- cb (cb_cls,
- wire_method,
- &af[0]);
- }
- }
- return GNUNET_OK;
-}
-
-
/* end of exchange_api_wire.c */
diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c
index fe3877790..7ca74a227 100644
--- a/src/exchange-lib/test_exchange_api.c
+++ b/src/exchange-lib/test_exchange_api.c
@@ -36,9 +36,12 @@
#define WIRE_TEST 1
/**
- * Is the configuration file is set to include wire format 'sepa'?
+ * Is the configuration file is set to include wire format 'ebics'?
+ * Requires that EBICS /history function is implemented, which it
+ * is currently not. Once it is, set ENABLE_CREDIT to YES in the
+ * configuration and then set this option to 1.
*/
-#define WIRE_SEPA 1
+#define WIRE_EBICS 0
/**
* Account number of the exchange at the bank.
@@ -1539,12 +1542,15 @@ find_pk (const struct TALER_EXCHANGE_Keys *keys,
}
+#if LEGACY
+/* Tests the *old* /wire API, the _modern_ testcase was adapted,
+ but little point in right now adapting the old testcase */
/**
* Function called with information about the wire fees
* for each wire method.
*
* @param cls closure
- * @param wire_method name of the wire method (i.e. "sepa")
+ * @param wire_method name of the wire method (i.e. "ebics")
* @param fees fee structure for this method
*/
static void
@@ -1556,9 +1562,9 @@ check_fee_cb (void *cls,
struct Command *cmd = &is->commands[is->ip];
struct TALER_Amount expected_amount;
- GNUNET_break ( (0 == strcasecmp ("test",
+ GNUNET_break ( (0 == strcasecmp ("x-taler-bank",
wire_method)) ||
- (0 == strcasecmp ("sepa",
+ (0 == strcasecmp ("ebics",
wire_method)) );
if (GNUNET_OK !=
TALER_string_to_amount (cmd->details.wire.expected_fee,
@@ -1582,6 +1588,7 @@ check_fee_cb (void *cls,
fees = fees->next;
}
}
+#endif
/**
@@ -1592,14 +1599,15 @@ check_fee_cb (void *cls,
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful 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 obj the received JSON reply, if successful this should be the wire
- * format details as provided by /wire.
+ * @param accounts_len length of the @a accounts array
+ * @param accounts list of wire accounts of the exchange, NULL on error
*/
static void
wire_cb (void *cls,
unsigned int http_status,
enum TALER_ErrorCode ec,
- const json_t *obj)
+ unsigned int accounts_len,
+ const struct TALER_EXCHANGE_WireAccount *accounts)
{
struct InterpreterState *is = cls;
struct Command *cmd = &is->commands[is->ip];
@@ -1611,7 +1619,9 @@ wire_cb (void *cls,
"Unexpected response code %u to command %s\n",
http_status,
cmd->label);
+#if LEGACY
json_dumpf (obj, stderr, 0);
+#endif
fail (is);
return;
}
@@ -1619,6 +1629,7 @@ wire_cb (void *cls,
{
case MHD_HTTP_OK:
{
+#if LEGACY
json_t *method;
method = json_object_get (obj,
@@ -1646,6 +1657,7 @@ wire_cb (void *cls,
fail (is);
return;
}
+#endif
}
break;
default:
@@ -1760,8 +1772,8 @@ wire_deposits_cb (void *cls,
JSON_REJECT_DUPLICATES,
NULL);
GNUNET_assert (GNUNET_OK ==
- TALER_JSON_hash (wire,
- &hw));
+ TALER_JSON_wire_signature_hash (wire,
+ &hw));
json_decref (wire);
if (0 != memcmp (&hw,
h_wire,
@@ -2331,13 +2343,15 @@ interpreter_run (void *cls)
{
struct TALER_DepositRequestPS dr;
- memset (&dr, 0, sizeof (dr));
+ memset (&dr,
+ 0,
+ sizeof (dr));
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
dr.h_contract_terms = h_contract_terms;
GNUNET_assert (GNUNET_OK ==
- TALER_JSON_hash (wire,
- &dr.h_wire));
+ TALER_JSON_wire_signature_hash (wire,
+ &dr.h_wire));
dr.timestamp = GNUNET_TIME_absolute_hton (timestamp);
dr.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline);
TALER_amount_hton (&dr.amount_with_fee,
@@ -2581,8 +2595,8 @@ interpreter_run (void *cls)
NULL);
GNUNET_assert (NULL != wire);
GNUNET_assert (GNUNET_OK ==
- TALER_JSON_hash (wire,
- &h_wire));
+ TALER_JSON_wire_signature_hash (wire,
+ &h_wire));
json_decref (wire);
contract_terms = json_loads (ref->details.deposit.contract_terms,
JSON_REJECT_DUPLICATES,
@@ -2640,7 +2654,6 @@ interpreter_run (void *cls)
"taler-exchange-wirewatch",
"taler-exchange-wirewatch",
"-c", "test_exchange_api.conf",
- "-t", "test", /* use Taler's bank/fakebank */
"-T", /* exit when done */
NULL);
if (NULL == cmd->details.run_wirewatch.wirewatch_proc)
@@ -3204,15 +3217,15 @@ run (void *cls)
.label = "wire-test",
/* expecting 'test' method in response */
.expected_response_code = MHD_HTTP_OK,
- .details.wire.format = "test",
+ .details.wire.format = "x-taler-bank",
.details.wire.expected_fee = "EUR:0.01" },
#endif
-#if WIRE_SEPA
+#if WIRE_EBICS
{ .oc = OC_WIRE,
.label = "wire-sepa",
- /* expecting 'sepa' method in response */
+ /* expecting 'ebics' method in response */
.expected_response_code = MHD_HTTP_OK,
- .details.wire.format = "sepa",
+ .details.wire.format = "ebics",
.details.wire.expected_fee = "EUR:0.01" },
#endif
/* *************** end of /wire testing ************** */
@@ -3252,7 +3265,7 @@ run (void *cls)
.expected_response_code = MHD_HTTP_OK,
.details.deposit.amount = "EUR:5",
.details.deposit.coin_ref = "withdraw-coin-1",
- .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_url\":\"http://localhost:8082/\", \"account_number\":42 }",
+ .details.deposit.wire_details = "{ \"url\":\"payto://x-taler-bank/localhost:8082/42\", \"salt\":\"my salt\" }",
.details.deposit.contract_terms = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":1 } ] }" },
/* Try to overdraw funds ... */
@@ -3268,7 +3281,7 @@ run (void *cls)
.expected_response_code = MHD_HTTP_FORBIDDEN,
.details.deposit.amount = "EUR:5",
.details.deposit.coin_ref = "withdraw-coin-1",
- .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_url\":\"http://localhost:8082/\", \"account_number\":43 }",
+ .details.deposit.wire_details = "{ \"url\":\"payto://x-taler-bank/localhost:8082/43\", \"salt\":\"my salt\" }",
.details.deposit.contract_terms = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":1 } ] }" },
/* Try to double-spend the 5 EUR coin at the same merchant (but different
transaction ID) */
@@ -3277,7 +3290,7 @@ run (void *cls)
.expected_response_code = MHD_HTTP_FORBIDDEN,
.details.deposit.amount = "EUR:5",
.details.deposit.coin_ref = "withdraw-coin-1",
- .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_url\":\"http://localhost:8082/\", \"account_number\":42 }",
+ .details.deposit.wire_details = "{ \"url\":\"payto://x-taler-bank/localhost:8082/42\", \"salt\":\"my salt\" }",
.details.deposit.contract_terms = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":1 } ] }" },
/* Try to double-spend the 5 EUR coin at the same merchant (but different
proposal) */
@@ -3286,7 +3299,7 @@ run (void *cls)
.expected_response_code = MHD_HTTP_FORBIDDEN,
.details.deposit.amount = "EUR:5",
.details.deposit.coin_ref = "withdraw-coin-1",
- .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_url\":\"http://localhost:8082/\", \"account_number\":42 }",
+ .details.deposit.wire_details = "{ \"url\":\"payto://x-taler-bank/localhost:8082/42\", \"salt\":\"my salt\" }",
.details.deposit.contract_terms = "{ \"items\":[{ \"name\":\"ice cream\", \"value\":2 } ] }" },
/* ***************** /refresh testing ******************** */
@@ -3316,7 +3329,7 @@ run (void *cls)
.expected_response_code = MHD_HTTP_OK,
.details.deposit.amount = "EUR:1",
.details.deposit.coin_ref = "refresh-withdraw-coin-1",
- .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_url\":\"http://localhost:8082/\", \"account_number\":42 }",
+ .details.deposit.wire_details = "{ \"url\":\"payto://x-taler-bank/localhost:8082/42\", \"salt\":\"my salt\" }",
.details.deposit.contract_terms = "{ \"items\" : [ { \"name\":\"ice cream\", \"value\":\"EUR:1\" } ] }" },
/* Melt the rest of the coin's value (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */
@@ -3357,7 +3370,7 @@ run (void *cls)
.details.deposit.amount = "EUR:1",
.details.deposit.coin_ref = "refresh-reveal-1-idempotency",
.details.deposit.coin_idx = 0,
- .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_url\":\"http://localhost:8082/\", \"account_number\":42 }",
+ .details.deposit.wire_details = "{ \"url\":\"payto://x-taler-bank/localhost:8082/42\", \"salt\":\"my salt\" }",
.details.deposit.contract_terms = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":3 } ] }" },
/* Test successfully spending coins from the refresh operation:
@@ -3368,7 +3381,7 @@ run (void *cls)
.details.deposit.amount = "EUR:0.1",
.details.deposit.coin_ref = "refresh-reveal-1",
.details.deposit.coin_idx = 4,
- .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_url\":\"http://localhost:8082/\", \"account_number\":43 }",
+ .details.deposit.wire_details = "{ \"url\":\"payto://x-taler-bank/localhost:8082/43\", \"salt\":\"my salt\" }",
.details.deposit.contract_terms = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":3 } ] }" },
/* Test running a failing melt operation (same operation again must fail) */
@@ -3507,7 +3520,7 @@ run (void *cls)
.expected_response_code = MHD_HTTP_OK,
.details.deposit.amount = "EUR:5",
.details.deposit.coin_ref = "withdraw-coin-r1",
- .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_url\":\"http://localhost:8082/\", \"account_number\":42 }",
+ .details.deposit.wire_details = "{ \"url\":\"payto://x-taler-bank/localhost:8082/42\", \"salt\":\"my salt\" }",
.details.deposit.contract_terms = "{ \"items\" : [ { \"name\":\"ice cream\", \"value\":\"EUR:5\" } ] }",
.details.deposit.refund_deadline = { 60LL * 1000 * 1000 } /* 60 s */,
},
@@ -3539,7 +3552,7 @@ run (void *cls)
.expected_response_code = MHD_HTTP_OK,
.details.deposit.amount = "EUR:4.99",
.details.deposit.coin_ref = "withdraw-coin-r1",
- .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_url\":\"http://localhost:8082/\", \"account_number\":42 }",
+ .details.deposit.wire_details = "{ \"url\":\"payto://x-taler-bank/localhost:8082/42\", \"salt\":\"my salt\" }",
.details.deposit.contract_terms = "{ \"items\" : [ { \"name\":\"more ice cream\", \"value\":\"EUR:5\" } ] }",
},
/* Run transfers. This will do the transfer as refund deadline was 0 */
@@ -3591,9 +3604,9 @@ run (void *cls)
.expected_response_code = MHD_HTTP_OK,
.details.deposit.amount = "EUR:5",
.details.deposit.coin_ref = "withdraw-coin-rb",
- .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_url\":\"http://localhost:8082/\", \"account_number\":42 }",
.details.deposit.contract_terms = "{ \"items\" : [ { \"name\":\"ice cream\", \"value\":\"EUR:5\" } ] }",
.details.deposit.refund_deadline = { 0 },
+ .details.deposit.wire_details = "{ \"url\":\"payto://x-taler-bank/localhost:8082/42\", \"salt\":\"my salt\" }"
},
{ .oc = OC_CHECK_BANK_TRANSFER,
.label = "check_bank_transfer-aai-3b",
@@ -3695,7 +3708,7 @@ run (void *cls)
.expected_response_code = MHD_HTTP_OK,
.details.deposit.amount = "EUR:0.5",
.details.deposit.coin_ref = "payback-withdraw-coin-2a",
- .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_url\":\"http://localhost:8082/\", \"account_number\":42 }",
+ .details.deposit.wire_details = "{ \"url\":\"payto://x-taler-bank/localhost:8082/42\", \"salt\":\"my salt\" }",
.details.deposit.contract_terms = "{ \"items\": [ { \"name\":\"more ice cream\", \"value\":1 } ] }" },
{ .oc = OC_REVOKE,
.label = "revoke-2",
@@ -3716,7 +3729,7 @@ run (void *cls)
.expected_response_code = MHD_HTTP_NOT_FOUND,
.details.deposit.amount = "EUR:1",
.details.deposit.coin_ref = "payback-withdraw-coin-2b",
- .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_url\":\"http://localhost:8082/\", \"account_number\":42 }",
+ .details.deposit.wire_details = "{ \"url\":\"payto://x-taler-bank/localhost:8082/42\", \"salt\":\"my salt\" }",
.details.deposit.contract_terms = "{ \"items\": [ { \"name\":\"more ice cream\", \"value\":1 } ] }" },
/* Test deposit fails after payback, with proof in payback */
@@ -3727,7 +3740,7 @@ run (void *cls)
.expected_response_code = MHD_HTTP_NOT_FOUND,
.details.deposit.amount = "EUR:0.5",
.details.deposit.coin_ref = "payback-withdraw-coin-2a",
- .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_url\":\"http://localhost:8082/\", \"account_number\":42 }",
+ .details.deposit.wire_details = "{ \"url\":\"payto://x-taler-bank/localhost:8082/42\", \"salt\":\"my salt\" }",
.details.deposit.contract_terms = "{ \"items\": [ { \"name\":\"extra ice cream\", \"value\":1 } ] }" },
@@ -3999,6 +4012,7 @@ main (int argc,
}
while (0 != system ("wget -q -t 1 -T 1 http://127.0.0.1:8081/keys -o /dev/null -O /dev/null"));
fprintf (stderr, "\n");
+
result = GNUNET_NO;
sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO);
GNUNET_assert (NULL != sigpipe);
diff --git a/src/exchange-lib/test_exchange_api.conf b/src/exchange-lib/test_exchange_api.conf
index 7d8761f94..8c8bd7ef5 100644
--- a/src/exchange-lib/test_exchange_api.conf
+++ b/src/exchange-lib/test_exchange_api.conf
@@ -9,7 +9,6 @@ TALER_TEST_HOME = test_exchange_api_home/
CURRENCY = EUR
[exchange]
-
# HTTP port the exchange listens to
PORT = 8081
@@ -23,23 +22,58 @@ DB = postgres
# exchange (or the twister) is actually listening.
BASE_URL = "http://localhost:8081/"
+# Keep it short so the test runs fast.
+LOOKAHEAD_SIGN = 12 h
+
[exchangedb-postgres]
-DB_CONN_STR = "postgres:///talercheck"
+CONFIG = "postgres:///talercheck"
[auditordb-postgres]
-DB_CONN_STR = "postgres:///talercheck"
+CONFIG = "postgres:///talercheck"
+
+# Sections starting with "account-" configure the bank accounts
+# of the exchange. The "URL" specifies the account in
+# payto://-format, while the WIRE_JSON specifies the
+# (possibly offline) signed version to be returned in /wire.
+# WIRE_JSON is optional, as not all accounts must be
+# advertised in /wire.
+[account-1]
+# What is the URL of our account?
+URL = "payto://sepa/CH9300762011623852957"
+# This is the response we give out for the /wire request. It provides
+# wallets with the bank information for transfers to the exchange.
+WIRE_RESPONSE = ${TALER_CONFIG_HOME}/account-1.json
+# Which wire plugin should we used to access the account?
+PLUGIN = ebics
-[exchange-wire-sepa]
-# Enable 'sepa' to test SEPA-specific routines.
-ENABLE = YES
+# ENABLE_CREDIT = YES
+
+[account-2]
+# What is the bank account (with the "Taler Bank" demo system)?
+URL = "payto://x-taler-bank/localhost:8082/2"
# This is the response we give out for the /wire request. It provides
# wallets with the bank information for transfers to the exchange.
-SEPA_RESPONSE_FILE = ${TALER_CONFIG_HOME}/sepa.json
+WIRE_RESPONSE = ${TALER_CONFIG_HOME}/account-2.json
+
+# Which wire plugin should we used to access the account?
+PLUGIN = taler_bank
+
+# Authentication information for basic authentication
+TALER_BANK_AUTH_METHOD = "basic"
+USERNAME = user
+PASSWORD = pass
+
+ENABLE_DEBIT = YES
+
+ENABLE_CREDIT = YES
+
+# Sections starting with "fee-" configure the wire fee for the
+# respective wire method.
+[fees-sepa]
# Fees for the forseeable future...
# If you see this after 2017, update to match the next 10 years...
-WIRE-FEE-2017 = EUR:0.01
WIRE-FEE-2018 = EUR:0.01
WIRE-FEE-2019 = EUR:0.01
WIRE-FEE-2020 = EUR:0.01
@@ -49,8 +83,8 @@ WIRE-FEE-2023 = EUR:0.01
WIRE-FEE-2024 = EUR:0.01
WIRE-FEE-2025 = EUR:0.01
WIRE-FEE-2026 = EUR:0.01
+WIRE-FEE-2027 = EUR:0.01
-CLOSING-FEE-2017 = EUR:0.01
CLOSING-FEE-2018 = EUR:0.01
CLOSING-FEE-2019 = EUR:0.01
CLOSING-FEE-2020 = EUR:0.01
@@ -60,18 +94,11 @@ CLOSING-FEE-2023 = EUR:0.01
CLOSING-FEE-2024 = EUR:0.01
CLOSING-FEE-2025 = EUR:0.01
CLOSING-FEE-2026 = EUR:0.01
+CLOSING-FEE-2027 = EUR:0.01
-[exchange_keys]
-# Keep it short so the test runs fast.
-LOOKAHEAD_SIGN = 12 h
-
-[exchange-wire-test]
-# Enable 'test' for testing of the actual coin operations.
-ENABLE = YES
-
+[fees-x-taler-bank]
# Fees for the forseeable future...
# If you see this after 2017, update to match the next 10 years...
-WIRE-FEE-2017 = EUR:0.01
WIRE-FEE-2018 = EUR:0.01
WIRE-FEE-2019 = EUR:0.01
WIRE-FEE-2020 = EUR:0.01
@@ -81,8 +108,8 @@ WIRE-FEE-2023 = EUR:0.01
WIRE-FEE-2024 = EUR:0.01
WIRE-FEE-2025 = EUR:0.01
WIRE-FEE-2026 = EUR:0.01
+WIRE-FEE-2027 = EUR:0.01
-CLOSING-FEE-2017 = EUR:0.01
CLOSING-FEE-2018 = EUR:0.01
CLOSING-FEE-2019 = EUR:0.01
CLOSING-FEE-2020 = EUR:0.01
@@ -92,17 +119,10 @@ CLOSING-FEE-2023 = EUR:0.01
CLOSING-FEE-2024 = EUR:0.01
CLOSING-FEE-2025 = EUR:0.01
CLOSING-FEE-2026 = EUR:0.01
+CLOSING-FEE-2027 = EUR:0.01
-# This is the response we give out for the /wire request. It provides
-# wallets with the bank information for transfers to the exchange.
-TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/test.json
-
-# What is the main website of the bank?
-BANK_URL = "http://localhost:8082/"
-# From which account at the 'bank' should outgoing wire transfers be made?
-BANK_ACCOUNT_NUMBER = 2
-
-
+# Sections starting with "coin_" specify which denominations
+# the exchange should support (and their respective fee structure)
[coin_eur_ct_1]
value = EUR:0.01
duration_overlap = 5 minutes
diff --git a/src/exchange-lib/test_exchange_api_home/.config/taler/account-1.json b/src/exchange-lib/test_exchange_api_home/.config/taler/account-1.json
new file mode 100644
index 000000000..48093f2aa
--- /dev/null
+++ b/src/exchange-lib/test_exchange_api_home/.config/taler/account-1.json
@@ -0,0 +1,5 @@
+{
+ "url": "payto://sepa/CH9300762011623852957",
+ "salt": "N83T9J9202WCC8TQFDMJDWEGZNBEKA33C1ZM241VNYH88RZNTHPW509Y1M2YF7Y098R8VRESWQ05H03BK1SPAZCWE54KARDCKT5N8AG",
+ "master_sig": "D4V5GJ998YK7D6N0N56AD0J6MZNFEW6MRZT2CFPVQ5ME3NMQ59AA2007CXYESSFGRN70CNCFM06858QSSENCWTZM8VHEJ93YQ20ZJ1R"
+} \ No newline at end of file
diff --git a/src/exchange-lib/test_exchange_api_home/.config/taler/account-2.json b/src/exchange-lib/test_exchange_api_home/.config/taler/account-2.json
new file mode 100644
index 000000000..85d80de56
--- /dev/null
+++ b/src/exchange-lib/test_exchange_api_home/.config/taler/account-2.json
@@ -0,0 +1,5 @@
+{
+ "url": "payto://x-taler-bank/localhost:8082/2",
+ "salt": "TMXB995ZZVKA02AG4074X3C6XX0BFTHY8XK76EF4BSG5XVDF069FEBN4TCKW9GS7NKZH409GKAVHMQPA3T361MC6VM7J268V3GBH42R",
+ "master_sig": "CK7BGHKYVAT7DMVCN00DQ0761NCTJVESZT69049BCF3SKNJKVHXXEQ5X6FH2HFGHCJ18YA1MGHBD8RRG4W3G4KJWQJDY2CGPGTHDJ2G"
+} \ No newline at end of file
diff --git a/src/exchange-lib/test_exchange_api_home/.config/taler/x-taler-bank.json b/src/exchange-lib/test_exchange_api_home/.config/taler/x-taler-bank.json
new file mode 100644
index 000000000..9445f048e
--- /dev/null
+++ b/src/exchange-lib/test_exchange_api_home/.config/taler/x-taler-bank.json
@@ -0,0 +1,5 @@
+{
+ "url": "payto://x-taler-bank/http://localhost:8082/2",
+ "salt": "WGRD0W7YKD8ZAN960B0JBRARRY0K5FQ4920Q3DJBTYH4GY7W0XNAX1F04R5B1E0RWH1NFG08TM8K1517WNCXTJM9KMH4913Q5XPK0N8",
+ "master_sig": "J4N0KP64MGNEQX9HST9TDWK67152MSHHM9CTZH8GSMKD607BXSAF209AQYDKYT6QJP0NQXYXC1JMM9Z405DJHGV75JFMWP4G6WB6A00"
+} \ No newline at end of file
diff --git a/src/exchange-lib/test_exchange_api_keys_cherry_picking.conf b/src/exchange-lib/test_exchange_api_keys_cherry_picking.conf
index 38b952824..7193bf11e 100644
--- a/src/exchange-lib/test_exchange_api_keys_cherry_picking.conf
+++ b/src/exchange-lib/test_exchange_api_keys_cherry_picking.conf
@@ -23,20 +23,53 @@ DB = postgres
# exchange (or the twister) is actually listening.
BASE_URL = "http://localhost:8081/"
+# Keep it short so we can prolong later!
+LOOKAHEAD_SIGN = 60 s
+
+
[exchangedb-postgres]
-DB_CONN_STR = "postgres:///talercheck"
+CONFIG = "postgres:///talercheck"
[auditordb-postgres]
-DB_CONN_STR = "postgres:///talercheck"
+CONFIG = "postgres:///talercheck"
+
+
+[account-1]
+# This is the response we give out for the /wire request. It provides
+# wallets with the bank information for transfers to the exchange.
+WIRE_RESPONSE = ${TALER_CONFIG_HOME}/iban.json
+
+# What is the URL of our bank account? Must match WIRE_RESPONSE above!
+URL = payto://sepa/FIXME
-[exchange-wire-sepa]
-# Enable 'sepa' to test SEPA-specific routines.
-ENABLE = YES
+# Which plugin implements access for this account?
+PLUGIN = "ebics"
+
+[account-2]
# This is the response we give out for the /wire request. It provides
# wallets with the bank information for transfers to the exchange.
-SEPA_RESPONSE_FILE = ${TALER_CONFIG_HOME}/sepa.json
+WIRE_RESPONSE = ${TALER_CONFIG_HOME}/x-taler-bank.json
+
+# What is the URL of our bank account? Must match WIRE_RESPONSE above!
+URL = payto://x-taler-bank/http://localhost:8082/2
+
+# Which plugin implements access for this account?
+PLUGIN = "taler_bank"
+
+# Authentication information for basic authentication
+TALER_BANK_AUTH_METHOD = "basic"
+USERNAME = user
+PASSWORD = pass
+
+ENABLE_DEBIT = YES
+ENABLE_CREDIT = YES
+
+
+
+
+[fees-x-taler-bank]
# Fees for the forseeable future...
# If you see this after 2017, update to match the next 10 years...
WIRE-FEE-2017 = EUR:0.01
@@ -61,14 +94,7 @@ CLOSING-FEE-2024 = EUR:0.01
CLOSING-FEE-2025 = EUR:0.01
CLOSING-FEE-2026 = EUR:0.01
-[exchange_keys]
-# Keep it short so we can prolong later!
-LOOKAHEAD_SIGN = 60 s
-
-[exchange-wire-test]
-# Enable 'test' for testing of the actual coin operations.
-ENABLE = YES
-
+[fees-sepa]
# Fees for the forseeable future...
# If you see this after 2017, update to match the next 10 years...
WIRE-FEE-2017 = EUR:0.01
@@ -93,16 +119,6 @@ CLOSING-FEE-2024 = EUR:0.01
CLOSING-FEE-2025 = EUR:0.01
CLOSING-FEE-2026 = EUR:0.01
-# This is the response we give out for the /wire request. It provides
-# wallets with the bank information for transfers to the exchange.
-TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/test.json
-
-# What is the main website of the bank?
-BANK_URL = "http://localhost:8082/"
-# From which account at the 'bank' should outgoing wire transfers be made?
-BANK_ACCOUNT_NUMBER = 2
-
-
[coin_eur_ct_1]
value = EUR:0.01
duration_overlap = 5 s
diff --git a/src/exchange-lib/test_exchange_api_keys_cherry_picking_extended.conf b/src/exchange-lib/test_exchange_api_keys_cherry_picking_extended.conf
index 3becf3d68..29290c99c 100644
--- a/src/exchange-lib/test_exchange_api_keys_cherry_picking_extended.conf
+++ b/src/exchange-lib/test_exchange_api_keys_cherry_picking_extended.conf
@@ -1,5 +1,5 @@
@INLINE@ test_exchange_api_keys_cherry_picking.conf
-[exchange_keys]
+[exchange]
# Lengthen over original value (60 s)
LOOKAHEAD_SIGN = 100 s
diff --git a/src/exchange-lib/test_exchange_api_new.c b/src/exchange-lib/test_exchange_api_new.c
index c3e1ce85e..a33f8d014 100644
--- a/src/exchange-lib/test_exchange_api_new.c
+++ b/src/exchange-lib/test_exchange_api_new.c
@@ -43,6 +43,14 @@
#define CONFIG_FILE "test_exchange_api.conf"
/**
+ * Is the configuration file is set to include wire format 'ebics'?
+ * Requires that EBICS /history function is implemented, which it
+ * is currently not. Once it is, set ENABLE_CREDIT to YES in the
+ * configuration and then set this option to 1.
+ */
+#define WIRE_EBICS 0
+
+/**
* URL of the fakebank. Obtained from CONFIG_FILE's
* "exchange-wire-test:BANK_URI" option.
*/
@@ -145,23 +153,23 @@ run (void *cls,
CMD_EXEC_WIREWATCH ("wirewatch-1"),
/**
- * Check if 'test' wire method is offered by the exchange.
+ * Check if 'x-taler-bank' wire method is offered by the exchange.
*/
- TALER_TESTING_cmd_wire ("wire-test-1",
+ TALER_TESTING_cmd_wire ("wire-taler-bank-1",
is->exchange,
- "test",
+ "x-taler-bank",
NULL,
MHD_HTTP_OK),
-
+#if WIRE_EBICS
/**
- * Check if 'sepa' wire method is offered by the exchange.
+ * Check if 'ebics' wire method is offered by the exchange.
*/
TALER_TESTING_cmd_wire ("wire-sepa-1",
is->exchange,
- "sepa",
+ "ebics",
NULL,
MHD_HTTP_OK),
-
+#endif
/****** End of "wire" testing ******/
/****** Start of withdraw and spend testing ******/
@@ -188,9 +196,8 @@ run (void *cls,
*/
TALER_TESTING_cmd_deposit
("deposit-simple", is->exchange, "withdraw-coin-1", 0,
- TALER_TESTING_make_wire_details
- ("{ \"type\":\"test\",\"account_number\":42}",
- fakebank_url),
+ TALER_TESTING_make_wire_details (42,
+ fakebank_url),
"{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
GNUNET_TIME_UNIT_ZERO, "EUR:5", MHD_HTTP_OK),
@@ -208,9 +215,8 @@ run (void *cls,
*/
TALER_TESTING_cmd_deposit
("deposit-double-1", is->exchange, "withdraw-coin-1", 0,
- TALER_TESTING_make_wire_details
- ("{\"type\":\"test\",\"account_number\":43}",
- fakebank_url),
+ TALER_TESTING_make_wire_details (43,
+ fakebank_url),
"{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
GNUNET_TIME_UNIT_ZERO, "EUR:5", MHD_HTTP_FORBIDDEN),
@@ -225,9 +231,8 @@ run (void *cls,
*/
TALER_TESTING_cmd_deposit
("deposit-double-1", is->exchange, "withdraw-coin-1", 0,
- TALER_TESTING_make_wire_details
- ("{ \"type\":\"test\", \"account_number\":43}",
- fakebank_url),
+ TALER_TESTING_make_wire_details (43,
+ fakebank_url),
"{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
GNUNET_TIME_UNIT_ZERO, "EUR:5", MHD_HTTP_FORBIDDEN),
@@ -236,12 +241,11 @@ run (void *cls,
*/
TALER_TESTING_cmd_deposit
("deposit-double-2", is->exchange, "withdraw-coin-1", 0,
- TALER_TESTING_make_wire_details
- ("{ \"type\":\"test\", \"account_number\":43}",
- fakebank_url),
+ TALER_TESTING_make_wire_details (43,
+ fakebank_url),
"{\"items\":[{\"name\":\"ice cream\",\"value\":2}]}",
GNUNET_TIME_UNIT_ZERO, "EUR:5", MHD_HTTP_FORBIDDEN),
-
+
/****** End of withdraw and spend testing ******/
/****** Start of refresh testing ******/
@@ -254,7 +258,7 @@ run (void *cls,
*/
CMD_TRANSFER_TO_EXCHANGE ("refresh-create-reserve-1",
"EUR:5.01"),
-
+
/**
* Make previous command effective.
*/
@@ -277,9 +281,8 @@ run (void *cls,
TALER_TESTING_cmd_deposit
("refresh-deposit-partial", is->exchange,
"refresh-withdraw-coin-1", 0,
- TALER_TESTING_make_wire_details
- ("{ \"type\":\"test\",\"account_number\":42}",
- fakebank_url),
+ TALER_TESTING_make_wire_details (42,
+ fakebank_url),
"{\"items\":[{\"name\":\"ice cream\",\
\"value\":\"EUR:1\"}]}",
GNUNET_TIME_UNIT_ZERO, "EUR:1", MHD_HTTP_OK),
@@ -297,7 +300,7 @@ run (void *cls,
TALER_TESTING_cmd_refresh_reveal
("refresh-reveal-1", is->exchange,
"refresh-melt-1", MHD_HTTP_OK),
-
+
/**
* Do it again to check idempotency
*/
@@ -318,9 +321,8 @@ run (void *cls,
TALER_TESTING_cmd_deposit
("refresh-deposit-refreshed-1a", is->exchange,
"refresh-reveal-1-idempotency", 0,
- TALER_TESTING_make_wire_details
- ("{ \"type\":\"test\",\"account_number\":42}",
- fakebank_url),
+ TALER_TESTING_make_wire_details (42,
+ fakebank_url),
"{\"items\":[{\"name\":\"ice cream\",\
\"value\":3}]}",
GNUNET_TIME_UNIT_ZERO, "EUR:1", MHD_HTTP_OK),
@@ -331,9 +333,8 @@ run (void *cls,
TALER_TESTING_cmd_deposit
("refresh-deposit-refreshed-1b", is->exchange,
"refresh-reveal-1", 4,
- TALER_TESTING_make_wire_details
- ("{ \"type\":\"test\",\"account_number\":43}",
- fakebank_url),
+ TALER_TESTING_make_wire_details (43,
+ fakebank_url),
"{\"items\":[{\"name\":\"ice cream\",\
\"value\":3}]}",
GNUNET_TIME_UNIT_ZERO, "EUR:0.1", MHD_HTTP_OK),
@@ -463,9 +464,8 @@ run (void *cls,
*/
TALER_TESTING_cmd_deposit
("deposit-refund-1", is->exchange, "withdraw-coin-r1", 0,
- TALER_TESTING_make_wire_details
- ("{ \"type\":\"test\", \"account_number\":42}",
- fakebank_url),
+ TALER_TESTING_make_wire_details (42,
+ fakebank_url),
"{\"items\":[{\"name\":\"ice cream\","
"\"value\":\"EUR:5\"}]}",
GNUNET_TIME_UNIT_MINUTES, "EUR:5", MHD_HTTP_OK),
@@ -502,9 +502,8 @@ run (void *cls,
* 1 ct deposit fee) */
TALER_TESTING_cmd_deposit
("deposit-refund-2", is->exchange, "withdraw-coin-r1", 0,
- TALER_TESTING_make_wire_details
- ("{ \"type\":\"test\", \"account_number\":42}",
- fakebank_url),
+ TALER_TESTING_make_wire_details (42,
+ fakebank_url),
"{\"items\":[{\"name\":\"more ice cream\","
"\"value\":\"EUR:5\"}]}",
GNUNET_TIME_UNIT_ZERO, "EUR:4.99", MHD_HTTP_OK),
@@ -555,9 +554,8 @@ run (void *cls,
TALER_TESTING_cmd_deposit
("deposit-refund-1b", is->exchange, "withdraw-coin-rb", 0,
- TALER_TESTING_make_wire_details
- ("{ \"type\":\"test\", \"account_number\":42}",
- fakebank_url),
+ TALER_TESTING_make_wire_details (42,
+ fakebank_url),
"{\"items\":[{\"name\":\"ice cream\","
"\"value\":\"EUR:5\"}]}",
GNUNET_TIME_UNIT_ZERO, "EUR:5", MHD_HTTP_OK),
@@ -602,7 +600,7 @@ run (void *cls,
is->exchange,
"payback-create-reserve-1",
"EUR:5",
- MHD_HTTP_OK),
+ MHD_HTTP_OK),
TALER_TESTING_cmd_revoke ("revoke-1", MHD_HTTP_OK,
"payback-withdraw-coin-1",
@@ -648,9 +646,8 @@ run (void *cls,
TALER_TESTING_cmd_deposit
("payback-deposit-partial", is->exchange,
"payback-withdraw-coin-2a", 0,
- TALER_TESTING_make_wire_details
- ("{ \"type\":\"test\",\"account_number\":42}",
- fakebank_url),
+ TALER_TESTING_make_wire_details (42,
+ fakebank_url),
"{\"items\":[{\"name\":\"more ice cream\",\"value\":1}]}",
GNUNET_TIME_UNIT_ZERO, "EUR:0.5", MHD_HTTP_OK),
@@ -670,9 +667,8 @@ run (void *cls,
TALER_TESTING_cmd_deposit
("payback-deposit-revoked", is->exchange,
"payback-withdraw-coin-2b", 0,
- TALER_TESTING_make_wire_details
- ("{ \"type\":\"test\",\"account_number\":42}",
- fakebank_url),
+ TALER_TESTING_make_wire_details (42,
+ fakebank_url),
"{\"items\":[{\"name\":\"more ice cream\",\"value\":1}]}",
GNUNET_TIME_UNIT_ZERO, "EUR:1", MHD_HTTP_NOT_FOUND),
@@ -685,9 +681,8 @@ run (void *cls,
TALER_TESTING_cmd_deposit
("payback-deposit-partial-after-payback", is->exchange,
"payback-withdraw-coin-2a", 0,
- TALER_TESTING_make_wire_details
- ("{ \"type\":\"test\",\"account_number\":42}",
- fakebank_url),
+ TALER_TESTING_make_wire_details (42,
+ fakebank_url),
"{\"items\":[{\"name\":\"extra ice cream\",\"value\":1}]}",
GNUNET_TIME_UNIT_ZERO, "EUR:0.5", MHD_HTTP_NOT_FOUND),
@@ -740,6 +735,7 @@ run (void *cls,
fakebank_url);
}
+
int
main (int argc,
char * const *argv)
@@ -753,7 +749,8 @@ main (int argc,
if (NULL == (fakebank_url
/* Check fakebank port is available and config cares
* about bank url. */
- = TALER_TESTING_prepare_fakebank (CONFIG_FILE)))
+ = TALER_TESTING_prepare_fakebank (CONFIG_FILE,
+ "account-2")))
return 77;
TALER_TESTING_cleanup_files (CONFIG_FILE);
/* @helpers. Run keyup, create tables, ... Note: it
diff --git a/src/exchange-lib/testing_api_cmd_deposit.c b/src/exchange-lib/testing_api_cmd_deposit.c
index 6f66e8ad0..5854bf8ba 100644
--- a/src/exchange-lib/testing_api_cmd_deposit.c
+++ b/src/exchange-lib/testing_api_cmd_deposit.c
@@ -50,9 +50,9 @@ struct DepositState
unsigned int coin_index;
/**
- * JSON string describing the merchant's "wire details".
+ * payto://-URL of the merchant's bank account.
*/
- char *wire_details;
+ json_t *wire_details;
/**
* JSON string describing what a proposal is about.
@@ -126,6 +126,7 @@ deposit_cb (void *cls,
TALER_TESTING_interpreter_next (ds->is);
}
+
/**
* Run the command.
*
@@ -133,7 +134,7 @@ deposit_cb (void *cls,
* @param cmd the command to execute, a /wire one.
* @param i the interpreter state.
*/
-void
+static void
deposit_run (void *cls,
const struct TALER_TESTING_Command *cmd,
struct TALER_TESTING_Interpreter *is)
@@ -153,7 +154,6 @@ deposit_run (void *cls,
struct TALER_MerchantPublicKeyP merchant_pub;
struct GNUNET_HashCode h_contract_terms;
json_t *contract_terms;
- json_t *wire;
struct TALER_Amount amount;
ds->is = is;
@@ -166,7 +166,7 @@ deposit_run (void *cls,
if (NULL == coin_cmd)
{
GNUNET_break (0);
- TALER_TESTING_interpreter_fail (is);
+ TALER_TESTING_interpreter_fail (is);
return;
}
@@ -213,21 +213,6 @@ deposit_run (void *cls,
TALER_JSON_hash (contract_terms,
&h_contract_terms));
json_decref (contract_terms);
-
- wire = json_loads (ds->wire_details,
- JSON_REJECT_DUPLICATES,
- NULL);
- if (NULL == wire)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to parse wire details `%s' at %u/%s\n",
- ds->wire_details,
- is->ip,
- this_cmd->label);
- TALER_TESTING_interpreter_fail (is);
- return;
- }
-
GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
&coin_pub.eddsa_pub);
@@ -267,8 +252,9 @@ deposit_run (void *cls,
dr.purpose.purpose = htonl
(TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
dr.h_contract_terms = h_contract_terms;
- GNUNET_assert (GNUNET_OK == TALER_JSON_hash
- (wire, &dr.h_wire));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_JSON_wire_signature_hash (ds->wire_details,
+ &dr.h_wire));
dr.timestamp = GNUNET_TIME_absolute_hton (timestamp);
dr.refund_deadline = GNUNET_TIME_absolute_hton
(refund_deadline);
@@ -286,7 +272,7 @@ deposit_run (void *cls,
(ds->exchange,
&amount,
wire_deadline,
- wire,
+ ds->wire_details,
&h_contract_terms,
&coin_pub,
denom_pub_sig,
@@ -301,21 +287,20 @@ deposit_run (void *cls,
if (NULL == ds->dh)
{
GNUNET_break (0);
- json_decref (wire);
TALER_TESTING_interpreter_fail (is);
return;
}
- json_decref (wire);
return;
}
+
/**
* Cleanup the state.
*
* @param cls closure, typically a #struct WireState.
* @param cmd the command which is being cleaned up.
*/
-void
+static void
deposit_cleanup (void *cls,
const struct TALER_TESTING_Command *cmd)
{
@@ -331,10 +316,11 @@ deposit_cleanup (void *cls,
ds->dh = NULL;
}
- GNUNET_free (ds->wire_details);
+ json_decref (ds->wire_details);
GNUNET_free (ds);
}
+
/**
* Extract information from a command that is useful for other
* commands.
@@ -354,7 +340,7 @@ deposit_traits (void *cls,
unsigned int index)
{
struct DepositState *ds = cls;
- const struct TALER_TESTING_Command *coin_cmd;
+ const struct TALER_TESTING_Command *coin_cmd;
/* Will point to coin cmd internals. */
struct TALER_CoinSpendPrivateKeyP *coin_spent_priv;
@@ -382,7 +368,7 @@ deposit_traits (void *cls,
TALER_TESTING_make_trait_contract_terms (0, ds->contract_terms),
TALER_TESTING_make_trait_peer_key
(0, &ds->merchant_priv.eddsa_priv),
- TALER_TESTING_trait_end ()
+ TALER_TESTING_trait_end ()
};
return TALER_TESTING_get_trait (traits,
@@ -402,8 +388,8 @@ deposit_traits (void *cls,
* coins, this parameter selects which one in that array.
* This value is currently ignored, as only one-coin
* withdrawals are implemented.
- * @param wire_details bank details of the merchant performing the
- * deposit
+ * @param wire_details JSON details of the wire account of the merchant performing the
+ * deposit, reference is captured by this command
* @param contract_terms contract terms to be signed over by the
* coin
* @param refund_deadline refund deadline, zero means 'no refunds'
@@ -419,7 +405,7 @@ TALER_TESTING_cmd_deposit
struct TALER_EXCHANGE_Handle *exchange,
const char *coin_reference,
unsigned int coin_index,
- char *wire_details,
+ json_t *wire_details,
const char *contract_terms,
struct GNUNET_TIME_Relative refund_deadline,
const char *amount,
@@ -427,7 +413,7 @@ TALER_TESTING_cmd_deposit
{
struct TALER_TESTING_Command cmd;
struct DepositState *ds;
-
+
ds = GNUNET_new (struct DepositState);
ds->exchange = exchange;
ds->coin_reference = coin_reference;
diff --git a/src/exchange-lib/testing_api_cmd_exec_wirewatch.c b/src/exchange-lib/testing_api_cmd_exec_wirewatch.c
index 1ff466f56..fd8404bec 100644
--- a/src/exchange-lib/testing_api_cmd_exec_wirewatch.c
+++ b/src/exchange-lib/testing_api_cmd_exec_wirewatch.c
@@ -68,7 +68,6 @@ wirewatch_run (void *cls,
"taler-exchange-wirewatch",
"taler-exchange-wirewatch",
"-c", ws->config_filename,
- "-t", "test", /* use Taler's bank/fakebank */
"-T", /* exit when done */
NULL);
if (NULL == ws->wirewatch_proc)
diff --git a/src/exchange-lib/testing_api_cmd_payback.c b/src/exchange-lib/testing_api_cmd_payback.c
index 3a750e7fc..65665c9c8 100644
--- a/src/exchange-lib/testing_api_cmd_payback.c
+++ b/src/exchange-lib/testing_api_cmd_payback.c
@@ -31,7 +31,7 @@
struct RevokeState
{
- /**
+ /**
* Expected HTTP status code.
*/
unsigned int expected_response_code;
@@ -65,7 +65,7 @@ struct RevokeState
struct PaybackState
{
- /**
+ /**
* Expected HTTP status code.
*/
unsigned int expected_response_code;
@@ -154,7 +154,7 @@ payback_cb (void *cls,
TALER_TESTING_interpreter_fail (is);
return;
}
-
+
if (GNUNET_OK != TALER_TESTING_get_trait_reserve_priv
(reserve_cmd, 0, &reserve_priv))
{
@@ -201,6 +201,7 @@ payback_cb (void *cls,
TALER_TESTING_interpreter_next (is);
}
+
/**
* Run the command.
*
@@ -208,7 +209,7 @@ payback_cb (void *cls,
* @param cmd the command to execute, a /wire one.
* @param is the interpreter state.
*/
-void
+static void
payback_run (void *cls,
const struct TALER_TESTING_Command *cmd,
struct TALER_TESTING_Interpreter *is)
@@ -230,7 +231,7 @@ payback_run (void *cls,
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
- return;
+ return;
}
if (GNUNET_OK != TALER_TESTING_get_trait_coin_priv
@@ -238,7 +239,7 @@ payback_run (void *cls,
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
- return;
+ return;
}
if (GNUNET_OK != TALER_TESTING_get_trait_blinding_key
@@ -246,7 +247,7 @@ payback_run (void *cls,
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
- return;
+ return;
}
planchet.coin_priv = *coin_priv;
planchet.blinding_key = *blinding_key;
@@ -256,7 +257,7 @@ payback_run (void *cls,
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
- return;
+ return;
}
if (GNUNET_OK != TALER_TESTING_get_trait_denom_sig
@@ -264,13 +265,13 @@ payback_run (void *cls,
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
- return;
+ return;
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Trying to get '%s..' paid back\n",
TALER_B2S (&denom_pub->h_key));
-
+
ps->ph = TALER_EXCHANGE_payback (ps->exchange,
denom_pub,
coin_sig,
@@ -280,13 +281,14 @@ payback_run (void *cls,
GNUNET_assert (NULL != ps->ph);
}
+
/**
* Cleanup the state.
*
* @param cls closure, typically a #struct WireState.
* @param cmd the command which is being cleaned up.
*/
-void
+static void
revoke_cleanup (void *cls,
const struct TALER_TESTING_Command *cmd)
{
@@ -302,17 +304,18 @@ revoke_cleanup (void *cls,
rs->revoke_proc = NULL;
}
- GNUNET_free (rs->dhks);
+ GNUNET_free_non_null (rs->dhks);
GNUNET_free (rs);
}
+
/**
* Cleanup the state.
*
* @param cls closure, typically a #struct WireState.
* @param cmd the command which is being cleaned up.
*/
-void
+static void
payback_cleanup (void *cls,
const struct TALER_TESTING_Command *cmd)
{
@@ -325,6 +328,7 @@ payback_cleanup (void *cls,
GNUNET_free (ps);
}
+
/**
* Extract information from a command that is useful for other
* commands.
@@ -366,7 +370,7 @@ revoke_traits (void *cls,
* @param cmd the command to execute, a /wire one.
* @param is the interpreter state.
*/
-void
+static void
revoke_run (void *cls,
const struct TALER_TESTING_Command *cmd,
struct TALER_TESTING_Interpreter *is)
@@ -384,7 +388,7 @@ revoke_run (void *cls,
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
- return;
+ return;
}
GNUNET_assert (GNUNET_OK == TALER_TESTING_get_trait_denom_pub
@@ -395,8 +399,8 @@ revoke_run (void *cls,
TALER_B2S (&denom_pub->h_key));
rs->dhks = GNUNET_STRINGS_data_to_string_alloc
- (&denom_pub->h_key, sizeof (struct GNUNET_HashCode));
-
+ (&denom_pub->h_key, sizeof (struct GNUNET_HashCode));
+
rs->revoke_proc = GNUNET_OS_start_process
(GNUNET_NO,
GNUNET_OS_INHERIT_STD_ALL,
@@ -441,7 +445,7 @@ TALER_TESTING_cmd_payback (const char *label,
{
struct PaybackState *ps;
struct TALER_TESTING_Command cmd;
-
+
ps = GNUNET_new (struct PaybackState);
ps->expected_response_code = expected_response_code;
ps->coin_reference = coin_reference;
@@ -455,6 +459,7 @@ TALER_TESTING_cmd_payback (const char *label,
return cmd;
}
+
/**
* Make a /revoke command.
*
diff --git a/src/exchange-lib/testing_api_cmd_refund.c b/src/exchange-lib/testing_api_cmd_refund.c
index a092ee2d2..35cb20d26 100644
--- a/src/exchange-lib/testing_api_cmd_refund.c
+++ b/src/exchange-lib/testing_api_cmd_refund.c
@@ -139,7 +139,7 @@ refund_run (void *cls,
const struct TALER_TESTING_Command *cmd,
struct TALER_TESTING_Interpreter *is)
{
- struct RefundState *rs = cls;
+ struct RefundState *rs = cls;
struct TALER_CoinSpendPrivateKeyP *coin_priv;
struct TALER_CoinSpendPublicKeyP coin;
const char *contract_terms;
@@ -193,7 +193,7 @@ refund_run (void *cls,
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
- return;
+ return;
}
j_contract_terms = json_loads
@@ -201,8 +201,9 @@ refund_run (void *cls,
/* Very unlikely to fail */
GNUNET_assert (NULL != j_contract_terms);
- GNUNET_assert (GNUNET_OK == TALER_JSON_hash
- (j_contract_terms, &h_contract_terms));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_JSON_hash (j_contract_terms,
+ &h_contract_terms));
json_decref (j_contract_terms);
@@ -222,7 +223,7 @@ refund_run (void *cls,
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
- return;
+ return;
}
rs->rh = TALER_EXCHANGE_refund
diff --git a/src/exchange-lib/testing_api_cmd_track.c b/src/exchange-lib/testing_api_cmd_track.c
index 3f14c5110..638329d69 100644
--- a/src/exchange-lib/testing_api_cmd_track.c
+++ b/src/exchange-lib/testing_api_cmd_track.c
@@ -183,7 +183,7 @@ deposit_wtid_cb
tts->wtid = *wtid;
if (NULL != tts->bank_transfer_reference)
{
- const struct TALER_TESTING_Command *bank_transfer_cmd;
+ const struct TALER_TESTING_Command *bank_transfer_cmd;
char *ws;
ws = GNUNET_STRINGS_data_to_string_alloc (wtid,
@@ -205,7 +205,7 @@ deposit_wtid_cb
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
- return;
+ return;
}
if (0 != strcmp (ws, transfer_subject))
@@ -248,14 +248,13 @@ track_transaction_run (void *cls,
const struct TALER_TESTING_Command *transaction_cmd;
struct TALER_CoinSpendPrivateKeyP *coin_priv;
struct TALER_CoinSpendPublicKeyP coin_pub;
- const char *wire_details;
const char *contract_terms;
- json_t *j_wire_details;
+ const json_t *wire_details;
json_t *j_contract_terms;
struct GNUNET_HashCode h_wire_details;
struct GNUNET_HashCode h_contract_terms;
const struct GNUNET_CRYPTO_EddsaPrivateKey *merchant_priv;
-
+
tts->is = is;
transaction_cmd = TALER_TESTING_interpreter_lookup_command
(tts->is, tts->transaction_reference);
@@ -264,7 +263,7 @@ track_transaction_run (void *cls,
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (tts->is);
- return;
+ return;
}
if (GNUNET_OK != TALER_TESTING_get_trait_coin_priv
@@ -272,7 +271,7 @@ track_transaction_run (void *cls,
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (tts->is);
- return;
+ return;
}
GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
@@ -296,31 +295,31 @@ track_transaction_run (void *cls,
}
/* Parse them.. */
- j_wire_details = json_loads
- (wire_details, JSON_REJECT_DUPLICATES, NULL);
j_contract_terms = json_loads
(contract_terms, JSON_REJECT_DUPLICATES, NULL);
-
- if ((NULL == j_wire_details) || (NULL == j_contract_terms))
+
+ if ((NULL == wire_details) || (NULL == j_contract_terms))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (tts->is);
- return;
+ return;
}
/* Should not fail here, json has been parsed already */
GNUNET_assert
- ( (GNUNET_OK == TALER_JSON_hash (j_wire_details,
- &h_wire_details)) &&
- (GNUNET_OK == TALER_JSON_hash (j_contract_terms,
- &h_contract_terms)) );
+ ( (GNUNET_OK ==
+ TALER_JSON_wire_signature_hash (wire_details,
+ &h_wire_details)) &&
+ (GNUNET_OK ==
+ TALER_JSON_hash (j_contract_terms,
+ &h_contract_terms)) );
if (GNUNET_OK != TALER_TESTING_get_trait_peer_key
(transaction_cmd, 0, &merchant_priv))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (tts->is);
- return;
+ return;
}
tts->tth = TALER_EXCHANGE_track_transaction
@@ -580,7 +579,7 @@ track_transfer_cb
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
- return;
+ return;
}
/**
@@ -594,8 +593,7 @@ track_transfer_cb
if (NULL != tts->wire_details_reference)
{
const struct TALER_TESTING_Command *wire_details_cmd;
- const char *wire_details;
- json_t *j_wire_details;
+ const json_t *wire_details;
struct GNUNET_HashCode h_wire_details;
if (NULL == (wire_details_cmd
@@ -615,13 +613,9 @@ track_transfer_cb
return;
}
- j_wire_details = json_loads
- (wire_details, JSON_REJECT_DUPLICATES, NULL);
-
- GNUNET_assert (NULL != j_wire_details);
-
- GNUNET_assert (GNUNET_OK == TALER_JSON_hash
- (j_wire_details, &h_wire_details));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_JSON_wire_signature_hash (wire_details,
+ &h_wire_details));
if (0 != memcmp (&h_wire_details,
h_wire,
@@ -647,7 +641,7 @@ track_transfer_cb
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
- return;
+ return;
}
if (GNUNET_OK != TALER_TESTING_get_trait_amount
@@ -657,7 +651,7 @@ track_transfer_cb
TALER_TESTING_interpreter_fail (is);
return;
}
-
+
GNUNET_assert (GNUNET_OK == TALER_string_to_amount
(total_amount_from_reference_str,
&total_amount_from_reference));
@@ -699,7 +693,7 @@ track_transfer_run (void *cls,
* WTID */
memset (&wtid, 0, sizeof (wtid));
wtid_ptr = &wtid;
-
+
tts->is = is;
if (NULL != tts->wtid_reference)
{
@@ -720,7 +714,7 @@ track_transfer_run (void *cls,
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (tts->is);
- return;
+ return;
}
GNUNET_assert (NULL != wtid_ptr);
}
@@ -756,7 +750,7 @@ TALER_TESTING_cmd_track_transfer_empty
{
struct TrackTransferState *tts;
struct TALER_TESTING_Command cmd;
-
+
tts = GNUNET_new (struct TrackTransferState);
tts->wtid_reference = wtid_reference;
@@ -769,7 +763,7 @@ TALER_TESTING_cmd_track_transfer_empty
cmd.run = &track_transfer_run;
cmd.cleanup = &track_transfer_cleanup;
- return cmd;
+ return cmd;
}
/**
@@ -801,7 +795,7 @@ TALER_TESTING_cmd_track_transfer
{
struct TrackTransferState *tts;
struct TALER_TESTING_Command cmd;
-
+
tts = GNUNET_new (struct TrackTransferState);
tts->wtid_reference = wtid_reference;
@@ -816,5 +810,5 @@ TALER_TESTING_cmd_track_transfer
cmd.run = &track_transfer_run;
cmd.cleanup = &track_transfer_cleanup;
- return cmd;
+ return cmd;
}
diff --git a/src/exchange-lib/testing_api_cmd_wire.c b/src/exchange-lib/testing_api_cmd_wire.c
index f65daec00..cf8304e29 100644
--- a/src/exchange-lib/testing_api_cmd_wire.c
+++ b/src/exchange-lib/testing_api_cmd_wire.c
@@ -27,6 +27,7 @@
#include "taler_json_lib.h"
#include <gnunet/gnunet_curl_lib.h>
#include "exchange_api_handle.h"
+#include "taler_wire_lib.h"
#include "taler_testing_lib.h"
struct WireState
@@ -71,19 +72,6 @@ struct WireState
/**
- * Check all the expected values have been returned by /wire.
- *
- * @param cls closure
- * @param wire_method name of the wire method (i.e. "sepa")
- * @param fees fee structure for this method
- */
-static void
-check_method_and_fee_cb
- (void *cls,
- const char *wire_method,
- const struct TALER_EXCHANGE_WireAggregateFees *fees);
-
-/**
* Callbacks called with the result(s) of a wire format inquiry
* request to the exchange.
*
@@ -92,23 +80,20 @@ check_method_and_fee_cb
* for successful 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 obj the received JSON reply, if successful this should
- * be the wire format details as provided by /wire.
+ * @param accounts_len length of the @a accounts array
+ * @param accounts list of wire accounts of the exchange, NULL on error
*/
static void
wire_cb (void *cls,
unsigned int http_status,
enum TALER_ErrorCode ec,
- const json_t *obj)
+ unsigned int accounts_len,
+ const struct TALER_EXCHANGE_WireAccount *accounts)
{
struct WireState *ws = cls;
- struct TALER_TESTING_Command *cmd
- = &ws->is->commands[ws->is->ip];
+ struct TALER_TESTING_Command *cmd = &ws->is->commands[ws->is->ip];
+ struct TALER_Amount expected_fee;
- /**
- * The handle has been free'd by GNUnet curl-lib. FIXME:
- * shouldn't GNUnet nullify it once it frees it?
- */
ws->wh = NULL;
if (ws->expected_response_code != http_status)
{
@@ -117,74 +102,54 @@ wire_cb (void *cls,
return;
}
- if (GNUNET_OK != TALER_EXCHANGE_wire_get_fees
- (&TALER_EXCHANGE_get_keys (ws->exchange)->master_pub,
- obj,
- // will check synchronously.
- &check_method_and_fee_cb,
- ws))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Wire fee extraction in command %s failed\n",
- cmd->label);
- json_dumpf (obj, stderr, 0);
- TALER_TESTING_interpreter_fail (ws->is);
- return;
- }
-
- if (ws->method_found != GNUNET_OK)
+ if (MHD_HTTP_OK == http_status)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "/wire does not offer method '%s'\n",
- ws->expected_method);
- TALER_TESTING_interpreter_fail (ws->is);
- return;
- }
- TALER_TESTING_interpreter_next (ws->is);
-}
-
-/**
- * Check all the expected values have been returned by /wire.
- *
- * @param cls closure
- * @param wire_method name of the wire method (i.e. "sepa")
- * @param fees fee structure for this method
- */
-static void
-check_method_and_fee_cb
- (void *cls,
- const char *wire_method,
- const struct TALER_EXCHANGE_WireAggregateFees *fees)
-{
- struct WireState *ws = cls;
- struct TALER_TESTING_Command *cmd
- = &ws->is->commands[ws->is->ip]; // ugly?
- struct TALER_Amount expected_fee;
-
- if (0 == strcmp (ws->expected_method, wire_method))
- ws->method_found = GNUNET_OK;
-
- if ( ws->expected_fee && (ws->method_found == GNUNET_OK) )
- {
- GNUNET_assert (GNUNET_OK == TALER_string_to_amount
- (ws->expected_fee,
- &expected_fee));
- while (NULL != fees)
+ for (unsigned int i=0;i<accounts_len;i++)
{
- if (0 != TALER_amount_cmp (&fees->wire_fee,
- &expected_fee))
+ char *method;
+
+ method = TALER_WIRE_payto_get_method (accounts[i].url);
+ if (0 == strcmp (ws->expected_method,
+ method))
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Wire fee missmatch to command %s\n",
- cmd->label);
- TALER_TESTING_interpreter_fail (ws->is);
- return;
+ ws->method_found = GNUNET_OK;
+ if (NULL != ws->expected_fee)
+ {
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (ws->expected_fee,
+ &expected_fee));
+ for (const struct TALER_EXCHANGE_WireAggregateFees *waf = accounts[i].fees;
+ NULL != waf;
+ waf = waf->next)
+ {
+ if (0 != TALER_amount_cmp (&waf->wire_fee,
+ &expected_fee))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Wire fee missmatch to command %s\n",
+ cmd->label);
+ TALER_TESTING_interpreter_fail (ws->is);
+ GNUNET_free (method);
+ return;
+ }
+ }
+ }
}
- fees = fees->next;
+ GNUNET_free (method);
+ }
+ if (GNUNET_OK != ws->method_found)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "/wire does not offer method '%s'\n",
+ ws->expected_method);
+ TALER_TESTING_interpreter_fail (ws->is);
+ return;
}
}
+ TALER_TESTING_interpreter_next (ws->is);
}
+
/**
* Run the command.
*
diff --git a/src/exchange-lib/testing_api_helpers.c b/src/exchange-lib/testing_api_helpers.c
index a942b6522..3aff0a3cc 100644
--- a/src/exchange-lib/testing_api_helpers.c
+++ b/src/exchange-lib/testing_api_helpers.c
@@ -416,42 +416,54 @@ TALER_TESTING_url_port_free (const char *url)
return GNUNET_OK;
}
+
/**
- * Allocate and return a piece of wire-details. Mostly, it adds
- * the bank_url to the JSON.
+ * Allocate and return a piece of wire-details. Combines
+ * the @a account_no and the @a bank_url to a
+ * @a payto://-URL and adds some salt to create the JSON.
*
- * @param template the wire-details template.
+ * @param account_no account number
* @param bank_url the bank_url
- *
- * @return the filled out and stringified wire-details. To
- * be manually free'd.
+ * @return JSON describing the account, including the
+ * payto://-URL of the account, must be manually decref'd
*/
-char *
-TALER_TESTING_make_wire_details (const char *template,
+json_t *
+TALER_TESTING_make_wire_details (unsigned long long account_no,
const char *bank_url)
{
- json_t *jtemplate;
-
- GNUNET_assert (NULL != (jtemplate = json_loads
- (template, JSON_REJECT_DUPLICATES, NULL)));
- GNUNET_assert (0 == json_object_set
- (jtemplate, "bank_url", json_string (bank_url)));
- return json_dumps (jtemplate, JSON_COMPACT);
+ char *payto;
+ json_t *ret;
+
+ GNUNET_asprintf (&payto,
+ "payto://x-taler-bank/%s/%llu",
+ bank_url,
+ account_no);
+ ret = json_pack ("{s:s, s:s}",
+ "url", payto,
+ "salt", "test-salt (must be constant for aggregation tests)");
+ GNUNET_free (payto);
+ return ret;
}
+
/**
* Prepare launching a fakebank. Check that the configuration
* file has the right option, and that the port is available.
* If everything is OK, return the configured URL of the fakebank.
*
* @param config_filename configuration file to use
+ * @param config_section which account to use (must match x-taler-bank)
* @return NULL on error, fakebank URL otherwise
*/
char *
-TALER_TESTING_prepare_fakebank (const char *config_filename)
+TALER_TESTING_prepare_fakebank (const char *config_filename,
+ const char *config_section)
{
struct GNUNET_CONFIGURATION_Handle *cfg;
+ char *payto_url;
char *fakebank_url;
+ const char *start;
+ const char *end;
cfg = GNUNET_CONFIGURATION_create ();
if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg,
@@ -459,17 +471,37 @@ TALER_TESTING_prepare_fakebank (const char *config_filename)
return NULL;
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
- "exchange-wire-test",
- "BANK_URL",
- &fakebank_url))
+ config_section,
+ "URL",
+ &payto_url))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
- "exchange-wire-test",
- "BANK_URL");
+ config_section,
+ "URL");
GNUNET_CONFIGURATION_destroy (cfg);
return NULL;
}
GNUNET_CONFIGURATION_destroy (cfg);
+ if (0 != strncasecmp (payto_url,
+ "payto://x-taler-bank/",
+ strlen ("payto://x-taler-bank/")))
+ {
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
+ config_section,
+ "URL",
+ "expected `x-taler-bank' payto://-URL");
+ GNUNET_CONFIGURATION_destroy (cfg);
+ GNUNET_free (payto_url);
+ return NULL;
+ }
+ start = &payto_url [strlen ("payto://x-taler-bank/")];
+ end = strchr (start,
+ (unsigned char) '/');
+ if (NULL == end)
+ end = &start[strlen (start)];
+ fakebank_url = GNUNET_strndup (start,
+ end - start);
+ GNUNET_free (payto_url);
if (GNUNET_OK !=
TALER_TESTING_url_port_free (fakebank_url))
{
diff --git a/src/exchange-lib/testing_api_trait_json.c b/src/exchange-lib/testing_api_trait_json.c
new file mode 100644
index 000000000..40dddbfa3
--- /dev/null
+++ b/src/exchange-lib/testing_api_trait_json.c
@@ -0,0 +1,76 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2018 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 Foundation; either version 3, or (at your
+ option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with TALER; see the file COPYING. If not, see
+ <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file exchange-lib/testing_api_trait_json.c
+ * @brief offers JSON traits.
+ * @author Marcello Stanisci
+ */
+#include "platform.h"
+#include "taler_json_lib.h"
+#include <gnunet/gnunet_curl_lib.h>
+#include "exchange_api_handle.h"
+#include "taler_signatures.h"
+#include "taler_testing_lib.h"
+
+#define TALER_TESTING_TRAIT_WIRE_DETAILS "wire-details"
+
+/**
+ * Obtain wire details from @a cmd.
+ *
+ * @param cmd command to extract trait from
+ * @param index always (?) zero, as one command sticks
+ * to one bank account
+ * @param wire_details[out] where to write the wire details.
+ * @return #GNUNET_OK on success
+ */
+int
+TALER_TESTING_get_trait_wire_details
+ (const struct TALER_TESTING_Command *cmd,
+ unsigned int index,
+ const json_t **wire_details)
+{
+ return cmd->traits (cmd->cls,
+ (void **) wire_details,
+ TALER_TESTING_TRAIT_WIRE_DETAILS,
+ index);
+}
+
+/**
+ * Offer wire details in a trait.
+ *
+ * @param index always (?) zero, as one command sticks
+ * to one bank account
+ * @param wire_details wire details to offer
+ * @return the trait, to be put in the traits array of the command
+ */
+struct TALER_TESTING_Trait
+TALER_TESTING_make_trait_wire_details
+ (unsigned int index,
+ const json_t *wire_details)
+{
+ struct TALER_TESTING_Trait ret = {
+ .index = index,
+ .trait_name = TALER_TESTING_TRAIT_WIRE_DETAILS,
+ .ptr = (const json_t *) wire_details
+ };
+ return ret;
+}
+
+/* end of testing_api_trait_json.c */
diff --git a/src/exchange-lib/testing_api_trait_string.c b/src/exchange-lib/testing_api_trait_string.c
index 1b1b42219..fb5af93e5 100644
--- a/src/exchange-lib/testing_api_trait_string.c
+++ b/src/exchange-lib/testing_api_trait_string.c
@@ -30,7 +30,6 @@
#include "taler_signatures.h"
#include "taler_testing_lib.h"
-#define TALER_TESTING_TRAIT_WIRE_DETAILS "wire-details"
#define TALER_TESTING_TRAIT_CONTRACT_TERMS "contract-terms"
#define TALER_TESTING_TRAIT_TRANSFER_SUBJECT "transfer-subject"
#define TALER_TESTING_TRAIT_AMOUNT "amount"
@@ -81,49 +80,6 @@ TALER_TESTING_make_trait_contract_terms
/**
- * Obtain wire details from @a cmd.
- *
- * @param cmd command to extract trait from
- * @param index always (?) zero, as one command sticks
- * to one bank account
- * @param wire_details[out] where to write the wire details.
- * @return #GNUNET_OK on success
- */
-int
-TALER_TESTING_get_trait_wire_details
- (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const char **wire_details)
-{
- return cmd->traits (cmd->cls,
- (void **) wire_details,
- TALER_TESTING_TRAIT_WIRE_DETAILS,
- index);
-}
-
-/**
- * Offer wire details in a trait.
- *
- * @param index always (?) zero, as one command sticks
- * to one bank account
- * @param wire_details wire details to offer
- * @return the trait, to be put in the traits array of the command
- */
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_wire_details
- (unsigned int index,
- const char *wire_details)
-{
- struct TALER_TESTING_Trait ret = {
- .index = index,
- .trait_name = TALER_TESTING_TRAIT_WIRE_DETAILS,
- .ptr = (const void *) wire_details
- };
- return ret;
-}
-
-
-/**
* Obtain a transfer subject from @a cmd.
*
* @param cmd command to extract trait from
@@ -289,7 +245,7 @@ TALER_TESTING_make_trait_order_id
struct TALER_TESTING_Trait ret = {
.index = index,
.trait_name = TALER_TESTING_TRAIT_ORDER_ID,
- .ptr = (const void *) order_id
+ .ptr = (const void *) order_id
};
return ret;
}
@@ -333,7 +289,7 @@ TALER_TESTING_make_trait_rejected
struct TALER_TESTING_Trait ret = {
.index = index,
.trait_name = TALER_TESTING_TRAIT_REJECTED,
- .ptr = (const void *) rejected
+ .ptr = (const void *) rejected
};
return ret;
}