summaryrefslogtreecommitdiff
path: root/src/cli
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli')
-rw-r--r--src/cli/.gitignore7
-rw-r--r--src/cli/Makefile.am28
-rw-r--r--src/cli/anastasis-cli-discover.c261
-rw-r--r--src/cli/anastasis-cli-redux.c43
-rw-r--r--src/cli/resources/00-backup.json7
-rw-r--r--src/cli/resources/00-recovery.json3
-rw-r--r--src/cli/resources/01-backup.json27
-rw-r--r--src/cli/resources/01-recovery.json3
-rw-r--r--src/cli/resources/02-backup.json35
-rw-r--r--src/cli/resources/02-recovery.json9
-rw-r--r--src/cli/resources/03-backup.json45
-rw-r--r--src/cli/resources/04-backup.json44
-rw-r--r--src/cli/resources/05-backup.json13
-rw-r--r--src/cli/resources/06-backup.json13
-rwxr-xr-xsrc/cli/setup.sh72
-rw-r--r--src/cli/test_anastasis_reducer_1.conf2
-rw-r--r--src/cli/test_anastasis_reducer_2.conf2
-rw-r--r--src/cli/test_anastasis_reducer_3.conf2
-rw-r--r--src/cli/test_anastasis_reducer_4.conf2
-rwxr-xr-xsrc/cli/test_anastasis_reducer_backup_enter_user_attributes.sh10
-rwxr-xr-xsrc/cli/test_anastasis_reducer_done_authentication.sh4
-rwxr-xr-xsrc/cli/test_anastasis_reducer_enter_secret.sh438
-rw-r--r--src/cli/test_anastasis_reducer_free_1.conf10
-rw-r--r--src/cli/test_anastasis_reducer_free_2.conf10
-rw-r--r--src/cli/test_anastasis_reducer_free_3.conf10
-rw-r--r--src/cli/test_anastasis_reducer_free_4.conf10
-rwxr-xr-xsrc/cli/test_anastasis_reducer_recovery_enter_user_attributes.sh500
-rwxr-xr-xsrc/cli/test_anastasis_reducer_recovery_hanging.sh376
-rwxr-xr-xsrc/cli/test_anastasis_reducer_recovery_no_pay.sh351
-rwxr-xr-xsrc/cli/test_anastasis_reducer_select_continent.sh14
-rwxr-xr-xsrc/cli/test_anastasis_reducer_select_country.sh18
-rw-r--r--src/cli/test_free_reducer.conf2
-rwxr-xr-xsrc/cli/test_iban.sh363
-rw-r--r--src/cli/test_reducer.conf76
-rw-r--r--src/cli/test_reducer_free.conf210
-rw-r--r--src/cli/test_reducer_home/.local/share/taler/exchange-offline/master.priv1
36 files changed, 2148 insertions, 873 deletions
diff --git a/src/cli/.gitignore b/src/cli/.gitignore
index dbf01fa..111e321 100644
--- a/src/cli/.gitignore
+++ b/src/cli/.gitignore
@@ -1,6 +1,13 @@
*.log
+*.err
+*.out
anastasis-reducer
test_reducer_home
*.trs
taler-bank.err
wallet.err
+anastasis-discover
+talercheck
+test_reducer.conf.edited
+wallet-withdraw.out
+libeufin-transfer-initiate.out
diff --git a/src/cli/Makefile.am b/src/cli/Makefile.am
index 8434c91..8b2a9a0 100644
--- a/src/cli/Makefile.am
+++ b/src/cli/Makefile.am
@@ -2,6 +2,7 @@
AM_CPPFLAGS = -I$(top_srcdir)/src/include
bin_PROGRAMS = \
+ anastasis-discover \
anastasis-reducer
if USE_COVERAGE
@@ -19,7 +20,11 @@ check_SCRIPTS = \
test_anastasis_reducer_done_policy_review.sh \
test_anastasis_reducer_enter_secret.sh \
test_anastasis_reducer_recovery_enter_user_attributes.sh \
- test_iban.sh
+ test_anastasis_reducer_recovery_no_pay.sh \
+ test_anastasis_reducer_recovery_hanging.sh
+
+# Removed for now, libeufin is not yet working OK for this.
+# test_iban.sh
AM_TESTS_ENVIRONMENT=export ANASTASIS_PREFIX=$${ANASTASIS_PREFIX:-@libdir@};export PATH=$${ANASTASIS_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
@@ -29,12 +34,19 @@ TESTS = \
EXTRA_DIST = \
$(check_SCRIPTS) \
+ setup.sh \
+ test_reducer_home/.local/share/taler/exchange-offline/master.priv \
test_reducer.conf \
+ test_reducer_free.conf \
test_free_reducer.conf \
test_anastasis_reducer_1.conf \
test_anastasis_reducer_2.conf \
test_anastasis_reducer_3.conf \
test_anastasis_reducer_4.conf \
+ test_anastasis_reducer_free_1.conf \
+ test_anastasis_reducer_free_2.conf \
+ test_anastasis_reducer_free_3.conf \
+ test_anastasis_reducer_free_4.conf \
resources/00-backup.json \
resources/01-backup.json \
resources/02-backup.json \
@@ -58,3 +70,17 @@ anastasis_reducer_LDADD = \
-lgnunetutil \
-ljansson \
$(XLIB)
+
+
+anastasis_discover_SOURCES = \
+ anastasis-cli-discover.c
+anastasis_discover_LDADD = \
+ $(top_builddir)/src/util/libanastasisutil.la \
+ $(top_builddir)/src/reducer/libanastasisredux.la \
+ -ltalerjson \
+ -ltalerutil \
+ -lgnunetjson \
+ -lgnunetcurl \
+ -lgnunetutil \
+ -ljansson \
+ $(XLIB)
diff --git a/src/cli/anastasis-cli-discover.c b/src/cli/anastasis-cli-discover.c
new file mode 100644
index 0000000..f614165
--- /dev/null
+++ b/src/cli/anastasis-cli-discover.c
@@ -0,0 +1,261 @@
+/*
+ This file is part of Anastasis
+ Copyright (C) 2022 Anastasis SARL
+
+ Anastasis is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Lesser General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ Anastasis 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file cli/anastasis-cli-discover.c
+ * @brief command line tool to discover recovery policies
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_curl_lib.h>
+#include "anastasis_redux.h"
+#include <taler/taler_util.h>
+#include <taler/taler_error_codes.h>
+#include <taler/taler_json_lib.h>
+#include "anastasis_util_lib.h"
+
+/**
+ * Closure for #GNUNET_CURL_gnunet_scheduler_reschedule().
+ */
+static struct GNUNET_CURL_RescheduleContext *rc;
+
+/**
+ * Curl context for communication with anastasis backend
+ */
+static struct GNUNET_CURL_Context *ctx;
+
+/**
+ * Input to -a option given.
+ */
+static char *input;
+
+/**
+ * JSON containing previous state
+ */
+static json_t *prev_state;
+
+/**
+ * JSON containing arguments for action
+ */
+static json_t *arguments;
+
+/**
+ * Handle to an ongoing action.
+ */
+struct ANASTASIS_PolicyDiscovery *pd;
+
+/**
+ * Return value from main.
+ */
+static int global_ret;
+
+
+/**
+ * Function called on each discovered recovery policy. Called
+ * with all arguments NULL if we have received all policies that
+ * we could possibly receive for the current operation.
+ *
+ * The client can then start a new policy discovery process, using the
+ * smallest (also most recent) @a version received per @a provider_url
+ * in the cursor to resume. Note that in this case, the application
+ * logic is responsible for de-duplication using @a hcpd, or it may show
+ * policies again if they are at different providers under versions not
+ * queried up to the cursor.
+ *
+ * @param cls closure
+ * @param hcpd hash of the compressed policy document (unique per policy)
+ * @param provider_url which provider claims to have this policy
+ * @param version version of the policy at this provider
+ * @param attribute_mask combination of optional identity attributes
+ * present in the state that was used to locate this version
+ * @param server_time when did the provider receive the upload
+ * @param secret_name name the user assigned to the backup
+ */
+static void
+print_policy_cb (void *cls,
+ const struct GNUNET_HashCode *hcpd,
+ const char *provider_url,
+ uint32_t version,
+ json_int_t attribute_mask,
+ struct GNUNET_TIME_Timestamp server_time,
+ const char *secret_name,
+ const json_t *providers)
+{
+ if (NULL == hcpd)
+ {
+ fprintf (stderr,
+ "All results received, terminating\n");
+ pd = NULL;
+ global_ret = 0;
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ fprintf (stdout,
+ "%s %u %u : \"%s\" \"%s\" (%s)\n",
+ provider_url,
+ (unsigned int) version,
+ (unsigned int) attribute_mask,
+ GNUNET_TIME_timestamp2s (server_time),
+ secret_name,
+ GNUNET_h2s (hcpd));
+}
+
+
+/**
+ * @brief Shutdown the application.
+ *
+ * @param cls closure
+ */
+static void
+shutdown_task (void *cls)
+{
+ (void) cls;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Shutdown initiated\n");
+ if (NULL != pd)
+ {
+ ANASTASIS_policy_discovery_stop (pd);
+ pd = NULL;
+ }
+ ANASTASIS_redux_done ();
+ if (NULL != ctx)
+ {
+ GNUNET_CURL_fini (ctx);
+ ctx = NULL;
+ }
+ if (NULL != rc)
+ {
+ GNUNET_CURL_gnunet_rc_destroy (rc);
+ rc = NULL;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Shutdown complete\n");
+}
+
+
+/**
+ * @brief Start the application
+ *
+ * @param cls closure
+ * @param args arguments left
+ * @param cfgfile config file name
+ * @param cfg handle for the configuration file
+ */
+static void
+run (void *cls,
+ char *const *args,
+ const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ (void) cls;
+ json_error_t error;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Starting anastasis-discover\n");
+ GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+ NULL);
+ /* load cursor */
+ if (NULL != input)
+ {
+ arguments = json_loads (input,
+ JSON_DECODE_ANY,
+ &error);
+ if (NULL == arguments)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Failed to parse arguments on line %u:%u: %s!\n",
+ error.line,
+ error.column,
+ error.text);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ }
+ /* load state */
+ if (NULL != args[0])
+ {
+ prev_state = json_load_file (args[0],
+ JSON_DECODE_ANY,
+ &error);
+ args++;
+ }
+ else
+ {
+ prev_state = json_loadf (stdin,
+ JSON_DECODE_ANY,
+ &error);
+ }
+ if (NULL == prev_state)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Failed to parse initial state on line %u:%u: %s!\n",
+ error.line,
+ error.column,
+ error.text);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ /* initialize HTTP client event loop */
+ ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
+ &rc);
+ rc = GNUNET_CURL_gnunet_rc_create (ctx);
+ ANASTASIS_redux_init (ctx);
+ pd = ANASTASIS_policy_discovery_start (prev_state,
+ arguments,
+ &print_policy_cb,
+ NULL);
+}
+
+
+int
+main (int argc,
+ char *const *argv)
+{
+ /* the available command line options */
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_option_string ('a',
+ "arguments",
+ "JSON",
+ "pass a JSON string containing cursor to use",
+ &input),
+
+ GNUNET_GETOPT_OPTION_END
+ };
+ enum GNUNET_GenericReturnValue ret;
+
+ /* FIRST get the libtalerutil initialization out
+ of the way. Then throw that one away, and force
+ the SYNC defaults to be used! */
+ (void) TALER_project_data_default ();
+ GNUNET_OS_init (ANASTASIS_project_data_default ());
+ ret = GNUNET_PROGRAM_run (argc,
+ argv,
+ "anastasis-discover",
+ "This is an application for finding secrets that could be recovered.\n",
+ options,
+ &run,
+ NULL);
+ if (GNUNET_SYSERR == ret)
+ return 3;
+ if (GNUNET_NO == ret)
+ return 0;
+ return global_ret;
+}
+
+
+/* end of anastasis-cli-discover.c */
diff --git a/src/cli/anastasis-cli-redux.c b/src/cli/anastasis-cli-redux.c
index dc9c7ab..e2d2e1d 100644
--- a/src/cli/anastasis-cli-redux.c
+++ b/src/cli/anastasis-cli-redux.c
@@ -1,6 +1,6 @@
/*
This file is part of Anastasis
- Copyright (C) 2020,2021 Anastasis SARL
+ Copyright (C) 2020,2021,2022 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
@@ -41,6 +41,12 @@ static struct GNUNET_CURL_RescheduleContext *rc;
static struct GNUNET_CURL_Context *ctx;
/**
+ * Application ID to include in the user attributes.
+ * (-a option).
+ */
+char *application_id;
+
+/**
* -b option given.
*/
static int b_flag;
@@ -146,6 +152,9 @@ action_cb (void *cls,
"Redux failed with error %d: %s\n",
error_code,
TALER_ErrorCode_get_hint (error_code));
+ json_dumpf (result_state,
+ stderr,
+ JSON_INDENT (2));
}
GNUNET_SCHEDULER_shutdown ();
global_ret = (TALER_EC_NONE != error_code) ? 1 : 0;
@@ -309,6 +318,21 @@ run (void *cls,
&rc);
rc = GNUNET_CURL_gnunet_rc_create (ctx);
ANASTASIS_redux_init (ctx);
+ /* Expand identity_attributes if -a is given explicitly and we
+ are at the respective step of the reduction */
+ if ( (0 == strcasecmp (action,
+ "enter_user_attributes")) &&
+ (NULL != application_id) &&
+ (NULL != arguments) )
+ {
+ json_t *attr = json_object_get (arguments,
+ "identity_attributes");
+ if (NULL != attr)
+ GNUNET_assert (0 ==
+ json_object_set_new (attr,
+ "application-id",
+ json_string (application_id)));
+ }
ra = ANASTASIS_redux_action (prev_state,
action,
arguments,
@@ -324,6 +348,16 @@ main (int argc,
{
/* the available command line options */
struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_option_string ('A',
+ "application",
+ "ID",
+ "set the application ID",
+ &application_id),
+ GNUNET_GETOPT_option_string ('a',
+ "arguments",
+ "JSON",
+ "pass a JSON string containing arguments to reducer",
+ &input),
GNUNET_GETOPT_option_flag ('b',
"backup",
"use reducer to handle states for backup process",
@@ -332,12 +366,6 @@ main (int argc,
"restore",
"use reducer to handle states for restore process",
&r_flag),
- GNUNET_GETOPT_option_string ('a',
- "arguments",
- "JSON",
- "pass a JSON string containing arguments to reducer",
- &input),
-
GNUNET_GETOPT_OPTION_END
};
enum GNUNET_GenericReturnValue ret;
@@ -354,6 +382,7 @@ main (int argc,
options,
&run,
NULL);
+ GNUNET_free (application_id);
if (GNUNET_SYSERR == ret)
return 3;
if (GNUNET_NO == ret)
diff --git a/src/cli/resources/00-backup.json b/src/cli/resources/00-backup.json
index 6e6c320..700f8cd 100644
--- a/src/cli/resources/00-backup.json
+++ b/src/cli/resources/00-backup.json
@@ -2,7 +2,8 @@
"continents": [
"Europe",
"North America",
- "Testcontinent"
+ "Demoworld"
],
- "backup_state": "CONTINENT_SELECTING"
-} \ No newline at end of file
+ "backup_state": "CONTINENT_SELECTING",
+ "reducer_type": "backup"
+}
diff --git a/src/cli/resources/00-recovery.json b/src/cli/resources/00-recovery.json
index acff19a..e9b14f3 100644
--- a/src/cli/resources/00-recovery.json
+++ b/src/cli/resources/00-recovery.json
@@ -4,5 +4,6 @@
"North America",
"Testcontinent"
],
+ "reducer_type": "recovery",
"recovery_state": "CONTINENT_SELECTING"
-} \ No newline at end of file
+}
diff --git a/src/cli/resources/01-backup.json b/src/cli/resources/01-backup.json
index 842d3af..be2a9d9 100644
--- a/src/cli/resources/01-backup.json
+++ b/src/cli/resources/01-backup.json
@@ -2,15 +2,16 @@
"continents": [
"Europe",
"North America",
- "Testcontinent"
+ "Demoworld"
],
"backup_state": "COUNTRY_SELECTING",
- "selected_continent": "Testcontinent",
+ "reducer_type": "backup",
+ "selected_continent": "Demoworld",
"countries": [
{
"code": "xx",
"name": "Testland",
- "continent": "Testcontinent",
+ "continent": "Demoworld",
"continent_i18n": {
"xx": "Testkontinent"
},
@@ -19,23 +20,7 @@
"de_CH": "Testlandi",
"fr": "Testpais",
"en": "Testland"
- },
- "currency": "TESTKUDOS"
- },
- {
- "code": "xy",
- "name": "Demoland",
- "continent": "Testcontinent",
- "continent_i18n": {
- "xx": "Testkontinent"
- },
- "name_i18n": {
- "de_DE": "Demolandt",
- "de_CH": "Demolandi",
- "fr": "Demopais",
- "en": "Demoland"
- },
- "currency": "KUDOS"
+ }
}
]
-} \ No newline at end of file
+}
diff --git a/src/cli/resources/01-recovery.json b/src/cli/resources/01-recovery.json
index 11aafd3..5489814 100644
--- a/src/cli/resources/01-recovery.json
+++ b/src/cli/resources/01-recovery.json
@@ -5,6 +5,7 @@
"Testcontinent"
],
"recovery_state": "COUNTRY_SELECTING",
+ "reducer_type": "recovery",
"selected_continent": "Testcontinent",
"countries": [
{
@@ -38,4 +39,4 @@
"currency": "KUDOS"
}
]
-} \ No newline at end of file
+}
diff --git a/src/cli/resources/02-backup.json b/src/cli/resources/02-backup.json
index c9bba16..a298b69 100644
--- a/src/cli/resources/02-backup.json
+++ b/src/cli/resources/02-backup.json
@@ -2,50 +2,31 @@
"continents": [
"Europe",
"North America",
- "Testcontinent"
+ "Demoworld"
],
"backup_state": "USER_ATTRIBUTES_COLLECTING",
+ "reducer_type": "backup",
"selected_continent": "Testcontinent",
"countries": [
{
"code": "xx",
"name": "Testland",
- "continent": "Testcontinent",
- "continent_i18n": {
- "xx": "Testkontinent"
- },
+ "continent": "Demoworld",
"name_i18n": {
"de_DE": "Testlandt",
"de_CH": "Testlandi",
"fr": "Testpais",
"en": "Testland"
- },
- "currency": "TESTKUDOS"
- },
- {
- "code": "xy",
- "name": "Demoland",
- "continent": "Testcontinent",
- "continent_i18n": {
- "xx": "Testkontinent"
- },
- "name_i18n": {
- "de_DE": "Demolandt",
- "de_CH": "Demolandi",
- "fr": "Demopais",
- "en": "Demoland"
- },
- "currency": "KUDOS"
+ }
}
],
"authentication_providers": {
- "http://localhost:8086/": {},
- "http://localhost:8087/": {},
- "http://localhost:8088/": {},
- "http://localhost:8089/": {}
+ "http://localhost:8086/": { "status" : "not-contacted" },
+ "http://localhost:8087/": { "status" : "not-contacted" },
+ "http://localhost:8088/": { "status" : "not-contacted" },
+ "http://localhost:8089/": { "status" : "not-contacted" }
},
"selected_country": "xx",
- "currencies": [ "TESTKUDOS" ],
"required_attributes": [
{
"type": "string",
diff --git a/src/cli/resources/02-recovery.json b/src/cli/resources/02-recovery.json
index 79cfd6d..875fae0 100644
--- a/src/cli/resources/02-recovery.json
+++ b/src/cli/resources/02-recovery.json
@@ -5,6 +5,7 @@
"Testcontinent"
],
"recovery_state": "USER_ATTRIBUTES_COLLECTING",
+ "reducer_type": "recovery",
"selected_continent": "Testcontinent",
"countries": [
{
@@ -39,10 +40,10 @@
}
],
"authentication_providers": {
- "http://localhost:8086/": {},
- "http://localhost:8087/": {},
- "http://localhost:8088/": {},
- "http://localhost:8089/": {}
+ "http://localhost:8086/": { "status" : "not-contacted" },
+ "http://localhost:8087/": { "status" : "not-contacted" },
+ "http://localhost:8088/": { "status" : "not-contacted" },
+ "http://localhost:8089/": { "status" : "not-contacted" }
},
"selected_country": "xx",
"currencies": [ "TESTKUDOS" ],
diff --git a/src/cli/resources/03-backup.json b/src/cli/resources/03-backup.json
index 4dd5368..15627a9 100644
--- a/src/cli/resources/03-backup.json
+++ b/src/cli/resources/03-backup.json
@@ -2,44 +2,27 @@
"continents": [
"Europe",
"North America",
- "Testcontinent"
+ "Demoworld"
],
"backup_state": "AUTHENTICATIONS_EDITING",
- "selected_continent": "Testcontinent",
+ "reducer_type": "backup",
+ "selected_continent": "Demoworld",
"countries": [
{
"code": "xx",
"name": "Testland",
- "continent": "Testcontinent",
- "continent_i18n": {
- "xx": "Testkontinent"
- },
+ "continent": "Demoworld",
"name_i18n": {
"de_DE": "Testlandt",
"de_CH": "Testlandi",
"fr": "Testpais",
"en": "Testland"
- },
- "currency": "TESTKUDOS"
- },
- {
- "code": "xy",
- "name": "Demoland",
- "continent": "Testcontinent",
- "continent_i18n": {
- "xx": "Testkontinent"
- },
- "name_i18n": {
- "de_DE": "Demolandt",
- "de_CH": "Demolandi",
- "fr": "Demopais",
- "en": "Demoland"
- },
- "currency": "KUDOS"
+ }
}
],
"authentication_providers": {
"http://localhost:8086/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -52,13 +35,13 @@
"truth_lifetime": {
"d_ms": 63115200000
},
- "currency": "TESTKUDOS",
"business_name": "Data loss #1 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "F0HEYJQW81ZAZ3VYMZHFG8T1Z0",
+ "provider_salt": "F0HEYJQW81ZAZ3VYMZHFG8T1Z0",
"http_status": 200
},
"http://localhost:8087/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -71,13 +54,13 @@
"truth_lifetime": {
"d_ms": 63115200000
},
- "currency": "TESTKUDOS",
"business_name": "Data loss #2 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "D378FWXHJB8JHPQFQRZGGV9PWG",
+ "provider_salt": "D378FWXHJB8JHPQFQRZGGV9PWG",
"http_status": 200
},
"http://localhost:8088/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -90,13 +73,13 @@
"truth_lifetime": {
"d_ms": 63115200000
},
- "currency": "TESTKUDOS",
"business_name": "Data loss #3 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "7W9W4A4TTWSWRPJ76RNDPJHSPR",
+ "provider_salt": "7W9W4A4TTWSWRPJ76RNDPJHSPR",
"http_status": 200
},
"http://localhost:8089/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -109,15 +92,13 @@
"truth_lifetime": {
"d_ms": 63115200000
},
- "currency": "TESTKUDOS",
"business_name": "Data loss #4 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "PN0VJF6KDSBYN40SGRCEXPB07M",
+ "provider_salt": "PN0VJF6KDSBYN40SGRCEXPB07M",
"http_status": 200
}
},
"selected_country": "xx",
- "currencies": ["TESTKUDOS"],
"required_attributes": [
{
"type": "string",
diff --git a/src/cli/resources/04-backup.json b/src/cli/resources/04-backup.json
index db51f5a..c7dc6fe 100644
--- a/src/cli/resources/04-backup.json
+++ b/src/cli/resources/04-backup.json
@@ -2,44 +2,27 @@
"continents": [
"Europe",
"North America",
- "Testcontinent"
+ "Demoworld"
],
"backup_state": "AUTHENTICATIONS_EDITING",
- "selected_continent": "Testcontinent",
+ "reducer_type": "backup",
+ "selected_continent": "Demoworld",
"countries": [
{
"code": "xx",
"name": "Testland",
- "continent": "Testcontinent",
- "continent_i18n": {
- "xx": "Testkontinent"
- },
+ "continent": "Demoworld",
"name_i18n": {
"de_DE": "Testlandt",
"de_CH": "Testlandi",
"fr": "Testpais",
"en": "Testland"
- },
- "currency": "TESTKUDOS"
- },
- {
- "code": "xy",
- "name": "Demoland",
- "continent": "Testcontinent",
- "continent_i18n": {
- "xx": "Testkontinent"
- },
- "name_i18n": {
- "de_DE": "Demolandt",
- "de_CH": "Demolandi",
- "fr": "Demopais",
- "en": "Demoland"
- },
- "currency": "KUDOS"
+ }
}
],
"authentication_providers": {
"http://localhost:8086/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -52,13 +35,13 @@
"truth_lifetime": {
"d_ms": 63115200000
},
- "currency": "TESTKUDOS",
"business_name": "Data loss #1 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "F0HEYJQW81ZAZ3VYMZHFG8T1Z0",
+ "provider_salt": "F0HEYJQW81ZAZ3VYMZHFG8T1Z0",
"http_status": 200
},
"http://localhost:8087/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -71,13 +54,13 @@
"truth_lifetime": {
"d_ms": 63115200000
},
- "currency": "TESTKUDOS",
"business_name": "Data loss #2 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "D378FWXHJB8JHPQFQRZGGV9PWG",
+ "provider_salt": "D378FWXHJB8JHPQFQRZGGV9PWG",
"http_status": 200
},
"http://localhost:8088/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -90,13 +73,13 @@
"truth_lifetime": {
"d_ms": 63115200000
},
- "currency": "TESTKUDOS",
"business_name": "Data loss #3 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "7W9W4A4TTWSWRPJ76RNDPJHSPR",
+ "provider_salt": "7W9W4A4TTWSWRPJ76RNDPJHSPR",
"http_status": 200
},
"http://localhost:8089/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -109,10 +92,9 @@
"truth_lifetime": {
"d_ms": 63115200000
},
- "currency": "TESTKUDOS",
"business_name": "Data loss #4 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "PN0VJF6KDSBYN40SGRCEXPB07M",
+ "provider_salt": "PN0VJF6KDSBYN40SGRCEXPB07M",
"http_status": 200
}
},
diff --git a/src/cli/resources/05-backup.json b/src/cli/resources/05-backup.json
index 143d9e3..c8f52f0 100644
--- a/src/cli/resources/05-backup.json
+++ b/src/cli/resources/05-backup.json
@@ -5,6 +5,7 @@
"Testcontinent"
],
"backup_state": "POLICIES_REVIEWING",
+ "reducer_type": "backup",
"selected_continent": "Testcontinent",
"countries": [
{
@@ -40,6 +41,7 @@
],
"authentication_providers": {
"http://localhost:8086/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -55,10 +57,11 @@
"currency": "TESTKUDOS",
"business_name": "Data loss #1 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "F0HEYJQW81ZAZ3VYMZHFG8T1Z0",
+ "provider_salt": "F0HEYJQW81ZAZ3VYMZHFG8T1Z0",
"http_status": 200
},
"http://localhost:8087/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -74,10 +77,11 @@
"currency": "TESTKUDOS",
"business_name": "Data loss #2 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "D378FWXHJB8JHPQFQRZGGV9PWG",
+ "provider_salt": "D378FWXHJB8JHPQFQRZGGV9PWG",
"http_status": 200
},
"http://localhost:8088/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -93,10 +97,11 @@
"currency": "TESTKUDOS",
"business_name": "Data loss #3 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "7W9W4A4TTWSWRPJ76RNDPJHSPR",
+ "provider_salt": "7W9W4A4TTWSWRPJ76RNDPJHSPR",
"http_status": 200
},
"http://localhost:8089/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -112,7 +117,7 @@
"currency": "TESTKUDOS",
"business_name": "Data loss #4 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "PN0VJF6KDSBYN40SGRCEXPB07M",
+ "provider_salt": "PN0VJF6KDSBYN40SGRCEXPB07M",
"http_status": 200
}
},
diff --git a/src/cli/resources/06-backup.json b/src/cli/resources/06-backup.json
index 9944a17..04d8b02 100644
--- a/src/cli/resources/06-backup.json
+++ b/src/cli/resources/06-backup.json
@@ -5,6 +5,7 @@
"Testcontinent"
],
"backup_state": "SECRET_EDITING",
+ "reducer_type": "backup",
"selected_continent": "Testcontinent",
"countries": [
{
@@ -40,6 +41,7 @@
],
"authentication_providers": {
"http://localhost:8086/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -55,10 +57,11 @@
"currency": "TESTKUDOS",
"business_name": "Data loss #1 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "F0HEYJQW81ZAZ3VYMZHFG8T1Z0",
+ "provider_salt": "F0HEYJQW81ZAZ3VYMZHFG8T1Z0",
"http_status": 200
},
"http://localhost:8087/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -74,10 +77,11 @@
"currency": "TESTKUDOS",
"business_name": "Data loss #2 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "D378FWXHJB8JHPQFQRZGGV9PWG",
+ "provider_salt": "D378FWXHJB8JHPQFQRZGGV9PWG",
"http_status": 200
},
"http://localhost:8088/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -93,10 +97,11 @@
"currency": "TESTKUDOS",
"business_name": "Data loss #3 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "7W9W4A4TTWSWRPJ76RNDPJHSPR",
+ "provider_salt": "7W9W4A4TTWSWRPJ76RNDPJHSPR",
"http_status": 200
},
"http://localhost:8089/": {
+ "status" : "ok",
"methods": [
{
"type": "question",
@@ -112,7 +117,7 @@
"currency": "TESTKUDOS",
"business_name": "Data loss #4 Inc.",
"storage_limit_in_megabytes": 1,
- "salt": "PN0VJF6KDSBYN40SGRCEXPB07M",
+ "provider_salt": "PN0VJF6KDSBYN40SGRCEXPB07M",
"http_status": 200
}
},
diff --git a/src/cli/setup.sh b/src/cli/setup.sh
new file mode 100755
index 0000000..6d26168
--- /dev/null
+++ b/src/cli/setup.sh
@@ -0,0 +1,72 @@
+#!/bin/sh
+# This file is in the public domain
+
+# Script to be inlined into the main test scripts. Defines function 'setup()'
+# which wraps around 'taler-unified-setup.sh' to launch GNU Taler services.
+# Call setup() with the arguments to pass to 'taler-unified-setup'. setup()
+# will then launch GNU Taler, wait for the process to be complete before
+# returning. The script will also install an exit handler to ensure the GNU
+# Taler processes are stopped when the shell exits.
+
+set -eu
+
+# Cleanup to run whenever we exit
+function exit_cleanup()
+{
+ if [ ! -z ${SETUP_PID+x} ]
+ then
+ echo "Killing taler-unified-setup ($SETUP_PID)" >&2
+ kill -TERM "$SETUP_PID" 2> /dev/null || true
+ wait "$SETUP_PID" 2> /dev/null || true
+ fi
+}
+
+# Install cleanup handler (except for kill -9)
+trap exit_cleanup EXIT
+
+function setup()
+{
+ echo "Starting test system ..." >&2
+ # Create a named pipe in a temp directory we own.
+ FIFO_DIR=$(mktemp -p "${TMPDIR:-/tmp}" -d fifo-XXXXXX)
+ FIFO_OUT=$(echo "$FIFO_DIR/out")
+ mkfifo "$FIFO_OUT"
+ # Open pipe as FD 3 (RW) and FD 4 (RO)
+ exec 3<> "$FIFO_OUT" 4< "$FIFO_OUT"
+ rm -rf "$FIFO_DIR"
+ # We require '-W' for our termination logic to work.
+ taler-unified-setup.sh -W "$@" >&3 &
+ SETUP_PID=$!
+ # Close FD3
+ exec 3>&-
+ sed -u '/<<READY>>/ q' <&4
+ # Close FD4
+ exec 4>&-
+ echo "Test system ready" >&2
+}
+
+# Exit, with status code "skip" (no 'real' failure)
+function exit_fail() {
+ echo "$@" >&2
+ exit 1
+}
+
+# Exit, with status code "skip" (no 'real' failure)
+function exit_skip() {
+ echo "SKIPPING: $1"
+ exit 77
+}
+
+function get_payto_uri() {
+ export LIBEUFIN_SANDBOX_USERNAME="$1"
+ export LIBEUFIN_SANDBOX_PASSWORD="$2"
+ export LIBEUFIN_SANDBOX_URL="http://localhost:18082"
+ libeufin-cli sandbox demobank info --bank-account "$1" | jq --raw-output '.paytoUri'
+}
+
+function get_bankaccount_transactions() {
+ export LIBEUFIN_SANDBOX_USERNAME=$1
+ export LIBEUFIN_SANDBOX_PASSWORD=$2
+ export LIBEUFIN_SANDBOX_URL="http://localhost:18082"
+ libeufin-cli sandbox demobank list-transactions --bank-account $1
+}
diff --git a/src/cli/test_anastasis_reducer_1.conf b/src/cli/test_anastasis_reducer_1.conf
index 3a05690..2a3a0e4 100644
--- a/src/cli/test_anastasis_reducer_1.conf
+++ b/src/cli/test_anastasis_reducer_1.conf
@@ -3,7 +3,7 @@
[anastasis]
PORT = 8086
-SERVER_SALT = AUfO1KGOKYIFlFQg
+PROVIDER_SALT = AUfO1KGOKYIFlFQg
BUSINESS_NAME = "Data loss #1 Inc."
[stasis-postgres]
diff --git a/src/cli/test_anastasis_reducer_2.conf b/src/cli/test_anastasis_reducer_2.conf
index 4eef5f0..71b133f 100644
--- a/src/cli/test_anastasis_reducer_2.conf
+++ b/src/cli/test_anastasis_reducer_2.conf
@@ -3,7 +3,7 @@
[anastasis]
PORT = 8087
-SERVER_SALT = BUfO1KGOKYIFlFQg
+PROVIDER_SALT = BUfO1KGOKYIFlFQg
BUSINESS_NAME = "Data loss #2 Inc."
[stasis-postgres]
diff --git a/src/cli/test_anastasis_reducer_3.conf b/src/cli/test_anastasis_reducer_3.conf
index 08f4700..47233ff 100644
--- a/src/cli/test_anastasis_reducer_3.conf
+++ b/src/cli/test_anastasis_reducer_3.conf
@@ -3,7 +3,7 @@
[anastasis]
PORT = 8088
-SERVER_SALT = CUfO1KGOKYIFlFQg
+PROVIDER_SALT = CUfO1KGOKYIFlFQg
BUSINESS_NAME = "Data loss #3 Inc."
[stasis-postgres]
diff --git a/src/cli/test_anastasis_reducer_4.conf b/src/cli/test_anastasis_reducer_4.conf
index dee90e3..f515a78 100644
--- a/src/cli/test_anastasis_reducer_4.conf
+++ b/src/cli/test_anastasis_reducer_4.conf
@@ -3,7 +3,7 @@
[anastasis]
PORT = 8089
-SERVER_SALT = DUfO1KGOKYIFlFQg
+PROVIDER_SALT = DUfO1KGOKYIFlFQg
BUSINESS_NAME = "Data loss #4 Inc."
[stasis-postgres]
diff --git a/src/cli/test_anastasis_reducer_backup_enter_user_attributes.sh b/src/cli/test_anastasis_reducer_backup_enter_user_attributes.sh
index b8662e8..8a04b0a 100755
--- a/src/cli/test_anastasis_reducer_backup_enter_user_attributes.sh
+++ b/src/cli/test_anastasis_reducer_backup_enter_user_attributes.sh
@@ -126,16 +126,6 @@ fi
echo "OK"
-echo -n "Test user attributes collection in a recovery state ..."
-anastasis-reducer -a \
- '{"identity_attributes": {
- "full_name": "Max Musterman",
- "sq_number": "4",
- "birthdate": "2000-01-01"}}' \
- enter_user_attributes resources/02-recovery.json $TFILE 2> /dev/null && exit_fail "Expected recovery to fail due to lacking policy data"
-
-echo "OK"
-
rm -f $TFILE
exit 0
diff --git a/src/cli/test_anastasis_reducer_done_authentication.sh b/src/cli/test_anastasis_reducer_done_authentication.sh
index 87c738c..545c733 100755
--- a/src/cli/test_anastasis_reducer_done_authentication.sh
+++ b/src/cli/test_anastasis_reducer_done_authentication.sh
@@ -46,9 +46,9 @@ echo " OK"
echo -n "Test done authentication (next) ..."
-anastasis-reducer next resources/04-backup.json $TFILE
+anastasis-reducer next resources/04-backup.json "$TFILE"
-STATE=`jq -r -e .backup_state < $TFILE`
+STATE=$(jq -r -e .backup_state < "$TFILE")
if test "$STATE" != "POLICIES_REVIEWING"
then
exit_fail "Expected new state to be AUTHENTICATIONS_EDITING, got $STATE"
diff --git a/src/cli/test_anastasis_reducer_enter_secret.sh b/src/cli/test_anastasis_reducer_enter_secret.sh
index 8005f08..3b25537 100755
--- a/src/cli/test_anastasis_reducer_enter_secret.sh
+++ b/src/cli/test_anastasis_reducer_enter_secret.sh
@@ -1,6 +1,7 @@
#!/bin/bash
# This file is in the public domain.
+# shellcheck disable=SC2317
## Coloring style Text shell script
COLOR='\033[0;35m'
NOCOLOR='\033[0m'
@@ -9,46 +10,22 @@ NORM="$(tput sgr0)"
set -eu
-# Exit, with status code "skip" (no 'real' failure)
-function exit_skip() {
- echo " SKIP: $1"
- exit 77
-}
-
-# Exit, with error message (hard failure)
-function exit_fail() {
- echo " FAIL: $1"
- exit 1
-}
-
-# Cleanup to run whenever we exit
-function cleanup()
-{
- for n in `jobs -p`
- do
- kill $n 2> /dev/null || true
- done
- rm -rf $CONF $WALLET_DB $TFILE $UFILE $TMP_DIR
- wait
-}
-
-CONF_1="test_anastasis_reducer_1.conf"
-CONF_2="test_anastasis_reducer_2.conf"
-CONF_3="test_anastasis_reducer_3.conf"
-CONF_4="test_anastasis_reducer_4.conf"
-
-# Exchange configuration file will be edited, so we create one
-# from the template.
-CONF=`mktemp test_reducerXXXXXX.conf`
-cp test_reducer.conf $CONF
-
-TMP_DIR=`mktemp -d keys-tmp-XXXXXX`
-WALLET_DB=`mktemp test_reducer_walletXXXXXX.json`
-TFILE=`mktemp test_reducer_statePPXXXXXX`
-UFILE=`mktemp test_reducer_stateBFXXXXXX`
-
-# Install cleanup handler (except for kill -9)
-trap cleanup EXIT
+# Replace with 0 for nexus...
+USE_FAKEBANK=1
+if [ 1 = "$USE_FAKEBANK" ]
+then
+ ACCOUNT="exchange-account-2"
+ WIRE_METHOD="x-taler-bank"
+ BANK_FLAGS="-f -d $WIRE_METHOD -u $ACCOUNT"
+ BANK_URL="http://localhost:18082/"
+ MERCHANT_PAYTO="payto://x-taler-bank/localhost/anastasis?receiver-name=anastasis"
+else
+ ACCOUNT="exchange-account-1"
+ WIRE_METHOD="iban"
+ BANK_FLAGS="-ns -d $WIRE_METHOD -u $ACCOUNT"
+ BANK_URL="http://localhost:18082/"
+ MERCHANT_PAYTO="payto://iban/SANDBOXX/DE648226?receiver-name=anastasis"
+fi
# Check we can actually run
echo -n "Testing for jq"
@@ -63,9 +40,6 @@ taler-exchange-httpd -h > /dev/null || exit_skip " taler-exchange required"
taler-merchant-httpd -h > /dev/null || exit_skip " taler-merchant required"
echo " FOUND"
-echo -n "Testing for taler-bank-manage"
-taler-bank-manage --help >/dev/null </dev/null || exit_skip " MISSING"
-echo " FOUND"
echo -n "Testing for taler-wallet-cli"
taler-wallet-cli -v >/dev/null </dev/null || exit_skip " MISSING"
echo " FOUND"
@@ -74,87 +48,65 @@ echo -n "Testing for anastasis-httpd"
anastasis-httpd -h >/dev/null </dev/null || exit_skip " MISSING"
echo " FOUND"
-echo -n "Initialize anastasis database ..."
-# Name of the Postgres database we will use for the script.
-# Will be dropped, do NOT use anything that might be used
-# elsewhere
-TARGET_DB_1=`anastasis-config -c $CONF_1 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
-TARGET_DB_2=`anastasis-config -c $CONF_2 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
-TARGET_DB_3=`anastasis-config -c $CONF_3 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
-TARGET_DB_4=`anastasis-config -c $CONF_4 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
-
-dropdb $TARGET_DB_1 >/dev/null 2>/dev/null || true
-createdb $TARGET_DB_1 || exit_skip "Could not create database $TARGET_DB_1"
-anastasis-dbinit -c $CONF_1 2> anastasis-dbinit_1.log
-dropdb $TARGET_DB_2 >/dev/null 2>/dev/null || true
-createdb $TARGET_DB_2 || exit_skip "Could not create database $TARGET_DB_2"
-anastasis-dbinit -c $CONF_2 2> anastasis-dbinit_2.log
-dropdb $TARGET_DB_3 >/dev/null 2>/dev/null || true
-createdb $TARGET_DB_3 || exit_skip "Could not create database $TARGET_DB_3"
-anastasis-dbinit -c $CONF_3 2> anastasis-dbinit_3.log
-dropdb $TARGET_DB_4 >/dev/null 2>/dev/null || true
-createdb $TARGET_DB_4 || exit_skip "Could not create database $TARGET_DB_4"
-anastasis-dbinit -c $CONF_4 2> anastasis-dbinit_4.log
+. setup.sh
+# Launch exchange, merchant and bank.
+# shellcheck disable=SC2086
+setup -c "test_reducer.conf" \
+ -aemw \
+ $BANK_FLAGS
-echo " OK"
-echo -n "Generating Taler auditor, exchange and merchant configurations ..."
-
-DATA_DIR=`taler-config -f -c $CONF -s PATHS -o TALER_HOME`
-rm -rf $DATA_DIR
-
-# obtain key configuration data
-MASTER_PRIV_FILE=`taler-config -f -c $CONF -s "EXCHANGE-OFFLINE" -o "MASTER_PRIV_FILE"`
-MASTER_PRIV_DIR=`dirname $MASTER_PRIV_FILE`
-mkdir -p $MASTER_PRIV_DIR
-gnunet-ecc -g1 $MASTER_PRIV_FILE > /dev/null 2> /dev/null
-MASTER_PUB=`gnunet-ecc -p $MASTER_PRIV_FILE`
-EXCHANGE_URL=`taler-config -c $CONF -s EXCHANGE -o BASE_URL`
-MERCHANT_PORT=`taler-config -c $CONF -s MERCHANT -o PORT`
-MERCHANT_URL=http://localhost:${MERCHANT_PORT}/
-BANK_PORT=`taler-config -c $CONF -s BANK -o HTTP_PORT`
-BANK_URL=http://localhost:${BANK_PORT}/
-AUDITOR_URL=http://localhost:8083/
-AUDITOR_PRIV_FILE=`taler-config -f -c $CONF -s AUDITOR -o AUDITOR_PRIV_FILE`
-AUDITOR_PRIV_DIR=`dirname $AUDITOR_PRIV_FILE`
-mkdir -p $AUDITOR_PRIV_DIR
-gnunet-ecc -g1 $AUDITOR_PRIV_FILE > /dev/null 2> /dev/null
-AUDITOR_PUB=`gnunet-ecc -p $AUDITOR_PRIV_FILE`
-
-# patch configuration
-TALER_DB=talercheck
-taler-config -c $CONF -s exchange -o MASTER_PUBLIC_KEY -V $MASTER_PUB
-taler-config -c $CONF -s merchant-exchange-default -o MASTER_KEY -V $MASTER_PUB
-taler-config -c $CONF -s exchangedb-postgres -o CONFIG -V postgres:///$TALER_DB
-taler-config -c $CONF -s auditordb-postgres -o CONFIG -V postgres:///$TALER_DB
-taler-config -c $CONF -s merchantdb-postgres -o CONFIG -V postgres:///$TALER_DB
-taler-config -c $CONF -s bank -o database -V postgres:///$TALER_DB
-taler-config -c $CONF -s exchange -o KEYDIR -V "${TMP_DIR}/keydir/"
-taler-config -c $CONF -s exchange -o REVOCATION_DIR -V "${TMP_DIR}/revdir/"
+# Cleanup to run whenever we exit
+function cleanup()
+{
+ exit_cleanup
+ for n in $(jobs -p)
+ do
+ kill "$n" 2> /dev/null || true
+ done
+ rm -rf "$CONF" "$WALLET_DB" "$TFILE" "$UFILE" "$TMP_DIR"
+ wait
+}
-echo " OK"
+CONF_1="test_anastasis_reducer_1.conf"
+CONF_2="test_anastasis_reducer_2.conf"
+CONF_3="test_anastasis_reducer_3.conf"
+CONF_4="test_anastasis_reducer_4.conf"
-echo -n "Setting up exchange ..."
+# Exchange configuration file will be edited, so we create one
+# from the template.
+CONF="test_reducer.conf.edited"
-# reset database
-dropdb $TALER_DB >/dev/null 2>/dev/null || true
-createdb $TALER_DB || exit_skip "Could not create database $TALER_DB"
-taler-exchange-dbinit -c $CONF
-taler-merchant-dbinit -c $CONF
-taler-auditor-dbinit -c $CONF
-taler-auditor-exchange -c $CONF -m $MASTER_PUB -u $EXCHANGE_URL
+TMP_DIR=$(mktemp -p "${TMPDIR:-/tmp}" -d keys-tmp-XXXXXX)
+WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_walletXXXXXX.json)
+TFILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_statePPXXXXXX)
+UFILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_stateBFXXXXXX)
-echo " OK"
+# Install cleanup handler (except for kill -9)
+trap cleanup EXIT
-# Launch services
-echo -n "Launching taler services ..."
-taler-bank-manage-testing $CONF postgres:///$TALER_DB serve > taler-bank.log 2> taler-bank.err &
-taler-exchange-secmod-eddsa -c $CONF 2> taler-exchange-secmod-eddsa.log &
-taler-exchange-secmod-rsa -c $CONF 2> taler-exchange-secmod-rsa.log &
-taler-exchange-httpd -c $CONF 2> taler-exchange-httpd.log &
-taler-merchant-httpd -c $CONF -L INFO 2> taler-merchant-httpd.log &
-taler-exchange-wirewatch -c $CONF 2> taler-exchange-wirewatch.log &
-taler-auditor-httpd -L INFO -c $CONF 2> taler-auditor-httpd.log &
+
+echo -n "Initialize anastasis databases ..."
+# Name of the Postgres database we will use for the script.
+# Will be dropped, do NOT use anything that might be used
+# elsewhere
+TARGET_DB_1=$(anastasis-config -c "$CONF_1" -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///")
+TARGET_DB_2=$(anastasis-config -c "$CONF_2" -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///")
+TARGET_DB_3=$(anastasis-config -c "$CONF_3" -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///")
+TARGET_DB_4=$(anastasis-config -c "$CONF_4" -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///")
+
+dropdb "$TARGET_DB_1" >/dev/null 2>/dev/null || true
+createdb "$TARGET_DB_1" || exit_skip "Could not create database $TARGET_DB_1"
+anastasis-dbinit -c "$CONF_1" 2> anastasis-dbinit_1.log
+dropdb "$TARGET_DB_2" >/dev/null 2>/dev/null || true
+createdb "$TARGET_DB_2" || exit_skip "Could not create database $TARGET_DB_2"
+anastasis-dbinit -c "$CONF_2" 2> anastasis-dbinit_2.log
+dropdb "$TARGET_DB_3" >/dev/null 2>/dev/null || true
+createdb "$TARGET_DB_3" || exit_skip "Could not create database $TARGET_DB_3"
+anastasis-dbinit -c "$CONF_3" 2> anastasis-dbinit_3.log
+dropdb "$TARGET_DB_4" >/dev/null 2>/dev/null || true
+createdb "$TARGET_DB_4" || exit_skip "Could not create database $TARGET_DB_4"
+anastasis-dbinit -c "$CONF_4" 2> anastasis-dbinit_4.log
echo " OK"
@@ -165,82 +117,9 @@ $PREFIX anastasis-httpd -c $CONF_2 2> anastasis-httpd_2.log &
$PREFIX anastasis-httpd -c $CONF_3 2> anastasis-httpd_3.log &
$PREFIX anastasis-httpd -c $CONF_4 2> anastasis-httpd_4.log &
-# Wait for bank to be available (usually the slowest)
-for n in `seq 1 50`
-do
- echo -n "."
- sleep 0.2
- OK=0
- # bank
- wget --tries=1 --timeout=1 http://localhost:8082/ -o /dev/null -O /dev/null >/dev/null || continue
- OK=1
- break
-done
-
-if [ 1 != $OK ]
-then
- exit_skip "Failed to launch services (bank)"
-fi
-
-# Wait for all other taler services to be available
-for n in `seq 1 50`
-do
- echo -n "."
- sleep 0.1
- OK=0
- # exchange
- wget --tries=1 --timeout=1 http://localhost:8081/seed -o /dev/null -O /dev/null >/dev/null || continue
- # merchant
- wget --tries=1 --timeout=1 http://localhost:9966/ -o /dev/null -O /dev/null >/dev/null || continue
- # auditor
- wget --tries=1 --timeout=1 http://localhost:8083/ -o /dev/null -O /dev/null >/dev/null || continue
- OK=1
- break
-done
-
-if [ 1 != $OK ]
-then
- exit_skip "Failed to launch taler services"
-fi
-
-echo "OK"
-
-echo -n "Setting up keys ..."
-taler-exchange-offline -c $CONF \
- download \
- sign \
- enable-account payto://x-taler-bank/localhost/Exchange \
- enable-auditor $AUDITOR_PUB $AUDITOR_URL "TESTKUDOS Auditor" \
- wire-fee now x-taler-bank TESTKUDOS:0.01 TESTKUDOS:0.01 \
- upload &> taler-exchange-offline.log
-
-echo -n "."
-
-for n in `seq 1 3`
-do
- echo -n "."
- OK=0
- wget --tries=1 --timeout=1 http://localhost:8081/keys -o /dev/null -O /dev/null >/dev/null || continue
- OK=1
- break
-done
-
-if [ 1 != $OK ]
-then
- exit_skip "Failed to setup keys"
-fi
-
-echo " OK"
-
-echo -n "Setting up auditor signatures ..."
-taler-auditor-offline -c $CONF \
- download sign upload &> taler-auditor-offline.log
-echo " OK"
-
echo -n "Waiting for anastasis services ..."
-
# Wait for anastasis services to be available
-for n in `seq 1 50`
+for n in $(seq 1 50)
do
echo -n "."
sleep 0.1
@@ -257,7 +136,7 @@ do
break
done
-if [ 1 != $OK ]
+if [ 1 != "$OK" ]
then
exit_skip "Failed to launch anastasis services"
fi
@@ -266,154 +145,193 @@ echo "OK"
echo -n "Configuring merchant instance ..."
# Setup merchant
-curl -H "Content-Type: application/json" -X POST -d '{"auth":{"method":"external"},"payto_uris":["payto://x-taler-bank/localhost/43"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_ms" : 3600000},"default_pay_delay":{"d_ms": 3600000}}' http://localhost:9966/management/instances
+curl -H "Content-Type: application/json" -X POST -d '{"auth":{"method":"external"},"id":"default","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' http://localhost:9966/management/instances
+
+
+curl -H "Content-Type: application/json" -X POST -d '{"payto_uri":"'"$MERCHANT_PAYTO"'"}' http://localhost:9966/private/accounts
+
echo " DONE"
-echo -en $COLOR$BOLD"Test enter secret in a backup state ..."$NORM$NOCOLOR
+echo -en "${COLOR}${BOLD}Test enter secret in a backup state ...${NORM}${NOCOLOR}"
$PREFIX anastasis-reducer -a \
'{"secret": { "value" : "veryhardtoguesssecret", "mime" : "text/plain" } }' \
- enter_secret resources/06-backup.json $TFILE
+ enter_secret resources/06-backup.json "$TFILE"
-STATE=`jq -r -e .backup_state < $TFILE`
-if test "$STATE" != "SECRET_EDITING"
+STATE=$(jq -r -e .backup_state < "$TFILE")
+if [ "$STATE" != "SECRET_EDITING" ]
then
- jq -e . $TFILE
+ jq -e . "$TFILE"
exit_fail "Expected new state to be 'SECRET_EDITING', got '$STATE'"
fi
echo " DONE"
-echo -en $COLOR$BOLD"Test expiration change ..."$NORM$NOCOLOR
+echo -en "${COLOR}${BOLD}Test expiration change ...${NORM}${NOCOLOR}"
-MILLIS=`date '+%s'`000
+SECS=$(date '+%s')
# Use 156 days into the future to get 1 year
-MILLIS=`expr $MILLIS + 13478400000`
+SECS=$(( SECS + 13478400 ))
$PREFIX anastasis-reducer -a \
"$(jq -n '
- {"expiration": { "t_ms" : $MSEC } }' \
- --argjson MSEC $MILLIS
+ {"expiration": { "t_s" : $SEC } }' \
+ --argjson SEC "$SECS"
)" \
- update_expiration $TFILE $UFILE
+ update_expiration "$TFILE" "$UFILE"
-STATE=`jq -r -e .backup_state < $UFILE`
+STATE=$(jq -r -e .backup_state < "$UFILE")
if test "$STATE" != "SECRET_EDITING"
then
- jq -e . $UFILE
+ jq -e . "$UFILE"
exit_fail "Expected new state to be 'SECRET_EDITING', got '$STATE'"
fi
-FEES=`jq -r -e '.upload_fees[0].fee' < $UFILE`
+FEES=$(jq -r -e '.upload_fees[0].fee' < "$UFILE")
# 4x 4.99 for annual fees, plus 4x0.01 for truth uploads
-if test "$FEES" != "TESTKUDOS:20"
+if [ "$FEES" != "TESTKUDOS:20" ]
then
- jq -e . $TFILE
+ jq -e . "$UFILE"
exit_fail "Expected upload fees to be 'TESTKUDOS:20', got '$FEES'"
fi
echo " DONE"
-echo -en $COLOR$BOLD"Test advance to payment ..."$NORM$NOCOLOR
+echo -en "${COLOR}${BOLD}Test advance to payment ...${NORM}${NOCOLOR}"
-$PREFIX anastasis-reducer next $UFILE $TFILE
+$PREFIX anastasis-reducer next "$UFILE" "$TFILE"
-STATE=`jq -r -e .backup_state < $TFILE`
-if test "$STATE" != "TRUTHS_PAYING"
+STATE=$(jq -r -e .backup_state < "$TFILE")
+if [ "$STATE" != "TRUTHS_PAYING" ]
then
- jq -e . $TFILE
+ jq -e . "$TFILE"
exit_fail "Expected new state to be 'TRUTHS_PAYING', got '$STATE'"
fi
-TMETHOD=`jq -r -e '.policies[0].methods[0].truth.type' < $TFILE`
-if test $TMETHOD != "question"
-then
- exit_fail "Expected method to be >='question', got $TMETHOD"
-fi
+# FIXME: this test is specific to how the
+# C reducer stores state (redundantly!), should converge eventually!
+
+#TMETHOD=$(jq -r -e '.policies[0].methods[0].truth.type' < $TFILE)
+#if test $TMETHOD != "question"
+#then
+# exit_fail "Expected method to be >='question', got $TMETHOD"
+#fi
+#
+#echo " OK"
+
-echo " OK"
#Pay
-echo -en $COLOR$BOLD"Withdrawing amount to wallet ..."$NORM$NOCOLOR
+echo -en "${COLOR}${BOLD}Withdrawing amount to wallet ...${NORM}${NOCOLOR}"
+
+EXCHANGE_URL="$(taler-config -c "$CONF" -s exchange -o BASE_URL)"
-rm $WALLET_DB
-taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api 'withdrawTestBalance' \
+rm "$WALLET_DB"
+taler-wallet-cli \
+ --no-throttle \
+ --wallet-db="$WALLET_DB" \
+ api \
+ --expect-success 'withdrawTestBalance' \
"$(jq -n '
{
amount: "TESTKUDOS:40",
- bankBaseUrl: $BANK_URL,
+ corebankApiBaseUrl: $BANK_URL,
exchangeBaseUrl: $EXCHANGE_URL
}' \
- --arg BANK_URL "$BANK_URL" \
- --arg EXCHANGE_URL "$EXCHANGE_URL"
- )" 2>wallet.err >wallet.log
-taler-wallet-cli --wallet-db=$WALLET_DB run-until-done 2>wallet.err >wallet.log
+ --arg BANK_URL "${BANK_URL}" \
+ --arg EXCHANGE_URL "${EXCHANGE_URL}"
+ )" 2>wallet-withdraw.err \
+ >wallet-withdraw.log
+taler-wallet-cli \
+ --no-throttle \
+ --wallet-db="$WALLET_DB" \
+ run-until-done \
+ 2>wallet-withdraw-finish.err \
+ >wallet-withdraw-finish.log
echo " OK"
-echo -en $COLOR$BOLD"Making payments for truth uploads ... "$NORM$NOCOLOR
-OBJECT_SIZE=`jq -r -e '.payments | length' < $TFILE`
-for ((INDEX=0; INDEX < $OBJECT_SIZE; INDEX++))
+echo -en "${COLOR}${BOLD}Making payments for truth uploads ... ${NORM}${NOCOLOR}"
+OBJECT_SIZE=$(jq -r -e '.payments | length' < "$TFILE")
+for ((INDEX=0; INDEX < "$OBJECT_SIZE"; INDEX++))
do
- PAY_URI=`jq --argjson INDEX $INDEX -r -e '.payments[$INDEX]' < $TFILE`
+ PAY_URI=$(jq --argjson INDEX $INDEX -r -e '.payments[$INDEX]' < "$TFILE")
# run wallet CLI
echo -n "$INDEX"
- taler-wallet-cli --wallet-db=$WALLET_DB handle-uri $PAY_URI -y 2>wallet.err >wallet.log
+ taler-wallet-cli \
+ --no-throttle \
+ --wallet-db="$WALLET_DB" \
+ handle-uri "${PAY_URI}" \
+ -y \
+ 2>wallet-pay1.err \
+ >wallet-pay1.log
echo -n ","
done
echo " OK"
-echo -e $COLOR$BOLD"Running wallet run-pending..."$NORM$NOCOLOR
-taler-wallet-cli --wallet-db=$WALLET_DB run-pending 2>wallet.err >wallet.log
-echo -e $COLOR$BOLD"Payments done"$NORM$NOCOLOR
-
-
-echo -en $COLOR$BOLD"Try to upload again ..."$NORM$NOCOLOR
-$PREFIX anastasis-reducer pay $TFILE $UFILE
-mv $UFILE $TFILE
+echo -e "${COLOR}${BOLD}Running wallet run-until-done...${NORM}${NOCOLOR}"
+taler-wallet-cli \
+ --wallet-db="$WALLET_DB" \
+ run-until-done \
+ 2>wallet-pay-finish.err \
+ >wallet-pay-finish.log
+echo -e "${COLOR}${BOLD}Payments done${NORM}${NOCOLOR}"
+
+
+echo -en "${COLOR}${BOLD}Try to upload again ...${NORM}${NOCOLOR}"
+$PREFIX anastasis-reducer pay "$TFILE" "$UFILE"
+mv "$UFILE" "$TFILE"
echo " OK"
-STATE=`jq -r -e .backup_state < $TFILE`
-if test "$STATE" != "POLICIES_PAYING"
+STATE="$(jq -r -e .backup_state < "$TFILE")"
+if [ "$STATE" != "POLICIES_PAYING" ]
then
exit_fail "Expected new state to be 'POLICIES_PAYING', got '$STATE'"
fi
-export TFILE
-export UFILE
-
-echo -en $COLOR$BOLD"Making payments for policy uploads ... "$NORM$NOCOLOR
-OBJECT_SIZE=`jq -r -e '.policy_payment_requests | length' < $TFILE`
-for ((INDEX=0; INDEX < $OBJECT_SIZE; INDEX++))
+echo -en "${COLOR}${BOLD}Making payments for policy uploads ... ${NORM}${NOCOLOR}"
+OBJECT_SIZE="$(jq -r -e '.policy_payment_requests | length' < "$TFILE")"
+for ((INDEX=0; INDEX < "$OBJECT_SIZE"; INDEX++))
do
- PAY_URI=`jq --argjson INDEX $INDEX -r -e '.policy_payment_requests[$INDEX].payto' < $TFILE`
+ PAY_URI="$(jq --argjson INDEX "$INDEX" -r -e '.policy_payment_requests[$INDEX].payto' < "$TFILE")"
# run wallet CLI
export PAY_URI
echo -n "$INDEX"
- taler-wallet-cli --wallet-db=$WALLET_DB handle-uri $PAY_URI -y 2>wallet.err >wallet.log
+ taler-wallet-cli \
+ --wallet-db="$WALLET_DB" \
+ handle-uri "$PAY_URI" \
+ -y \
+ 2>"wallet-pay2-$INDEX.err" \
+ >"wallet-pay2-$INDEX.log"
echo -n ","
done
echo " OK"
-echo -e $COLOR$BOLD"Running wallet run-pending..."$NORM$NOCOLOR
-taler-wallet-cli --wallet-db=$WALLET_DB run-pending 2>wallet.err >wallet.log
-echo -e $COLOR$BOLD"Payments done"$NORM$NOCOLOR
+echo -e "${COLOR}${BOLD}Running wallet run-until-done...${NORM}${NOCOLOR}"
+taler-wallet-cli \
+ --wallet-db="$WALLET_DB" \
+ run-until-done \
+ 2>wallet-pay2-finish.err \
+ >wallet-pay2-finish.log
+echo -e "${COLOR}${BOLD}Payments done${NORM}${NOCOLOR}"
-echo -en $COLOR$BOLD"Try to upload again ..."$NORM$NOCOLOR
-$PREFIX anastasis-reducer pay $TFILE $UFILE
+echo -en "${COLOR}${BOLD}Try to upload again ...${NORM}${NOCOLOR}"
+$PREFIX anastasis-reducer pay "$TFILE" "$UFILE"
echo " OK"
echo -n "Final checks ..."
-STATE=`jq -r -e .backup_state < $UFILE`
-if test "$STATE" != "BACKUP_FINISHED"
+STATE=$(jq -r -e .backup_state < "$UFILE")
+if [ "$STATE" != "BACKUP_FINISHED" ]
then
exit_fail "Expected new state to be BACKUP_FINISHED, got $STATE"
fi
-jq -r -e .core_secret < $UFILE > /dev/null && exit_fail "'core_secret' was not cleared upon success"
+jq -r -e .core_secret \
+ < "$UFILE" \
+ > /dev/null \
+ && exit_fail "'core_secret' was not cleared upon success"
echo " OK"
-
exit 0
diff --git a/src/cli/test_anastasis_reducer_free_1.conf b/src/cli/test_anastasis_reducer_free_1.conf
new file mode 100644
index 0000000..0e7ad9a
--- /dev/null
+++ b/src/cli/test_anastasis_reducer_free_1.conf
@@ -0,0 +1,10 @@
+# This file is in the public domain.
+@INLINE@ test_reducer_free.conf
+
+[anastasis]
+PORT = 8086
+PROVIDER_SALT = AUfO1KGOKYIFlFQg
+BUSINESS_NAME = "Data loss #1 Inc."
+
+[stasis-postgres]
+CONFIG = postgres:///anastasischeck1
diff --git a/src/cli/test_anastasis_reducer_free_2.conf b/src/cli/test_anastasis_reducer_free_2.conf
new file mode 100644
index 0000000..a628ff4
--- /dev/null
+++ b/src/cli/test_anastasis_reducer_free_2.conf
@@ -0,0 +1,10 @@
+# This file is in the public domain.
+@INLINE@ test_reducer_free.conf
+
+[anastasis]
+PORT = 8087
+PROVIDER_SALT = BUfO1KGOKYIFlFQg
+BUSINESS_NAME = "Data loss #2 Inc."
+
+[stasis-postgres]
+CONFIG = postgres:///anastasischeck2
diff --git a/src/cli/test_anastasis_reducer_free_3.conf b/src/cli/test_anastasis_reducer_free_3.conf
new file mode 100644
index 0000000..adbe392
--- /dev/null
+++ b/src/cli/test_anastasis_reducer_free_3.conf
@@ -0,0 +1,10 @@
+# This file is in the public domain.
+@INLINE@ test_reducer_free.conf
+
+[anastasis]
+PORT = 8088
+PROVIDER_SALT = CUfO1KGOKYIFlFQg
+BUSINESS_NAME = "Data loss #3 Inc."
+
+[stasis-postgres]
+CONFIG = postgres:///anastasischeck3
diff --git a/src/cli/test_anastasis_reducer_free_4.conf b/src/cli/test_anastasis_reducer_free_4.conf
new file mode 100644
index 0000000..cd0c701
--- /dev/null
+++ b/src/cli/test_anastasis_reducer_free_4.conf
@@ -0,0 +1,10 @@
+# This file is in the public domain.
+@INLINE@ test_reducer_free.conf
+
+[anastasis]
+PORT = 8089
+PROVIDER_SALT = DUfO1KGOKYIFlFQg
+BUSINESS_NAME = "Data loss #4 Inc."
+
+[stasis-postgres]
+CONFIG = postgres:///anastasischeck4
diff --git a/src/cli/test_anastasis_reducer_recovery_enter_user_attributes.sh b/src/cli/test_anastasis_reducer_recovery_enter_user_attributes.sh
index d65020e..551ab36 100755
--- a/src/cli/test_anastasis_reducer_recovery_enter_user_attributes.sh
+++ b/src/cli/test_anastasis_reducer_recovery_enter_user_attributes.sh
@@ -1,52 +1,26 @@
#!/bin/bash
# This file is in the public domain.
-set -eu
-
-# Exit, with status code "skip" (no 'real' failure)
-function exit_skip() {
- echo " SKIP: $1"
- exit 77
-}
-
-# Exit, with error message (hard failure)
-function exit_fail() {
- echo " FAIL: $1"
- exit 1
-}
-
-# Cleanup to run whenever we exit
-function cleanup()
-{
- for n in `jobs -p`
- do
- kill $n 2> /dev/null || true
- done
- rm -rf $CONF $WALLET_DB $R1FILE $R2FILE $B1FILE $B2FILE $TMP_DIR
- wait
-}
-
+# shellcheck disable=SC2317
-CONF_1="test_anastasis_reducer_1.conf"
-CONF_2="test_anastasis_reducer_2.conf"
-CONF_3="test_anastasis_reducer_3.conf"
-CONF_4="test_anastasis_reducer_4.conf"
-
-
-# Configuration file will be edited, so we create one
-# from the template.
-CONF=`mktemp test_reducerXXXXXX.conf`
-cp test_reducer.conf $CONF
-
-TMP_DIR=`mktemp -d keys-tmp-XXXXXX`
-WALLET_DB=`mktemp test_reducer_walletXXXXXX.json`
-B1FILE=`mktemp test_reducer_stateB1XXXXXX`
-B2FILE=`mktemp test_reducer_stateB2XXXXXX`
-R1FILE=`mktemp test_reducer_stateR1XXXXXX`
-R2FILE=`mktemp test_reducer_stateR2XXXXXX`
+set -eu
-# Install cleanup handler (except for kill -9)
-trap cleanup EXIT
+# Replace with 0 for nexus...
+USE_FAKEBANK=1
+if [ 1 = "$USE_FAKEBANK" ]
+then
+ ACCOUNT="exchange-account-2"
+ WIRE_METHOD="x-taler-bank"
+ BANK_FLAGS="-f -d $WIRE_METHOD -u $ACCOUNT"
+ BANK_URL="http://localhost:18082/"
+ MERCHANT_PAYTO="payto://x-taler-bank/localhost/anastasis?receiver-name=anastasis"
+else
+ ACCOUNT="exchange-account-1"
+ WIRE_METHOD="iban"
+ BANK_FLAGS="-ns -d $WIRE_METHOD -u $ACCOUNT"
+ BANK_URL="http://localhost:18082/"
+ MERCHANT_PAYTO="payto://iban/SANDBOXX/DE648226?receiver-name=anastasis"
+fi
# Check we can actually run
echo -n "Testing for jq"
@@ -61,9 +35,6 @@ taler-exchange-httpd -h > /dev/null || exit_skip " taler-exchange required"
taler-merchant-httpd -h > /dev/null || exit_skip " taler-merchant required"
echo " FOUND"
-echo -n "Testing for taler-bank-manage"
-taler-bank-manage --help >/dev/null </dev/null || exit_skip " MISSING"
-echo " FOUND"
echo -n "Testing for taler-wallet-cli"
taler-wallet-cli -v >/dev/null </dev/null || exit_skip " MISSING"
echo " FOUND"
@@ -72,173 +43,117 @@ echo -n "Testing for anastasis-httpd"
anastasis-httpd -h >/dev/null </dev/null || exit_skip " MISSING"
echo " FOUND"
-echo -n "Initialize anastasis database ..."
-# Name of the Postgres database we will use for the script.
-# Will be dropped, do NOT use anything that might be used
-# elsewhere
-TARGET_DB_1=`anastasis-config -c $CONF_1 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
-TARGET_DB_2=`anastasis-config -c $CONF_2 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
-TARGET_DB_3=`anastasis-config -c $CONF_3 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
-TARGET_DB_4=`anastasis-config -c $CONF_4 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
-
-dropdb $TARGET_DB_1 >/dev/null 2>/dev/null || true
-createdb $TARGET_DB_1 || exit_skip "Could not create database $TARGET_DB_1"
-anastasis-dbinit -c $CONF_1 2> anastasis-dbinit_1.log
-dropdb $TARGET_DB_2 >/dev/null 2>/dev/null || true
-createdb $TARGET_DB_2 || exit_skip "Could not create database $TARGET_DB_2"
-anastasis-dbinit -c $CONF_2 2> anastasis-dbinit_2.log
-dropdb $TARGET_DB_3 >/dev/null 2>/dev/null || true
-createdb $TARGET_DB_3 || exit_skip "Could not create database $TARGET_DB_3"
-anastasis-dbinit -c $CONF_3 2> anastasis-dbinit_3.log
-dropdb $TARGET_DB_4 >/dev/null 2>/dev/null || true
-createdb $TARGET_DB_4 || exit_skip "Could not create database $TARGET_DB_4"
-anastasis-dbinit -c $CONF_4 2> anastasis-dbinit_4.log
+. setup.sh
+# Launch exchange, merchant and bank.
+# shellcheck disable=SC2086
+setup -c "test_reducer.conf" \
+ -aemw \
+ $BANK_FLAGS
-echo " OK"
+# Cleanup to run whenever we exit
+function cleanup()
+{
+ exit_cleanup
+ for n in $(jobs -p)
+ do
+ kill "$n" 2> /dev/null || true
+ done
+ rm -rf "$CONF" "$WALLET_DB" "$R1FILE" "$R2FILE" "$B1FILE" "$B2FILE" "$TMP_DIR"
+ wait
+}
-echo -n "Generating Taler auditor, exchange and merchant configurations ..."
-
-DATA_DIR=`taler-config -f -c $CONF -s PATHS -o TALER_HOME`
-rm -rf $DATA_DIR
-
-# obtain key configuration data
-MASTER_PRIV_FILE=`taler-config -f -c $CONF -s "EXCHANGE-OFFLINE" -o "MASTER_PRIV_FILE"`
-MASTER_PRIV_DIR=`dirname $MASTER_PRIV_FILE`
-mkdir -p $MASTER_PRIV_DIR
-gnunet-ecc -g1 $MASTER_PRIV_FILE > /dev/null 2> /dev/null
-MASTER_PUB=`gnunet-ecc -p $MASTER_PRIV_FILE`
-EXCHANGE_URL=`taler-config -c $CONF -s EXCHANGE -o BASE_URL`
-MERCHANT_PORT=`taler-config -c $CONF -s MERCHANT -o PORT`
-MERCHANT_URL=http://localhost:${MERCHANT_PORT}/
-BANK_PORT=`taler-config -c $CONF -s BANK -o HTTP_PORT`
-BANK_URL=http://localhost:${BANK_PORT}/
-AUDITOR_URL=http://localhost:8083/
-AUDITOR_PRIV_FILE=`taler-config -f -c $CONF -s AUDITOR -o AUDITOR_PRIV_FILE`
-AUDITOR_PRIV_DIR=`dirname $AUDITOR_PRIV_FILE`
-mkdir -p $AUDITOR_PRIV_DIR
-gnunet-ecc -g1 $AUDITOR_PRIV_FILE > /dev/null 2> /dev/null
-AUDITOR_PUB=`gnunet-ecc -p $AUDITOR_PRIV_FILE`
-
-# patch configuration
-TALER_DB=talercheck
-taler-config -c $CONF -s exchange -o MASTER_PUBLIC_KEY -V $MASTER_PUB
-taler-config -c $CONF -s merchant-exchange-default -o MASTER_KEY -V $MASTER_PUB
-taler-config -c $CONF -s exchangedb-postgres -o CONFIG -V postgres:///$TALER_DB
-taler-config -c $CONF -s auditordb-postgres -o CONFIG -V postgres:///$TALER_DB
-taler-config -c $CONF -s merchantdb-postgres -o CONFIG -V postgres:///$TALER_DB
-taler-config -c $CONF -s bank -o database -V postgres:///$TALER_DB
-taler-config -c $CONF -s exchange -o KEYDIR -V "${TMP_DIR}/keydir/"
-taler-config -c $CONF -s exchange -o REVOCATION_DIR -V "${TMP_DIR}/revdir/"
+function sync_providers() {
+ infile=$1
+ outfile=$2
+ echo "Synchronizing providers"
+ # Sync with providers (up to 3 providers aren't synced here)
+ for x in 1 2 3; do
+ echo "Synchronizing providers (round $x)"
+ anastasis-reducer sync_providers < "$infile" > "$outfile" 2> /dev/null || true
+ CODE=$(jq -r -e ".code // 0" < "$outfile")
+ # ANASTASIS_REDUCER_PROVIDERS_ALREADY_SYNCED
+ # FIXME: Temporary workaround for C reducer. See #7227.
+ if [ "$CODE" = "8420" ]
+ then
+ # restore previous non-error state
+ cat "$infile" > "$outfile"
+ break
+ fi
+ # ANASTASIS_REDUCER_ACTION_INVALID
+ if [ "$CODE" = "8400" ]
+ then
+ # restore previous non-error state
+ cat "$infile" > "$outfile"
+ break
+ fi
+ if [ "$CODE" != "0" ]
+ then
+ exit_fail "Expected no error or 8420/8400, got $CODE"
+ fi
+ cat "$outfile" > "$infile"
+ done
+ echo "Providers synced."
+}
-echo " OK"
-echo -n "Setting up exchange ..."
+CONF_1="test_anastasis_reducer_1.conf"
+CONF_2="test_anastasis_reducer_2.conf"
+CONF_3="test_anastasis_reducer_3.conf"
+CONF_4="test_anastasis_reducer_4.conf"
-# reset database
-dropdb $TALER_DB >/dev/null 2>/dev/null || true
-createdb $TALER_DB || exit_skip "Could not create database $TALER_DB"
-taler-exchange-dbinit -c $CONF
-taler-merchant-dbinit -c $CONF
-taler-auditor-dbinit -c $CONF
-taler-auditor-exchange -c $CONF -m $MASTER_PUB -u $EXCHANGE_URL
-echo " OK"
+# Configuration file will be edited, so we create one
+# from the template.
+CONF="$(mktemp -p "${TMPDIR:-/tmp}" test_reducerXXXXXX.conf)"
+cp test_reducer.conf "$CONF"
-# Launch services
-echo -n "Launching taler services ..."
-taler-bank-manage-testing $CONF postgres:///$TALER_DB serve > taler-bank.log 2> taler-bank.err &
-taler-exchange-secmod-eddsa -c $CONF 2> taler-exchange-secmod-eddsa.log &
-taler-exchange-secmod-rsa -c $CONF 2> taler-exchange-secmod-rsa.log &
-taler-exchange-httpd -c $CONF 2> taler-exchange-httpd.log &
-taler-merchant-httpd -c $CONF -L INFO 2> taler-merchant-httpd.log &
-taler-exchange-wirewatch -c $CONF 2> taler-exchange-wirewatch.log &
-taler-auditor-httpd -L INFO -c $CONF 2> taler-auditor-httpd.log &
+TMP_DIR=$(mktemp -p "${TMPDIR:-/tmp}" -d keys-tmp-XXXXXX)
+WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_walletXXXXXX.json)
+B1FILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_stateB1XXXXXX)
+B2FILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_stateB2XXXXXX)
+R1FILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_stateR1XXXXXX)
+R2FILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_stateR2XXXXXX)
+
+# Install cleanup handler (except for kill -9)
+trap cleanup EXIT
+
+echo -n "Initialize anastasis database ..."
+# Name of the Postgres database we will use for the script.
+# Will be dropped, do NOT use anything that might be used
+# elsewhere
+TARGET_DB_1=$(anastasis-config -c $CONF_1 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///")
+TARGET_DB_2=$(anastasis-config -c $CONF_2 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///")
+TARGET_DB_3=$(anastasis-config -c $CONF_3 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///")
+TARGET_DB_4=$(anastasis-config -c $CONF_4 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///")
+
+dropdb "$TARGET_DB_1" >/dev/null 2>/dev/null || true
+createdb "$TARGET_DB_1" || exit_skip "Could not create database $TARGET_DB_1"
+anastasis-dbinit -c "$CONF_1" 2> anastasis-dbinit_1.log
+dropdb "$TARGET_DB_2" >/dev/null 2>/dev/null || true
+createdb "$TARGET_DB_2" || exit_skip "Could not create database $TARGET_DB_2"
+anastasis-dbinit -c "$CONF_2" 2> anastasis-dbinit_2.log
+dropdb "$TARGET_DB_3" >/dev/null 2>/dev/null || true
+createdb "$TARGET_DB_3" || exit_skip "Could not create database $TARGET_DB_3"
+anastasis-dbinit -c "$CONF_3" 2> anastasis-dbinit_3.log
+dropdb "$TARGET_DB_4" >/dev/null 2>/dev/null || true
+createdb "$TARGET_DB_4" || exit_skip "Could not create database $TARGET_DB_4"
+anastasis-dbinit -c "$CONF_4" 2> anastasis-dbinit_4.log
echo " OK"
echo -n "Launching anastasis services ..."
PREFIX="" #valgrind
-$PREFIX anastasis-httpd -c $CONF_1 2> anastasis-httpd_1.log &
-$PREFIX anastasis-httpd -c $CONF_2 2> anastasis-httpd_2.log &
-$PREFIX anastasis-httpd -c $CONF_3 2> anastasis-httpd_3.log &
-$PREFIX anastasis-httpd -c $CONF_4 2> anastasis-httpd_4.log &
-
-# Wait for bank to be available (usually the slowest)
-for n in `seq 1 50`
-do
- echo -n "."
- sleep 0.2
- OK=0
- # bank
- wget --tries=1 --timeout=1 http://localhost:8082/ -o /dev/null -O /dev/null >/dev/null || continue
- OK=1
- break
-done
-
-if [ 1 != $OK ]
-then
- exit_skip "Failed to launch services (bank)"
-fi
-
-# Wait for all other taler services to be available
-for n in `seq 1 50`
-do
- echo -n "."
- sleep 0.1
- OK=0
- # exchange
- wget --tries=1 --timeout=1 http://localhost:8081/seed -o /dev/null -O /dev/null >/dev/null || continue
- # merchant
- wget --tries=1 --timeout=1 http://localhost:9966/ -o /dev/null -O /dev/null >/dev/null || continue
- # auditor
- wget --tries=1 --timeout=1 http://localhost:8083/ -o /dev/null -O /dev/null >/dev/null || continue
- OK=1
- break
-done
-
-if [ 1 != $OK ]
-then
- exit_skip "Failed to launch taler services"
-fi
+$PREFIX anastasis-httpd -c "$CONF_1" 2> anastasis-httpd_1.log &
+$PREFIX anastasis-httpd -c "$CONF_2" 2> anastasis-httpd_2.log &
+$PREFIX anastasis-httpd -c "$CONF_3" 2> anastasis-httpd_3.log &
+$PREFIX anastasis-httpd -c "$CONF_4" 2> anastasis-httpd_4.log &
echo "OK"
-echo -n "Setting up keys ..."
-taler-exchange-offline -c $CONF \
- download \
- sign \
- enable-account payto://x-taler-bank/localhost/Exchange \
- enable-auditor $AUDITOR_PUB $AUDITOR_URL "TESTKUDOS Auditor" \
- wire-fee now x-taler-bank TESTKUDOS:0.01 TESTKUDOS:0.01 \
- upload &> taler-exchange-offline.log
-
-echo -n "."
-
-for n in `seq 1 3`
-do
- echo -n "."
- OK=0
- wget --tries=1 --timeout=1 http://localhost:8081/keys -o /dev/null -O /dev/null >/dev/null || continue
- OK=1
- break
-done
-
-if [ 1 != $OK ]
-then
- exit_skip "Failed to setup keys"
-fi
-
-echo " OK"
-
-echo -n "Setting up auditor signatures ..."
-taler-auditor-offline -c $CONF \
- download sign upload &> taler-auditor-offline.log
-echo " OK"
-
echo -n "Waiting for anastasis services ..."
# Wait for anastasis services to be available
-for n in `seq 1 50`
+for n in $(seq 1 50)
do
echo -n "."
sleep 0.1
@@ -255,7 +170,7 @@ do
break
done
-if [ 1 != $OK ]
+if [ 1 != "$OK" ]
then
exit_skip "Failed to launch anastasis services"
fi
@@ -264,29 +179,32 @@ echo "OK"
echo -n "Configuring merchant instance ..."
# Setup merchant
-curl -H "Content-Type: application/json" -X POST -d '{"auth":{"method":"external"},"payto_uris":["payto://x-taler-bank/localhost/43"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_ms" : 3600000},"default_pay_delay":{"d_ms": 3600000}}' http://localhost:9966/management/instances
+curl -H "Content-Type: application/json" -X POST -d '{"auth":{"method":"external"},"id":"default","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' http://localhost:9966/management/instances
+curl -H "Content-Type: application/json" -X POST -d '{"payto_uri":"'"$MERCHANT_PAYTO"'"}' http://localhost:9966/private/accounts
echo " DONE"
echo -n "Running backup logic ...,"
-anastasis-reducer -b > $B1FILE
+anastasis-reducer -b > "$B1FILE"
echo -n "."
anastasis-reducer -a \
- '{"continent": "Testcontinent"}' \
- select_continent < $B1FILE > $B2FILE
+ '{"continent": "Demoworld"}' \
+ select_continent < "$B1FILE" > "$B2FILE"
echo -n "."
anastasis-reducer -a \
- '{"country_code": "xx",
- "currencies":["TESTKUDOS"]}' \
- select_country < $B2FILE > $B1FILE
+ '{"country_code": "xx"}' \
+ select_country < "$B2FILE" > "$B1FILE"
echo -n "."
anastasis-reducer -a \
'{"identity_attributes": {
"full_name": "Max Musterman",
"sq_number": "4",
"birthdate": "2000-01-01"}}' \
- enter_user_attributes < $B1FILE > $B2FILE
+ enter_user_attributes < "$B1FILE" > "$B2FILE"
+cat "$B2FILE" > "$B1FILE"
+echo -n ","
+sync_providers "$B1FILE" "$B2FILE"
echo -n ","
# "91GPWWR" encodes "Hans"
anastasis-reducer -a \
@@ -295,7 +213,7 @@ anastasis-reducer -a \
"instructions": "What is your name?",
"challenge": "91GPWWR"
} }' \
- add_authentication < $B2FILE > $B1FILE
+ add_authentication < "$B2FILE" > "$B1FILE"
echo -n "."
# "64S36" encodes "123"
anastasis-reducer -a \
@@ -304,7 +222,7 @@ anastasis-reducer -a \
"instructions": "How old are you?",
"challenge": "64S36"
} }' \
- add_authentication < $B1FILE > $B2FILE
+ add_authentication < "$B1FILE" > "$B2FILE"
echo -n "."
# "9NGQ4WR" encodes "Mars"
anastasis-reducer -a \
@@ -313,149 +231,177 @@ anastasis-reducer -a \
"instructions": "Where do you live?",
"challenge": "9NGQ4WR"
} }' \
- add_authentication < $B2FILE > $B1FILE
+ add_authentication < "$B2FILE" > "$B1FILE"
echo -n "."
# Finished adding authentication methods
anastasis-reducer \
- next < $B1FILE > $B2FILE
+ next < "$B1FILE" > "$B2FILE"
echo -n ","
# Finished policy review
anastasis-reducer \
- next < $B2FILE > $B1FILE
+ next < "$B2FILE" > "$B1FILE"
echo -n "."
# Note: 'secret' must here be a Crockford base32-encoded value
anastasis-reducer -a \
'{"secret": { "value" : "VERYHARDT0GVESSSECRET", "mime" : "text/plain" }}' \
- enter_secret < $B1FILE > $B2FILE
-mv $B2FILE $B1FILE
-anastasis-reducer next $B1FILE $B2FILE
+ enter_secret < "$B1FILE" > "$B2FILE"
+mv "$B2FILE" "$B1FILE"
+anastasis-reducer next "$B1FILE" "$B2FILE"
echo " OK"
echo -n "Preparing wallet"
-rm $WALLET_DB
-taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api 'withdrawTestBalance' \
+
+EXCHANGE_URL="$(taler-config -c "$CONF" -s exchange -o BASE_URL)"
+
+rm -f "$WALLET_DB"
+taler-wallet-cli --no-throttle --wallet-db="$WALLET_DB" api --expect-success 'withdrawTestBalance' \
"$(jq -n '
{
amount: "TESTKUDOS:100",
- bankBaseUrl: $BANK_URL,
+ corebankApiBaseUrl: $BANK_URL,
exchangeBaseUrl: $EXCHANGE_URL
}' \
- --arg BANK_URL "$BANK_URL" \
+ --arg BANK_URL "${BANK_URL}" \
--arg EXCHANGE_URL "$EXCHANGE_URL"
- )" 2> /dev/null >/dev/null
-taler-wallet-cli --wallet-db=$WALLET_DB run-until-done 2>/dev/null >/dev/null
+ )" 2> wallet-withdraw.err > wallet-withdraw.out
+taler-wallet-cli \
+ --wallet-db="$WALLET_DB" \
+ run-until-done \
+ 2>wallet-withdraw-finish.err \
+ >wallet-withdraw-finish.out
echo " OK"
echo -en "Making payments for truth uploads ... "
-OBJECT_SIZE=`jq -r -e '.payments | length' < $B2FILE`
-for ((INDEX=0; INDEX < $OBJECT_SIZE; INDEX++))
+OBJECT_SIZE=$(jq -r -e '.payments | length' < "$B2FILE")
+for ((INDEX=0; INDEX < "$OBJECT_SIZE"; INDEX++))
do
- PAY_URI=`jq --argjson INDEX $INDEX -r -e '.payments[$INDEX]' < $B2FILE`
+ PAY_URI=$(jq --argjson INDEX $INDEX -r -e '.payments[$INDEX]' < "$B2FILE")
# run wallet CLI
echo -n "$INDEX"
- taler-wallet-cli --wallet-db=$WALLET_DB handle-uri $PAY_URI -y 2>/dev/null >/dev/null
+ taler-wallet-cli \
+ --wallet-db="$WALLET_DB" \
+ handle-uri "$PAY_URI" \
+ -y \
+ 2>"wallet-pay-truth-$INDEX.err" \
+ >"wallet-pay-truth-$INDEX.out"
echo -n ", "
done
echo "OK"
-echo -e "Running wallet run-pending..."
-taler-wallet-cli --wallet-db=$WALLET_DB run-pending 2>/dev/null >/dev/null
+echo -e "Running wallet run-until-done..."
+taler-wallet-cli \
+ --wallet-db="$WALLET_DB" \
+ run-until-done \
+ 2>"wallet-pay-truth-finish-$INDEX.err" \
+ >"wallet-pay-truth-finish-$INDEX.out"
echo -e "Payments done"
-export B2FILE
-export B1FILE
-
echo -en "Try to upload again ..."
-$PREFIX anastasis-reducer pay $B2FILE $B1FILE
-mv $B1FILE $B2FILE
+$PREFIX anastasis-reducer pay "$B2FILE" "$B1FILE"
+mv "$B1FILE" "$B2FILE"
echo " OK"
echo -en "Making payments for policy uploads ... "
-OBJECT_SIZE=`jq -r -e '.policy_payment_requests | length' < $B2FILE`
-for ((INDEX=0; INDEX < $OBJECT_SIZE; INDEX++))
+OBJECT_SIZE=$(jq -r -e '.policy_payment_requests | length' < "$B2FILE")
+for ((INDEX=0; INDEX < "$OBJECT_SIZE"; INDEX++))
do
- PAY_URI=`jq --argjson INDEX $INDEX -r -e '.policy_payment_requests[$INDEX].payto' < $B2FILE`
+ PAY_URI=$(jq --argjson INDEX $INDEX -r -e '.policy_payment_requests[$INDEX].payto' < "$B2FILE")
# run wallet CLI
echo -n "$INDEX"
- taler-wallet-cli --wallet-db=$WALLET_DB handle-uri $PAY_URI -y 2>/dev/null >/dev/null
+ taler-wallet-cli \
+ --wallet-db="$WALLET_DB" \
+ handle-uri "$PAY_URI" \
+ -y \
+ 2>"wallet-pay-policy-$INDEX.err" \
+ >"wallet-pay-policy-$INDEX.out"
echo -n ", "
done
echo " OK"
-echo -en "Running wallet run-pending..."
-taler-wallet-cli --wallet-db=$WALLET_DB run-pending 2>/dev/null >/dev/null
+echo -en "Running wallet run-until-done..."
+taler-wallet-cli \
+ --wallet-db="$WALLET_DB" \
+ run-until-done \
+ 2>wallet-pay-policy-finish.err \
+ >wallet-pay-policy-finish.out
echo -e " payments DONE"
echo -en "Try to upload again ..."
anastasis-reducer \
- pay < $B2FILE > $B1FILE
+ pay < "$B2FILE" > "$B1FILE"
echo " OK: Backup finished"
echo -n "Final backup checks ..."
-STATE=`jq -r -e .backup_state < $B1FILE`
-if test "$STATE" != "BACKUP_FINISHED"
+STATE=$(jq -r -e .backup_state < "$B1FILE")
+if [ "$STATE" != "BACKUP_FINISHED" ]
then
exit_fail "Expected new state to be 'BACKUP_FINISHED', got '$STATE'"
fi
-jq -r -e .core_secret < $B1FILE > /dev/null && exit_fail "'core_secret' was not cleared upon success"
+jq -r -e .core_secret < "$B1FILE" > /dev/null && exit_fail "'core_secret' was not cleared upon success"
echo " OK"
echo -n "Running recovery basic logic ..."
-anastasis-reducer -r > $R1FILE
+anastasis-reducer -r > "$R1FILE"
anastasis-reducer -a \
- '{"continent": "Testcontinent"}' \
- select_continent < $R1FILE > $R2FILE
+ '{"continent": "Demoworld"}' \
+ select_continent < "$R1FILE" > "$R2FILE"
anastasis-reducer -a \
- '{"country_code": "xx",
- "currencies":["TESTKUDOS"]}' \
- select_country < $R2FILE > $R1FILE
-anastasis-reducer -a '{"identity_attributes": { "full_name": "Max Musterman", "sq_number": "4", "birthdate": "2000-01-01" }}' enter_user_attributes < $R1FILE > $R2FILE
+ '{"country_code": "xx"}' \
+ select_country < "$R2FILE" > "$R1FILE"
+anastasis-reducer -a '{"identity_attributes": { "full_name": "Max Musterman", "sq_number": "4", "birthdate": "2000-01-01" }}' enter_user_attributes < "$R1FILE" > "$R2FILE"
-STATE=`jq -r -e .recovery_state < $R2FILE`
-if test "$STATE" != "SECRET_SELECTING"
+STATE=$(jq -r -e .recovery_state < "$R2FILE")
+if [ "$STATE" != "SECRET_SELECTING" ]
then
exit_fail "Expected new state to be 'SECRET_SELECTING', got '$STATE'"
fi
echo " OK"
-echo -n "Selecting default secret"
-mv $R2FILE $R1FILE
-anastasis-reducer next < $R1FILE > $R2FILE
+echo -n "Adding provider (to ensure it is loaded)"
+anastasis-reducer -a '{"provider_url" : "http://localhost:8086/" }' add_provider < "$R2FILE" > "$R1FILE"
+echo " OK"
+
+echo -n "Selecting secret to recover"
+anastasis-reducer -a '{"attribute_mask": 0, "providers" : [ { "version": 1, "url" : "http://localhost:8086/" } ] }' select_version < "$R1FILE" > "$R2FILE"
-STATE=`jq -r -e .recovery_state < $R2FILE`
-if test "$STATE" != "CHALLENGE_SELECTING"
+STATE=$(jq -r -e .recovery_state < "$R2FILE")
+if [ "$STATE" != "CHALLENGE_SELECTING" ]
then
exit_fail "Expected new state to be 'CHALLENGE_SELECTING', got '$STATE'"
fi
echo " OK"
+cat "$R2FILE" > "$R1FILE"
+
+sync_providers "$R1FILE" "$R2FILE"
+
echo -n "Running challenge logic ..."
-UUID0=`jq -r -e .recovery_information.challenges[0].uuid < $R2FILE`
-UUID1=`jq -r -e .recovery_information.challenges[1].uuid < $R2FILE`
-UUID2=`jq -r -e .recovery_information.challenges[2].uuid < $R2FILE`
-UUID0Q=`jq -r -e .recovery_information.challenges[0].instructions < $R2FILE`
-UUID1Q=`jq -r -e .recovery_information.challenges[1].instructions < $R2FILE`
-UUID2Q=`jq -r -e .recovery_information.challenges[2].instructions < $R2FILE`
+UUID0=$(jq -r -e .recovery_information.challenges[0].uuid < "$R2FILE")
+UUID1=$(jq -r -e .recovery_information.challenges[1].uuid < "$R2FILE")
+UUID2=$(jq -r -e .recovery_information.challenges[2].uuid < "$R2FILE")
+#UUID0Q=$(jq -r -e .recovery_information.challenges[0].instructions < "$R2FILE")
+UUID1Q=$(jq -r -e .recovery_information.challenges[1].instructions < "$R2FILE")
+UUID2Q=$(jq -r -e .recovery_information.challenges[2].instructions < "$R2FILE")
-if test "$UUID2Q" = 'How old are you?'
+if [ "$UUID2Q" = 'How old are you?' ]
then
AGE_UUID=$UUID2
-elif test "$UUID1Q" = 'How old are you?'
+elif [ "$UUID1Q" = 'How old are you?' ]
then
AGE_UUID=$UUID1
else
AGE_UUID=$UUID0
fi
-if test "$UUID2Q" = 'What is your name?'
+if [ "$UUID2Q" = 'What is your name?' ]
then
NAME_UUID=$UUID2
-elif test "$UUID1Q" = 'What is your name?'
+elif [ "$UUID1Q" = 'What is your name?' ]
then
NAME_UUID=$UUID1
else
@@ -469,10 +415,10 @@ anastasis-reducer -a \
}' \
--arg UUID "$NAME_UUID"
)" \
- select_challenge < $R2FILE > $R1FILE
+ select_challenge < "$R2FILE" > "$R1FILE"
anastasis-reducer -a '{"answer": "Hans"}' \
- solve_challenge < $R1FILE > $R2FILE
+ solve_challenge < "$R1FILE" > "$R2FILE"
anastasis-reducer -a \
"$(jq -n '
@@ -481,34 +427,34 @@ anastasis-reducer -a \
}' \
--arg UUID "$AGE_UUID"
)" \
- select_challenge < $R2FILE > $R1FILE
+ select_challenge < "$R2FILE" > "$R1FILE"
anastasis-reducer -a '{"answer": "123"}' \
- solve_challenge < $R1FILE > $R2FILE
+ solve_challenge < "$R1FILE" > "$R2FILE"
echo " OK"
echo -n "Checking recovered secret ..."
# finally: check here that we recovered the secret...
-STATE=`jq -r -e .recovery_state < $R2FILE`
-if test "$STATE" != "RECOVERY_FINISHED"
+STATE=$(jq -r -e .recovery_state < "$R2FILE")
+if [ "$STATE" != "RECOVERY_FINISHED" ]
then
- jq -e . $R2FILE
+ jq -e . "$R2FILE"
exit_fail "Expected new state to be 'RECOVERY_FINISHED', got '$STATE'"
fi
-SECRET=`jq -r -e .core_secret.value < $R2FILE`
-if test "$SECRET" != "VERYHARDT0GVESSSECRET"
+SECRET=$(jq -r -e .core_secret.value < "$R2FILE")
+if [ "$SECRET" != "VERYHARDT0GVESSSECRET" ]
then
- jq -e . $R2FILE
+ jq -e . "$R2FILE"
exit_fail "Expected recovered secret to be 'VERYHARDT0GVESSSECRET', got '$SECRET'"
fi
-MIME=`jq -r -e .core_secret.mime < $R2FILE`
-if test "$MIME" != "text/plain"
+MIME=$(jq -r -e .core_secret.mime < "$R2FILE")
+if [ "$MIME" != "text/plain" ]
then
- jq -e . $R2FILE
+ jq -e . "$R2FILE"
exit_fail "Expected recovered mime to be 'text/plain', got '$MIME'"
fi
diff --git a/src/cli/test_anastasis_reducer_recovery_hanging.sh b/src/cli/test_anastasis_reducer_recovery_hanging.sh
new file mode 100755
index 0000000..f67b850
--- /dev/null
+++ b/src/cli/test_anastasis_reducer_recovery_hanging.sh
@@ -0,0 +1,376 @@
+#!/bin/bash
+# This file is in the public domain.
+# Runs tests with a 'hanging' Anastasis provider.
+
+set -eu
+#set -x
+
+# Exit, with status code "skip" (no 'real' failure)
+function exit_skip() {
+ echo " SKIP: $1"
+ exit 77
+}
+
+# Exit, with error message (hard failure)
+function exit_fail() {
+ echo " FAIL: $1"
+ exit 1
+}
+
+# Cleanup to run whenever we exit
+function cleanup()
+{
+ for n in `jobs -p`
+ do
+ kill -SIGCONT $n # in case suspended...
+ kill $n 2> /dev/null || true
+ done
+ rm -rf $CONF $R1FILE $R2FILE $B1FILE $B2FILE $TMP_DIR
+ wait
+}
+
+function sync_providers() {
+ infile=$1
+ outfile=$2
+ echo "Synchronizing providers"
+ # Sync with providers (up to 3 providers aren't synced here)
+ for x in 1 2 3; do
+ echo "Synchronizing providers (round $x)"
+ #anastasis-reducer sync_providers < $infile > $outfile 2> /dev/null || true
+ anastasis-reducer sync_providers < $infile > $outfile || true
+ CODE=$(jq -r -e ".code // 0" < $outfile)
+ # ANASTASIS_REDUCER_PROVIDERS_ALREADY_SYNCED
+ # FIXME: Temporary workaround for C reducer. See #7227.
+ if test "$CODE" = "8420"; then
+ # restore previous non-error state
+ cat $infile > $outfile
+ break
+ fi
+ # ANASTASIS_REDUCER_ACTION_INVALID
+ if test "$CODE" = "8400"; then
+ # restore previous non-error state
+ cat $infile > $outfile
+ break
+ fi
+ if test "$CODE" != "0"; then
+ exit_fail "Expected no error or 8420/8400, got $CODE"
+ fi
+ cat $outfile > $infile
+ done
+ echo "Providers synced."
+}
+
+
+CONF_1="test_anastasis_reducer_free_1.conf"
+CONF_2="test_anastasis_reducer_free_2.conf"
+CONF_3="test_anastasis_reducer_free_3.conf"
+CONF_4="test_anastasis_reducer_free_4.conf"
+
+
+# Configuration file will be edited, so we create one
+# from the template.
+CONF=`mktemp test_reducerXXXXXX.conf`
+cp test_reducer.conf $CONF
+
+TMP_DIR=`mktemp -d keys-tmp-XXXXXX`
+B1FILE=`mktemp test_reducer_stateB1XXXXXX`
+B2FILE=`mktemp test_reducer_stateB2XXXXXX`
+R1FILE=`mktemp test_reducer_stateR1XXXXXX`
+R2FILE=`mktemp test_reducer_stateR2XXXXXX`
+export B1FILE
+export B2FILE
+export R1FILE
+export R2FILE
+
+# Install cleanup handler (except for kill -9)
+trap cleanup EXIT
+
+# Check we can actually run
+echo -n "Testing for jq"
+jq -h > /dev/null || exit_skip "jq required"
+echo " FOUND"
+echo -n "Testing for timeout"
+timeout --help > /dev/null || exit_skip "timeout required"
+echo " FOUND"
+echo -n "Testing for anastasis-reducer ..."
+anastasis-reducer -h > /dev/null || exit_skip "anastasis-reducer required"
+echo " FOUND"
+
+echo -n "Testing for anastasis-httpd"
+anastasis-httpd -h >/dev/null </dev/null || exit_skip " MISSING"
+echo " FOUND"
+
+echo -n "Initialize anastasis database ..."
+# Name of the Postgres database we will use for the script.
+# Will be dropped, do NOT use anything that might be used
+# elsewhere
+TARGET_DB_1=`anastasis-config -c $CONF_1 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
+TARGET_DB_2=`anastasis-config -c $CONF_2 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
+TARGET_DB_3=`anastasis-config -c $CONF_3 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
+TARGET_DB_4=`anastasis-config -c $CONF_4 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
+
+dropdb $TARGET_DB_1 >/dev/null 2>/dev/null || true
+createdb $TARGET_DB_1 || exit_skip "Could not create database $TARGET_DB_1"
+anastasis-dbinit -c $CONF_1 2> anastasis-dbinit_1.log
+dropdb $TARGET_DB_2 >/dev/null 2>/dev/null || true
+createdb $TARGET_DB_2 || exit_skip "Could not create database $TARGET_DB_2"
+anastasis-dbinit -c $CONF_2 2> anastasis-dbinit_2.log
+dropdb $TARGET_DB_3 >/dev/null 2>/dev/null || true
+createdb $TARGET_DB_3 || exit_skip "Could not create database $TARGET_DB_3"
+anastasis-dbinit -c $CONF_3 2> anastasis-dbinit_3.log
+dropdb $TARGET_DB_4 >/dev/null 2>/dev/null || true
+createdb $TARGET_DB_4 || exit_skip "Could not create database $TARGET_DB_4"
+anastasis-dbinit -c $CONF_4 2> anastasis-dbinit_4.log
+
+echo " OK"
+
+echo -n "Launching anastasis services ..."
+PREFIX="" #valgrind
+$PREFIX anastasis-httpd -c $CONF_1 2> anastasis-httpd_1.log &
+PPID_1=$!
+$PREFIX anastasis-httpd -c $CONF_2 2> anastasis-httpd_2.log &
+PPID_2=$!
+$PREFIX anastasis-httpd -c $CONF_3 2> anastasis-httpd_3.log &
+PPID_3=$!
+$PREFIX anastasis-httpd -c $CONF_4 2> anastasis-httpd_4.log &
+PPID_4=$!
+export PPID_1
+export PPID_2
+export PPID_3
+export PPID_4
+
+echo -n "Waiting for anastasis services ..."
+
+# Wait for anastasis services to be available
+for n in `seq 1 50`
+do
+ echo -n "."
+ sleep 0.1
+ OK=0
+ # anastasis_01
+ wget --tries=1 --timeout=1 http://localhost:8086/ -o /dev/null -O /dev/null >/dev/null || continue
+ # anastasis_02
+ wget --tries=1 --timeout=1 http://localhost:8087/ -o /dev/null -O /dev/null >/dev/null || continue
+ # anastasis_03
+ wget --tries=1 --timeout=1 http://localhost:8088/ -o /dev/null -O /dev/null >/dev/null || continue
+ # anastasis_04
+ wget --tries=1 --timeout=1 http://localhost:8089/ -o /dev/null -O /dev/null >/dev/null || continue
+ OK=1
+ break
+done
+
+if [ 1 != $OK ]
+then
+ exit_skip "Failed to launch anastasis services"
+fi
+echo "OK"
+
+echo -n "Running backup logic ...,"
+anastasis-reducer -b > $B1FILE
+echo -n "."
+anastasis-reducer -a \
+ '{"continent": "Demoworld"}' \
+ select_continent < $B1FILE > $B2FILE
+echo -n "."
+anastasis-reducer -a \
+ '{"country_code": "xx"}' \
+ select_country < $B2FILE > $B1FILE
+echo -n "."
+
+kill -SIGSTOP $PPID_4
+START=`date '+%s'`
+timeout 10 anastasis-reducer -L DEBUG -a \
+ '{"identity_attributes": {
+ "full_name": "Max Musterman",
+ "sq_number": "4",
+ "birthdate": "2000-01-01"}}' \
+ enter_user_attributes < $B1FILE > $B2FILE || true
+END=`date '+%s'`
+DELTA=`expr $END - $START`
+kill -SIGCONT $PPID_4
+
+if test $DELTA -ge 5
+then
+ exit_fail "Reducer hangs on suspended provider in 'enter_user_attributes'"
+fi
+
+cat $B2FILE > $B1FILE
+echo -n ","
+sync_providers $B1FILE $B2FILE
+echo -n ","
+# "91GPWWR" encodes "Hans"
+anastasis-reducer -a \
+ '{"authentication_method": {
+ "type": "question",
+ "instructions": "What is your name?",
+ "challenge": "91GPWWR"
+ } }' \
+ add_authentication < $B2FILE > $B1FILE
+echo -n "."
+# "64S36" encodes "123"
+anastasis-reducer -a \
+ '{"authentication_method": {
+ "type": "question",
+ "instructions": "How old are you?",
+ "challenge": "64S36"
+ } }' \
+ add_authentication < $B1FILE > $B2FILE
+echo -n "."
+# "9NGQ4WR" encodes "Mars"
+anastasis-reducer -a \
+ '{"authentication_method": {
+ "type": "question",
+ "instructions": "Where do you live?",
+ "challenge": "9NGQ4WR"
+ } }' \
+ add_authentication < $B2FILE > $B1FILE
+echo -n "."
+# Finished adding authentication methods
+anastasis-reducer \
+ next < $B1FILE > $B2FILE
+
+
+echo -n ","
+# Finished policy review
+anastasis-reducer \
+ next < $B2FILE > $B1FILE
+echo -n "."
+
+# Note: 'secret' must here be a Crockford base32-encoded value
+anastasis-reducer -a \
+ '{"secret": { "value" : "VERYHARDT0GVESSSECRET", "mime" : "text/plain" }}' \
+ enter_secret < $B1FILE > $B2FILE
+anastasis-reducer next $B2FILE $B1FILE
+echo " OK"
+
+echo -n "Final backup checks ..."
+STATE=`jq -r -e .backup_state < $B1FILE`
+if test "$STATE" != "BACKUP_FINISHED"
+then
+ exit_fail "Expected new state to be 'BACKUP_FINISHED', got '$STATE'"
+fi
+
+jq -r -e .core_secret < $B1FILE > /dev/null && exit_fail "'core_secret' was not cleared upon success"
+
+echo " OK"
+
+
+echo -n "Running recovery basic logic ..."
+anastasis-reducer -r > $R1FILE
+anastasis-reducer -a \
+ '{"continent": "Demoworld"}' \
+ select_continent < $R1FILE > $R2FILE
+anastasis-reducer -a \
+ '{"country_code": "xx" }' \
+ select_country < $R2FILE > $R1FILE
+anastasis-reducer -a '{"identity_attributes": { "full_name": "Max Musterman", "sq_number": "4", "birthdate": "2000-01-01" }}' enter_user_attributes < $R1FILE > $R2FILE
+
+
+STATE=`jq -r -e .recovery_state < $R2FILE`
+if test "$STATE" != "SECRET_SELECTING"
+then
+ exit_fail "Expected new state to be 'SECRET_SELECTING', got '$STATE'"
+fi
+echo " OK"
+
+echo -n "Adding provider (to ensure it is loaded)"
+anastasis-reducer -a '{"provider_url" : "http://localhost:8086/" }' add_provider < $R2FILE > $R1FILE
+echo " OK"
+
+echo -n "Selecting secret to recover"
+anastasis-reducer -a '{"attribute_mask": 0, "providers" : [ { "version": 1, "url" : "http://localhost:8086/" } ] }' select_version < $R1FILE > $R2FILE
+
+STATE=`jq -r -e .recovery_state < $R2FILE`
+if test "$STATE" != "CHALLENGE_SELECTING"
+then
+ exit_fail "Expected new state to be 'CHALLENGE_SELECTING', got '$STATE'"
+fi
+echo " OK"
+
+cat $R2FILE > $R1FILE
+sync_providers $R1FILE $R2FILE
+
+echo -n "Running challenge logic ..."
+
+cat $R2FILE | jq .
+
+UUID0=`jq -r -e .recovery_information.challenges[0].uuid < $R2FILE`
+UUID1=`jq -r -e .recovery_information.challenges[1].uuid < $R2FILE`
+UUID2=`jq -r -e .recovery_information.challenges[2].uuid < $R2FILE`
+UUID0Q=`jq -r -e .recovery_information.challenges[0].instructions < $R2FILE`
+UUID1Q=`jq -r -e .recovery_information.challenges[1].instructions < $R2FILE`
+UUID2Q=`jq -r -e .recovery_information.challenges[2].instructions < $R2FILE`
+
+if test "$UUID2Q" = 'How old are you?'
+then
+ AGE_UUID=$UUID2
+elif test "$UUID1Q" = 'How old are you?'
+then
+ AGE_UUID=$UUID1
+else
+ AGE_UUID=$UUID0
+fi
+
+if test "$UUID2Q" = 'What is your name?'
+then
+ NAME_UUID=$UUID2
+elif test "$UUID1Q" = 'What is your name?'
+then
+ NAME_UUID=$UUID1
+else
+ NAME_UUID=$UUID0
+fi
+
+anastasis-reducer -a \
+ "$(jq -n '
+ {
+ uuid: $UUID
+ }' \
+ --arg UUID "$NAME_UUID"
+ )" \
+ select_challenge < $R2FILE > $R1FILE
+
+anastasis-reducer -a '{"answer": "Hans"}' \
+ solve_challenge < $R1FILE > $R2FILE
+
+anastasis-reducer -a \
+ "$(jq -n '
+ {
+ uuid: $UUID
+ }' \
+ --arg UUID "$AGE_UUID"
+ )" \
+ select_challenge < $R2FILE > $R1FILE
+
+anastasis-reducer -a '{"answer": "123"}' \
+ solve_challenge < $R1FILE > $R2FILE
+
+echo " OK"
+
+echo -n "Checking recovered secret ..."
+# finally: check here that we recovered the secret...
+
+STATE=`jq -r -e .recovery_state < $R2FILE`
+if test "$STATE" != "RECOVERY_FINISHED"
+then
+ jq -e . $R2FILE
+ exit_fail "Expected new state to be 'RECOVERY_FINISHED', got '$STATE'"
+fi
+
+SECRET=`jq -r -e .core_secret.value < $R2FILE`
+if test "$SECRET" != "VERYHARDT0GVESSSECRET"
+then
+ jq -e . $R2FILE
+ exit_fail "Expected recovered secret to be 'VERYHARDT0GVESSSECRET', got '$SECRET'"
+fi
+
+MIME=`jq -r -e .core_secret.mime < $R2FILE`
+if test "$MIME" != "text/plain"
+then
+ jq -e . $R2FILE
+ exit_fail "Expected recovered mime to be 'text/plain', got '$MIME'"
+fi
+
+echo " OK"
+
+exit 0
diff --git a/src/cli/test_anastasis_reducer_recovery_no_pay.sh b/src/cli/test_anastasis_reducer_recovery_no_pay.sh
new file mode 100755
index 0000000..42f5b0c
--- /dev/null
+++ b/src/cli/test_anastasis_reducer_recovery_no_pay.sh
@@ -0,0 +1,351 @@
+#!/bin/bash
+# This file is in the public domain.
+
+set -eu
+set -x
+
+# Exit, with status code "skip" (no 'real' failure)
+function exit_skip() {
+ echo " SKIP: $1"
+ exit 77
+}
+
+# Exit, with error message (hard failure)
+function exit_fail() {
+ echo " FAIL: $1"
+ exit 1
+}
+
+# Cleanup to run whenever we exit
+function cleanup()
+{
+ for n in `jobs -p`
+ do
+ kill $n 2> /dev/null || true
+ done
+ rm -rf $CONF $R1FILE $R2FILE $B1FILE $B2FILE $TMP_DIR
+ wait
+}
+
+function sync_providers() {
+ infile=$1
+ outfile=$2
+ echo "Synchronizing providers"
+ # Sync with providers (up to 3 providers aren't synced here)
+ for x in 1 2 3; do
+ echo "Synchronizing providers (round $x)"
+ #anastasis-reducer sync_providers < $infile > $outfile 2> /dev/null || true
+ anastasis-reducer sync_providers < $infile > $outfile || true
+ CODE=$(jq -r -e ".code // 0" < $outfile)
+ # ANASTASIS_REDUCER_PROVIDERS_ALREADY_SYNCED
+ # FIXME: Temporary workaround for C reducer. See #7227.
+ if test "$CODE" = "8420"; then
+ # restore previous non-error state
+ cat $infile > $outfile
+ break
+ fi
+ # ANASTASIS_REDUCER_ACTION_INVALID
+ if test "$CODE" = "8400"; then
+ # restore previous non-error state
+ cat $infile > $outfile
+ break
+ fi
+ if test "$CODE" != "0"; then
+ exit_fail "Expected no error or 8420/8400, got $CODE"
+ fi
+ cat $outfile > $infile
+ done
+ echo "Providers synced."
+}
+
+
+CONF_1="test_anastasis_reducer_free_1.conf"
+CONF_2="test_anastasis_reducer_free_2.conf"
+CONF_3="test_anastasis_reducer_free_3.conf"
+CONF_4="test_anastasis_reducer_free_4.conf"
+
+
+# Configuration file will be edited, so we create one
+# from the template.
+CONF=$(mktemp test_reducerXXXXXX.conf)
+cp test_reducer.conf "$CONF"
+
+TMP_DIR=`mktemp -d keys-tmp-XXXXXX`
+B1FILE=`mktemp test_reducer_stateB1XXXXXX`
+B2FILE=`mktemp test_reducer_stateB2XXXXXX`
+R1FILE=`mktemp test_reducer_stateR1XXXXXX`
+R2FILE=`mktemp test_reducer_stateR2XXXXXX`
+export B1FILE
+export B2FILE
+export R1FILE
+export R2FILE
+
+# Install cleanup handler (except for kill -9)
+trap cleanup EXIT
+
+# Check we can actually run
+echo -n "Testing for jq"
+jq -h > /dev/null || exit_skip "jq required"
+echo " FOUND"
+echo -n "Testing for anastasis-reducer ..."
+anastasis-reducer -h > /dev/null || exit_skip "anastasis-reducer required"
+echo " FOUND"
+
+echo -n "Testing for anastasis-httpd"
+anastasis-httpd -h >/dev/null </dev/null || exit_skip " MISSING"
+echo " FOUND"
+
+echo -n "Initialize anastasis database ..."
+# Name of the Postgres database we will use for the script.
+# Will be dropped, do NOT use anything that might be used
+# elsewhere
+TARGET_DB_1=`anastasis-config -c $CONF_1 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
+TARGET_DB_2=`anastasis-config -c $CONF_2 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
+TARGET_DB_3=`anastasis-config -c $CONF_3 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
+TARGET_DB_4=`anastasis-config -c $CONF_4 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
+
+dropdb $TARGET_DB_1 >/dev/null 2>/dev/null || true
+createdb $TARGET_DB_1 || exit_skip "Could not create database $TARGET_DB_1"
+anastasis-dbinit -c $CONF_1 2> anastasis-dbinit_1.log
+dropdb $TARGET_DB_2 >/dev/null 2>/dev/null || true
+createdb $TARGET_DB_2 || exit_skip "Could not create database $TARGET_DB_2"
+anastasis-dbinit -c $CONF_2 2> anastasis-dbinit_2.log
+dropdb $TARGET_DB_3 >/dev/null 2>/dev/null || true
+createdb $TARGET_DB_3 || exit_skip "Could not create database $TARGET_DB_3"
+anastasis-dbinit -c $CONF_3 2> anastasis-dbinit_3.log
+dropdb $TARGET_DB_4 >/dev/null 2>/dev/null || true
+createdb $TARGET_DB_4 || exit_skip "Could not create database $TARGET_DB_4"
+anastasis-dbinit -c $CONF_4 2> anastasis-dbinit_4.log
+
+echo " OK"
+
+echo -n "Launching anastasis services ..."
+PREFIX="" #valgrind
+$PREFIX anastasis-httpd -L DEBUG -c $CONF_1 2> anastasis-httpd_1.log &
+$PREFIX anastasis-httpd -L DEBUG -c $CONF_2 2> anastasis-httpd_2.log &
+$PREFIX anastasis-httpd -L DEBUG -c $CONF_3 2> anastasis-httpd_3.log &
+$PREFIX anastasis-httpd -L DEBUG -c $CONF_4 2> anastasis-httpd_4.log &
+
+echo -n "Waiting for anastasis services ..."
+
+# Wait for anastasis services to be available
+for n in `seq 1 50`
+do
+ echo -n "."
+ sleep 0.1
+ OK=0
+ # anastasis_01
+ wget --tries=1 --timeout=1 http://localhost:8086/ -o /dev/null -O /dev/null >/dev/null || continue
+ # anastasis_02
+ wget --tries=1 --timeout=1 http://localhost:8087/ -o /dev/null -O /dev/null >/dev/null || continue
+ # anastasis_03
+ wget --tries=1 --timeout=1 http://localhost:8088/ -o /dev/null -O /dev/null >/dev/null || continue
+ # anastasis_04
+ wget --tries=1 --timeout=1 http://localhost:8089/ -o /dev/null -O /dev/null >/dev/null || continue
+ OK=1
+ break
+done
+
+if [ 1 != $OK ]
+then
+ exit_skip "Failed to launch anastasis services"
+fi
+echo "OK"
+
+echo -n "Running backup logic ...,"
+anastasis-reducer -b > $B1FILE
+echo -n "."
+anastasis-reducer -a \
+ '{"continent": "Demoworld"}' \
+ select_continent < $B1FILE > $B2FILE
+echo -n "."
+anastasis-reducer -a \
+ '{"country_code": "xx"}' \
+ select_country < $B2FILE > $B1FILE
+echo -n "."
+anastasis-reducer -a \
+ '{"identity_attributes": {
+ "full_name": "Max Musterman",
+ "sq_number": "4",
+ "birthdate": "2000-01-01"}}' \
+ enter_user_attributes < $B1FILE > $B2FILE
+cat $B2FILE > $B1FILE
+echo -n ","
+sync_providers $B1FILE $B2FILE
+echo -n ","
+# "91GPWWR" encodes "Hans"
+anastasis-reducer -a \
+ '{"authentication_method": {
+ "type": "question",
+ "instructions": "What is your name?",
+ "challenge": "91GPWWR"
+ } }' \
+ add_authentication < $B2FILE > $B1FILE
+echo -n "."
+# "64S36" encodes "123"
+anastasis-reducer -a \
+ '{"authentication_method": {
+ "type": "question",
+ "instructions": "How old are you?",
+ "challenge": "64S36"
+ } }' \
+ add_authentication < $B1FILE > $B2FILE
+echo -n "."
+# "9NGQ4WR" encodes "Mars"
+anastasis-reducer -a \
+ '{"authentication_method": {
+ "type": "question",
+ "instructions": "Where do you live?",
+ "challenge": "9NGQ4WR"
+ } }' \
+ add_authentication < $B2FILE > $B1FILE
+echo -n "."
+# Finished adding authentication methods
+anastasis-reducer \
+ next < $B1FILE > $B2FILE
+
+
+echo -n ","
+# Finished policy review
+anastasis-reducer \
+ next < $B2FILE > $B1FILE
+echo -n "."
+
+# Note: 'secret' must here be a Crockford base32-encoded value
+anastasis-reducer -a \
+ '{"secret": { "value" : "VERYHARDT0GVESSSECRET", "mime" : "text/plain" }}' \
+ enter_secret < $B1FILE > $B2FILE
+anastasis-reducer next $B2FILE $B1FILE
+echo " OK"
+
+echo -n "Final backup checks ..."
+STATE=`jq -r -e .backup_state < $B1FILE`
+if test "$STATE" != "BACKUP_FINISHED"
+then
+ exit_fail "Expected new state to be 'BACKUP_FINISHED', got '$STATE'"
+fi
+
+jq -r -e .core_secret < $B1FILE > /dev/null && exit_fail "'core_secret' was not cleared upon success"
+
+echo " OK"
+
+
+echo -n "Running recovery basic logic ..."
+anastasis-reducer -r > $R1FILE
+anastasis-reducer -a \
+ '{"continent": "Demoworld"}' \
+ select_continent < $R1FILE > $R2FILE
+anastasis-reducer -a \
+ '{"country_code": "xx" }' \
+ select_country < $R2FILE > $R1FILE
+anastasis-reducer -a '{"identity_attributes": { "full_name": "Max Musterman", "sq_number": "4", "birthdate": "2000-01-01" }}' enter_user_attributes < $R1FILE > $R2FILE
+
+
+STATE=`jq -r -e .recovery_state < $R2FILE`
+if test "$STATE" != "SECRET_SELECTING"
+then
+ exit_fail "Expected new state to be 'SECRET_SELECTING', got '$STATE'"
+fi
+echo " OK"
+
+echo -n "Adding provider (to ensure it is loaded)"
+anastasis-reducer -a '{"provider_url" : "http://localhost:8086/" }' add_provider < $R2FILE > $R1FILE
+echo " OK"
+
+echo -n "Selecting secret to recover"
+anastasis-reducer -a '{"attribute_mask": 0, "providers" : [ { "version": 1, "url" : "http://localhost:8086/" } ] }' select_version < $R1FILE > $R2FILE
+
+STATE=`jq -r -e .recovery_state < $R2FILE`
+if test "$STATE" != "CHALLENGE_SELECTING"
+then
+ exit_fail "Expected new state to be 'CHALLENGE_SELECTING', got '$STATE'"
+fi
+echo " OK"
+
+cat $R2FILE > $R1FILE
+sync_providers $R1FILE $R2FILE
+
+echo -n "Running challenge logic ..."
+
+cat $R2FILE | jq .
+
+UUID0=`jq -r -e .recovery_information.challenges[0].uuid < $R2FILE`
+UUID1=`jq -r -e .recovery_information.challenges[1].uuid < $R2FILE`
+UUID2=`jq -r -e .recovery_information.challenges[2].uuid < $R2FILE`
+UUID0Q=`jq -r -e .recovery_information.challenges[0].instructions < $R2FILE`
+UUID1Q=`jq -r -e .recovery_information.challenges[1].instructions < $R2FILE`
+UUID2Q=`jq -r -e .recovery_information.challenges[2].instructions < $R2FILE`
+
+if test "$UUID2Q" = 'How old are you?'
+then
+ AGE_UUID=$UUID2
+elif test "$UUID1Q" = 'How old are you?'
+then
+ AGE_UUID=$UUID1
+else
+ AGE_UUID=$UUID0
+fi
+
+if test "$UUID2Q" = 'What is your name?'
+then
+ NAME_UUID=$UUID2
+elif test "$UUID1Q" = 'What is your name?'
+then
+ NAME_UUID=$UUID1
+else
+ NAME_UUID=$UUID0
+fi
+
+anastasis-reducer -a \
+ "$(jq -n '
+ {
+ uuid: $UUID
+ }' \
+ --arg UUID "$NAME_UUID"
+ )" \
+ select_challenge < $R2FILE > $R1FILE
+
+anastasis-reducer -a '{"answer": "Hans"}' \
+ solve_challenge < $R1FILE > $R2FILE
+
+anastasis-reducer -a \
+ "$(jq -n '
+ {
+ uuid: $UUID
+ }' \
+ --arg UUID "$AGE_UUID"
+ )" \
+ select_challenge < $R2FILE > $R1FILE
+
+anastasis-reducer -a '{"answer": "123"}' \
+ solve_challenge < $R1FILE > $R2FILE
+
+echo " OK"
+
+echo -n "Checking recovered secret ..."
+# finally: check here that we recovered the secret...
+
+STATE=`jq -r -e .recovery_state < $R2FILE`
+if test "$STATE" != "RECOVERY_FINISHED"
+then
+ jq -e . $R2FILE
+ exit_fail "Expected new state to be 'RECOVERY_FINISHED', got '$STATE'"
+fi
+
+SECRET=`jq -r -e .core_secret.value < $R2FILE`
+if test "$SECRET" != "VERYHARDT0GVESSSECRET"
+then
+ jq -e . $R2FILE
+ exit_fail "Expected recovered secret to be 'VERYHARDT0GVESSSECRET', got '$SECRET'"
+fi
+
+MIME=`jq -r -e .core_secret.mime < $R2FILE`
+if test "$MIME" != "text/plain"
+then
+ jq -e . $R2FILE
+ exit_fail "Expected recovered mime to be 'text/plain', got '$MIME'"
+fi
+
+echo " OK"
+
+exit 0
diff --git a/src/cli/test_anastasis_reducer_select_continent.sh b/src/cli/test_anastasis_reducer_select_continent.sh
index 4cd8a84..bd1ce95 100755
--- a/src/cli/test_anastasis_reducer_select_continent.sh
+++ b/src/cli/test_anastasis_reducer_select_continent.sh
@@ -41,7 +41,7 @@ echo " FOUND"
# Test continent selection in a backup state
echo -n "Test continent selection in a backup state ..."
-anastasis-reducer -a '{"continent": "Testcontinent"}' select_continent resources/00-backup.json $TFILE
+anastasis-reducer -a '{"continent": "Demoworld"}' select_continent resources/00-backup.json $TFILE
STATE=`jq -r -e .backup_state < $TFILE`
if test "$STATE" != "COUNTRY_SELECTING"
@@ -49,9 +49,9 @@ then
exit_fail "Expected new state to be COUNTRY_SELECTING, got $STATE"
fi
SELECTED_CONTINENT=`jq -r -e .selected_continent < $TFILE`
-if test "$SELECTED_CONTINENT" != "Testcontinent"
+if test "$SELECTED_CONTINENT" != "Demoworld"
then
- exit_fail "Expected selected continent to be Testcontinent, got $SELECTED_CONTINENT"
+ exit_fail "Expected selected continent to be Demoworld, got $SELECTED_CONTINENT"
fi
COUNTRIES=`jq -r -e .countries < $TFILE`
if test "$COUNTRIES" == NULL
@@ -68,7 +68,7 @@ anastasis-reducer -a '{"continent": "Pangaia"}' select_continent resources/00-re
echo " OK"
echo -n "Test continent selection in a recovery state ..."
-anastasis-reducer -a '{"continent": "Testcontinent"}' select_continent resources/00-recovery.json $TFILE
+anastasis-reducer -a '{"continent": "Demoworld"}' select_continent resources/00-recovery.json $TFILE
STATE=`jq -r -e .recovery_state < $TFILE`
if test "$STATE" != "COUNTRY_SELECTING"
@@ -79,12 +79,11 @@ jq -e .countries[0] < $TFILE > /dev/null || exit_fail "Expected new state to inc
jq -e .countries[0].code < $TFILE > /dev/null || exit_fail "Expected new state to include countries with code"
jq -e .countries[0].continent < $TFILE > /dev/null || exit_fail "Expected new state to include countries with continent"
jq -e .countries[0].name < $TFILE > /dev/null || exit_fail "Expected new state to include countries with name"
-jq -e .countries[0].currency < $TFILE > /dev/null || exit_fail "Expected new state to include countries with currency"
SELECTED_CONTINENT=`jq -r -e .selected_continent < $TFILE`
-if test "$SELECTED_CONTINENT" != "Testcontinent"
+if test "$SELECTED_CONTINENT" != "Demoworld"
then
- exit_fail "Expected selected continent to be 'Testcontinent', got $SELECTED_CONTINENT"
+ exit_fail "Expected selected continent to be 'Demoworld', got $SELECTED_CONTINENT"
fi
COUNTRIES=`jq -r -e .countries < $TFILE`
@@ -96,7 +95,6 @@ jq -e .countries[0] < $TFILE > /dev/null || exit_fail "Expected new state to inc
jq -e .countries[0].code < $TFILE > /dev/null || exit_fail "Expected new state to include countries with code"
jq -e .countries[0].continent < $TFILE > /dev/null || exit_fail "Expected new state to include countries with continent"
jq -e .countries[0].name < $TFILE > /dev/null || exit_fail "Expected new state to include countries with name"
-jq -e .countries[0].currency < $TFILE > /dev/null || exit_fail "Expected new state to include countries with currency"
echo " OK"
diff --git a/src/cli/test_anastasis_reducer_select_country.sh b/src/cli/test_anastasis_reducer_select_country.sh
index c02f61f..2e18f44 100755
--- a/src/cli/test_anastasis_reducer_select_country.sh
+++ b/src/cli/test_anastasis_reducer_select_country.sh
@@ -63,12 +63,11 @@ jq -e .countries[0] < $TFILE > /dev/null || exit_fail "Expected new state to inc
jq -e .countries[0].code < $TFILE > /dev/null || exit_fail "Expected new state to include countries with code"
jq -e .countries[0].continent < $TFILE > /dev/null || exit_fail "Expected new state to include countries with continent"
jq -e .countries[0].name < $TFILE > /dev/null || exit_fail "Expected new state to include countries with name"
-jq -e .countries[0].currency < $TFILE > /dev/null || exit_fail "Expected new state to include countries with currency"
SELECTED_CONTINENT=`jq -r -e .selected_continent < $TFILE`
if test "$SELECTED_CONTINENT" != "Europe"
then
- exit_fail "Expected selected continent to be 'Testcontinent', got $SELECTED_CONTINENT"
+ exit_fail "Expected selected continent to be 'Europe', got $SELECTED_CONTINENT"
fi
echo " OK"
@@ -84,8 +83,7 @@ echo " OK"
echo -n "Test NX country selection ..."
anastasis-reducer -a \
- '{"country_code": "zz",
- "currencies": ["EUR" ]}' \
+ '{"country_code": "zz"}' \
select_country \
resources/01-backup.json $TFILE 2> /dev/null \
&& exit_fail "Expected selection to fail. Check '$TFILE'"
@@ -95,8 +93,7 @@ echo " OK"
echo -n "Test invalid country selection for continent ..."
anastasis-reducer -a \
- '{"country_code": "de",
- "currencies":["EUR"]}' \
+ '{"country_code": "de"}' \
select_country \
resources/01-backup.json $TFILE 2> /dev/null \
&& exit_fail "Expected selection to fail. Check '$TFILE'"
@@ -106,8 +103,7 @@ echo " OK"
echo -n "Test country selection ..."
anastasis-reducer -a \
- '{"country_code": "xx",
- "currencies":["TESTKUDOS"]}' \
+ '{"country_code": "xx"}' \
select_country resources/01-backup.json $TFILE
STATE=`jq -r -e .backup_state < $TFILE`
@@ -122,12 +118,6 @@ then
exit_fail "Expected selected country to be 'xx', got '$SELECTED_COUNTRY'"
fi
echo -n "."
-SELECTED_CURRENCY=`jq -r -e .currencies[0] < $TFILE`
-if test "$SELECTED_CURRENCY" != "TESTKUDOS"
-then
- exit_fail "Expected selected currency to be 'TESTKUDOS', got '$SELECTED_CURRENCY'"
-fi
-echo -n "."
REQ_ATTRIBUTES=`jq -r -e .required_attributes < $TFILE`
if test "$REQ_ATTRIBUTES" == NULL
then
diff --git a/src/cli/test_free_reducer.conf b/src/cli/test_free_reducer.conf
index 74954cd..8308537 100644
--- a/src/cli/test_free_reducer.conf
+++ b/src/cli/test_free_reducer.conf
@@ -11,7 +11,7 @@ UPLOAD_LIMIT_MB = 1
ANNUAL_POLICY_UPLOAD_LIMIT = 128
INSURANCE = EUR:0
PORT = 8086
-SERVER_SALT = BUfO1KGOKYIFlFQg
+PROVIDER_SALT = BUfO1KGOKYIFlFQg
BUSINESS_NAME = "Data loss Inc."
[stasis]
diff --git a/src/cli/test_iban.sh b/src/cli/test_iban.sh
index c3e858c..207d2d5 100755
--- a/src/cli/test_iban.sh
+++ b/src/cli/test_iban.sh
@@ -1,6 +1,8 @@
#!/bin/bash
+# This file is in the public domain.
set -eu
+#set -x
# Exit, with status code "skip" (no 'real' failure)
function exit_skip() {
@@ -17,38 +19,66 @@ function exit_fail() {
# Cleanup to run whenever we exit
function cleanup()
{
- for n in `jobs -p`
+ for n in $(jobs -p)
do
- kill $n 2> /dev/null || true
+ kill "$n" 2> /dev/null || true
done
- rm -rf $CONF $R1FILE $R2FILE $B1FILE $B2FILE
+ rm -rf "$CONF" "$R1FILE" "$R2FILE" "$B1FILE" "$B2FILE"
wait
}
# $1=ebics username, $2=ebics partner name, $3=person name, $4=sandbox bank account name, $5=iban
function prepare_sandbox_account() {
- echo -n "Activating ebics subscriber $1 at the sandbox ..."
- libeufin-cli \
- sandbox --sandbox-url=$SANDBOX_URL \
- ebicssubscriber create \
- --host-id=$EBICS_HOST \
- --partner-id=$2 \
- --user-id=$1
+ echo -n "Registering $4 to the Sandbox..."
+ export LIBEUFIN_SANDBOX_USERNAME="$4"
+ export LIBEUFIN_SANDBOX_PASSWORD=unused
+ libeufin-cli sandbox --sandbox-url="$SANDBOX_URL" \
+ demobank register --name "$3" --iban "$5"
echo " OK"
- echo -n "Giving a bank account ($4) to $1 ..."
- libeufin-cli \
- sandbox --sandbox-url=$SANDBOX_URL \
- ebicsbankaccount create \
- --iban=$5 \
- --bic="BCMAESM1XXX"\
- --person-name="$3" \
- --account-name=$4 \
- --ebics-user-id=$1 \
- --ebics-host-id=$EBICS_HOST \
- --ebics-partner-id=$2 \
- --currency=$CURRENCY
+ echo -n "Associating a EBICS subscriber to $4..."
+ export LIBEUFIN_SANDBOX_USERNAME=admin
+ libeufin-cli sandbox --sandbox-url="$SANDBOX_URL" demobank new-ebicssubscriber \
+ --host-id "$EBICS_HOST" \
+ --user-id "$1" --partner-id "$2" \
+ --bank-account "$4" # that's a username _and_ a bank account name
echo " OK"
+
+ unset LIBEUFIN_SANDBOX_USERNAME
+ unset LIBEUFIN_SANDBOX_PASSWORD
+}
+
+function sync_providers() {
+ infile="$1"
+ outfile="$2"
+ echo "Synchronizing providers"
+ # Sync with providers (up to 3 providers aren't synced here)
+ for x in 1 2 3; do
+ echo "Synchronizing providers (round $x)"
+ anastasis-reducer sync_providers < "$infile" > "$outfile" 2> /dev/null || true
+ CODE=$(jq -r -e ".code // 0" < $outfile)
+ # ANASTASIS_REDUCER_PROVIDERS_ALREADY_SYNCED
+ # FIXME: Temporary workaround for C reducer. See #7227.
+ if [ "$CODE" = "8420" ]
+ then
+ # restore previous non-error state
+ cp "$infile" "$outfile"
+ break
+ fi
+ # ANASTASIS_REDUCER_ACTION_INVALID
+ if [ "$CODE" = "8400" ]
+ then
+ # restore previous non-error state
+ cp "$infile" "$outfile"
+ break
+ fi
+ if [ "$CODE" != "0" ]
+ then
+ exit_fail "Expected no error or 8420/8400, got $CODE"
+ fi
+ cp "$outfile" "$infile"
+ done
+ echo "Providers synced."
}
@@ -61,13 +91,19 @@ trap cleanup EXIT
# to pass through the Nexus+Ebics layer to issue the payment
# $1 = amount ($CURRENCY:X.Y), $2 = subject.
function wire_transfer_to_anastasis() {
+ echo -n "Initiating wire transfer ..."
libeufin-sandbox make-transaction \
--debit-account=sandbox-account-debit \
- --credit-account=sandbox-account-credit "$1" "$2"
- # Sync nexus with sandbox
- export LIBEUFIN_NEXUS_USERNAME=$CREDIT_USERNAME
- export LIBEUFIN_NEXUS_PASSWORD=$CREDIT_PASSWORD
- libeufin-cli accounts fetch-transactions nexus-bankaccount-credit > /dev/null
+ --credit-account=sandbox-account-credit "$1" "$2" &> libeufin-transfer-initiate.out
+ echo " OK"
+ # FIXME-MS: the following command reports that it did not
+ # sync any transactions, even though presumably we just
+ # made one in the one above (which succeeded...)
+ echo -n "Syncing nexus with sandbox ..."
+ export LIBEUFIN_NEXUS_USERNAME="$CREDIT_USERNAME"
+ export LIBEUFIN_NEXUS_PASSWORD="$CREDIT_PASSWORD"
+ libeufin-cli accounts fetch-transactions nexus-bankaccount-credit &> libeufin-transfer-fetch.out
+ echo " OK"
}
# $1 = facade base URL. Merely a debug utility.
@@ -82,43 +118,33 @@ function prepare_nexus_account() {
echo -n "Making bank connection $3 ..."
libeufin-cli connections new-ebics-connection \
--ebics-url="${SANDBOX_URL}ebicsweb" \
- --host-id=$EBICS_HOST \
- --partner-id=$2 \
- --ebics-user-id=$1 \
+ --host-id="$EBICS_HOST" \
+ --partner-id="$2" \
+ --ebics-user-id="$1" \
$3 > /dev/null
echo " OK"
echo -n "Connecting $3 ..."
- libeufin-cli connections connect $3 > /dev/null
+ libeufin-cli connections connect "$3" > /dev/null
echo " OK"
echo -n "Importing Sandbox bank account ($5) to Nexus ($4) ..."
- libeufin-cli connections download-bank-accounts $3 > /dev/null
+ libeufin-cli connections download-bank-accounts "$3" > /dev/null
libeufin-cli connections import-bank-account \
- --offered-account-id=$5 --nexus-bank-account-id=$4 $3 > /dev/null
+ --offered-account-id="$5" --nexus-bank-account-id="$4" "$3" > /dev/null
echo " OK"
}
-# $1 = facade name, $2 = bank connection to use, $3 = bank account name
-# local to Nexus
-function prepare_anastasis_facade() {
- echo -n "Creating facade ..."
- libeufin-cli facades new-anastasis-facade \
- --currency=$CURRENCY \
- --facade-name=$1 \
- $2 $3
- echo " OK"
- # No need to setup facade permissions, as the anastasis client
- # is superuser at Nexus.
-}
# Configuration file will be edited, so we create one
# from the template.
-CONF=`mktemp test_free_reducerXXXXXX.conf`
-cp test_free_reducer.conf $CONF
+CONF=$(mktemp test_free_reducerXXXXXX.conf)
+cp test_free_reducer.conf "$CONF"
-B1FILE=`mktemp test_reducer_stateB1XXXXXX`
-B2FILE=`mktemp test_reducer_stateB2XXXXXX`
-R1FILE=`mktemp test_reducer_stateR1XXXXXX`
-R2FILE=`mktemp test_reducer_stateR2XXXXXX`
+
+
+B1FILE=$(mktemp test_reducer_stateB1XXXXXX)
+B2FILE=$(mktemp test_reducer_stateB2XXXXXX)
+R1FILE=$(mktemp test_reducer_stateR1XXXXXX)
+R2FILE=$(mktemp test_reducer_stateR2XXXXXX)
export CONF
export B2FILE
@@ -146,23 +172,40 @@ echo -n "Testing for anastasis-reducer ..."
anastasis-reducer -h > /dev/null || exit_skip "anastasis-reducer required"
echo " FOUND"
-export LIBEUFIN_NEXUS_DB_CONNECTION="jdbc:sqlite:$(mktemp -u /tmp/nexus-db-XXXXXX.sqlite)"
-export LIBEUFIN_SANDBOX_DB_CONNECTION="jdbc:sqlite:$(mktemp -u /tmp/sandbox-db-XXXXXX.sqlite)"
+echo -n "Initialize Anastasis database ..."
+# Name of the Postgres database we will use for the script.
+# Will be dropped, do NOT use anything that might be used
+# elsewhere
+
+TARGET_DB=$(anastasis-config -c "$CONF" -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///")
+
+dropdb "$TARGET_DB" >/dev/null 2>/dev/null || true
+createdb "$TARGET_DB" || exit_skip "Could not create database $TARGET_DB"
+anastasis-dbinit -c "$CONF" 2> anastasis-dbinit.log
+
+echo " OK"
+
+
+export LIBEUFIN_NEXUS_DB_CONNECTION="postgres:///anastasischeck"
+export LIBEUFIN_SANDBOX_DB_CONNECTION="postgres:///anastasischeck"
NEXUS_URL="http://localhost:5001/"
SANDBOX_URL="http://localhost:5000/"
echo -n "Starting Nexus ..."
libeufin-nexus serve &> nexus.log &
nexus_pid=$!
-if ! curl -s --retry 5 --retry-connrefused $NEXUS_URL > /dev/null; then
+if ! curl -s --retry 5 --retry-connrefused "$NEXUS_URL" > /dev/null; then
exit_skip "Could not launch Nexus"
fi
echo " OK"
+echo -n "Configuring Sandbox..."
+libeufin-sandbox config default &> sandbox-config.log
+echo " OK"
echo -n "Starting Sandbox ..."
-libeufin-sandbox serve &> sandbox.log &
+libeufin-sandbox serve --no-auth &> sandbox-serve.log &
sandbox_pid=$!
-if ! curl -s --retry 5 --retry-connrefused $SANDBOX_URL > /dev/null; then
+if ! curl -s --retry 5 --retry-connrefused "$SANDBOX_URL" > /dev/null; then
exit_skip "Could not launch Sandbox"
fi
echo " OK"
@@ -174,11 +217,11 @@ EBICS_HOST="ebicstesthost"
export IBAN_CREDIT="DE89370400440532013000"
export IBAN_DEBIT="FR1420041010050500013M02606"
-echo -n "Preparing Sandbox ..."
+echo -n "Preparing Sandbox (creating the EBICS host) ..."
libeufin-cli \
- sandbox --sandbox-url=$SANDBOX_URL \
+ sandbox --sandbox-url="$SANDBOX_URL" \
ebicshost create \
- --host-id=$EBICS_HOST
+ --host-id="$EBICS_HOST"
echo " OK"
PERSON_CREDIT_NAME="Person Credit"
@@ -189,32 +232,32 @@ prepare_sandbox_account \
ebicspartnerCredit \
"${PERSON_CREDIT_NAME}" \
sandbox-account-credit \
- $IBAN_CREDIT
+ "$IBAN_CREDIT"
prepare_sandbox_account \
ebicsuserDebit \
ebicspartnerDebit \
"Person Debit" \
sandbox-account-debit \
- $IBAN_DEBIT
+ "$IBAN_DEBIT"
echo "Sandbox preparation done"
echo -n "Preparing Nexus ..."
-export LIBEUFIN_NEXUS_URL=$NEXUS_URL
+export LIBEUFIN_NEXUS_URL="$NEXUS_URL"
# Make debit user, will buy Anastasis services.
DEBIT_USERNAME=anastasis-debit-user
DEBIT_PASSWORD=anastasis-debit-password
-libeufin-nexus superuser $DEBIT_USERNAME --password=$DEBIT_PASSWORD
+libeufin-nexus superuser "$DEBIT_USERNAME" --password="$DEBIT_PASSWORD"
echo " OK"
-export LIBEUFIN_NEXUS_USERNAME=$DEBIT_USERNAME
-export LIBEUFIN_NEXUS_PASSWORD=$DEBIT_PASSWORD
+export LIBEUFIN_NEXUS_USERNAME="$DEBIT_USERNAME"
+export LIBEUFIN_NEXUS_PASSWORD="$DEBIT_PASSWORD"
# Make credit user, will be Anastasis client.
CREDIT_USERNAME=anastasis-credit-user
CREDIT_PASSWORD=anastasis-credit-password
echo -n "Create credit user (for anastasis) at Nexus ..."
-libeufin-nexus superuser $CREDIT_USERNAME --password=$CREDIT_PASSWORD
+libeufin-nexus superuser "$CREDIT_USERNAME" --password="$CREDIT_PASSWORD"
echo " OK"
-export LIBEUFIN_NEXUS_USERNAME=$CREDIT_USERNAME
-export LIBEUFIN_NEXUS_PASSWORD=$CREDIT_PASSWORD
+export LIBEUFIN_NEXUS_USERNAME="$CREDIT_USERNAME"
+export LIBEUFIN_NEXUS_PASSWORD="$CREDIT_PASSWORD"
prepare_nexus_account \
ebicsuserCredit \
@@ -225,7 +268,7 @@ prepare_nexus_account \
echo -n "Create facade ..."
libeufin-cli facades new-anastasis-facade \
- --currency=$CURRENCY \
+ --currency="$CURRENCY" \
--facade-name=facade-credit \
bankconnection-credit nexus-bankaccount-credit
echo " OK"
@@ -233,41 +276,29 @@ FACADE_URL=$(libeufin-cli facades list | jq .facades[0].baseUrl | tr -d \")
## Reach facade with: $FACADE_URL + $CREDIT_USERNAME + $CREDIT_PASSWORD
-echo -n "Initialize Anastasis database ..."
-# Name of the Postgres database we will use for the script.
-# Will be dropped, do NOT use anything that might be used
-# elsewhere
-
-TARGET_DB=`anastasis-config -c $CONF -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"`
-
-dropdb $TARGET_DB >/dev/null 2>/dev/null || true
-createdb $TARGET_DB || exit_skip "Could not create database $TARGET_DB"
-anastasis-dbinit -c $CONF 2> anastasis-dbinit.log
-
-echo " OK"
echo -n "Configuring Anastasis IBAN account ..."
-anastasis-config -c $CONF \
+anastasis-config -c "$CONF" \
-s authorization-iban \
-o CREDIT_IBAN \
-V "${IBAN_CREDIT}"
-anastasis-config -c $CONF \
+anastasis-config -c "$CONF" \
-s authorization-iban \
-o BUSINESS_NAME \
-V "${PERSON_CREDIT_NAME}"
-anastasis-config -c $CONF \
+anastasis-config -c "$CONF" \
-s authorization-iban \
-o WIRE_GATEWAY_URL \
-V "${FACADE_URL}"
-anastasis-config -c $CONF \
+anastasis-config -c "$CONF" \
-s authorization-iban \
-o WIRE_GATEWAY_AUTH_METHOD \
-V "basic"
-anastasis-config -c $CONF \
+anastasis-config -c "$CONF" \
-s authorization-iban \
-o USERNAME \
-V "${LIBEUFIN_NEXUS_USERNAME}"
-anastasis-config -c $CONF \
+anastasis-config -c "$CONF" \
-s authorization-iban \
-o PASSWORD \
-V "${LIBEUFIN_NEXUS_PASSWORD}"
@@ -275,12 +306,12 @@ echo " OK"
echo -n "Launching Anastasis service ..."
PREFIX="" #valgrind
-$PREFIX anastasis-httpd -c $CONF -L INFO 2> anastasis-httpd_1.log &
+$PREFIX anastasis-httpd -c "$CONF" -L INFO 2> anastasis-httpd_1.log &
echo " OK"
echo -n "Waiting for Anastasis service ..."
# Wait for Anastasis service to be available
-for n in `seq 1 50`
+for n in $(seq 1 50)
do
echo -n "."
sleep 0.1
@@ -297,16 +328,15 @@ fi
echo "OK"
echo -n "Running backup logic ...,"
-anastasis-reducer -b > $B1FILE
+anastasis-reducer -b > "$B1FILE"
echo -n "."
anastasis-reducer -a \
- '{"continent": "Testcontinent"}' \
- select_continent < $B1FILE > $B2FILE
+ '{"continent": "Demoworld"}' \
+ select_continent < "$B1FILE" > "$B2FILE"
echo -n "."
anastasis-reducer -a \
- '{"country_code": "xx",
- "currencies":["TESTKUDOS"]}' \
- select_country < $B2FILE > $B1FILE 2>> test_reducer.err
+ '{"country_code": "xx" }' \
+ select_country < "$B2FILE" > "$B1FILE" 2>> test_reducer.err
echo -n "."
anastasis-reducer -a \
@@ -314,9 +344,12 @@ anastasis-reducer -a \
"full_name": "Max Musterman",
"sq_number": "4",
"birthdate": "2000-01-01"}}' \
- enter_user_attributes < $B1FILE > $B2FILE 2>> test_reducer.err
+ enter_user_attributes < "$B1FILE" > "$B2FILE" 2>> test_reducer.err
echo -n ","
-BASEIBAN=`echo -n $IBAN_DEBIT | gnunet-base32`
+cat "$B2FILE" > "$B1FILE"
+sync_providers "$B1FILE" "$B2FILE"
+echo -n ","
+BASEIBAN=$(echo -n $IBAN_DEBIT | gnunet-base32)
anastasis-reducer -a \
"$(jq -n '{ authentication_method: {
type: "iban",
@@ -325,67 +358,102 @@ anastasis-reducer -a \
} }' \
--arg CHALLENGE "$BASEIBAN"
)" \
- add_authentication < $B2FILE > $B1FILE 2>> test_reducer.err
+ add_authentication < "$B2FILE" > "$B1FILE" 2>> test_reducer.err
+echo -n "."
+
+# "91GPWWR" encodes "Hans"
+anastasis-reducer -a \
+ '{"authentication_method": {
+ "type": "question",
+ "instructions": "What is your name?",
+ "challenge": "91GPWWR"
+ } }' \
+ add_authentication < "$B1FILE" > "$B2FILE" 2>> test_reducer.err
echo -n "."
+
+mv "$B2FILE" "$B1FILE"
+
# Finished adding authentication methods
anastasis-reducer \
- next < $B1FILE > $B2FILE 2>> test_reducer.err
+ next < "$B1FILE" > "$B2FILE" 2>> test_reducer.err
echo -n ","
# Finished policy review
anastasis-reducer \
- next < $B2FILE > $B1FILE 2>> test_reducer.err
+ next < "$B2FILE" > "$B1FILE" 2>> test_reducer.err
echo -n "."
# Note: 'secret' must here be a Crockford base32-encoded value
anastasis-reducer -a \
'{"secret": { "value" : "VERYHARDT0GVESSSECRET", "mime" : "text/plain" }}' \
- enter_secret < $B1FILE > $B2FILE 2>> test_reducer.err
-mv $B2FILE $B1FILE
-anastasis-reducer next < $B1FILE > $B2FILE 2>> test_reducer.err
+ enter_secret < "$B1FILE" > "$B2FILE" 2>> test_reducer.err
+mv "$B2FILE" "$B1FILE"
+anastasis-reducer next < "$B1FILE" > "$B2FILE" 2>> test_reducer.err
echo " OK"
echo -n "Final backup checks ..."
-STATE=`jq -r -e .backup_state < $B2FILE`
-if test "$STATE" != "BACKUP_FINISHED"
+STATE=$(jq -r -e .backup_state < "$B2FILE")
+if [ "$STATE" != "BACKUP_FINISHED" ]
then
exit_fail "Expected new state to be 'BACKUP_FINISHED', got '$STATE'"
fi
-jq -r -e .core_secret < $B2FILE > /dev/null && exit_fail "'core_secret' was not cleared upon success"
+jq -r -e .core_secret < "$B2FILE" > /dev/null && exit_fail "'core_secret' was not cleared upon success"
echo " OK"
echo -n "Running recovery basic logic ..."
-anastasis-reducer -r > $R1FILE
+anastasis-reducer -r > "$R1FILE"
anastasis-reducer -a \
- '{"continent": "Testcontinent"}' \
- select_continent < $R1FILE > $R2FILE
+ '{"continent": "Demoworld"}' \
+ select_continent < "$R1FILE" > "$R2FILE"
anastasis-reducer -a \
'{"country_code": "xx",
"currencies":["TESTKUDOS"]}' \
- select_country < $R2FILE > $R1FILE 2>> test_reducer.err
-anastasis-reducer -a '{"identity_attributes": { "full_name": "Max Musterman", "sq_number": "4", "birthdate": "2000-01-01" }}' enter_user_attributes < $R1FILE > $R2FILE 2>> test_reducer.err
+ select_country < "$R2FILE" > "$R1FILE" 2>> test_reducer.err
+anastasis-reducer -a '{"identity_attributes": { "full_name": "Max Musterman", "sq_number": "4", "birthdate": "2000-01-01" }}' enter_user_attributes < "$R1FILE" > "$R2FILE" 2>> test_reducer.err
-STATE=`jq -r -e .recovery_state < $R2FILE`
-if test "$STATE" != "SECRET_SELECTING"
+STATE=$(jq -r -e .recovery_state < "$R2FILE")
+if [ "$STATE" != "SECRET_SELECTING" ]
then
exit_fail "Expected new state to be 'SECRET_SELECTING', got '$STATE'"
fi
echo " OK"
-echo -n "Selecting default secret"
-mv $R2FILE $R1FILE
-anastasis-reducer next < $R1FILE > $R2FILE 2>> test_reducer.err
+echo -n "Adding provider (to ensure it is loaded)"
+anastasis-reducer -a '{"provider_url" : "http://localhost:8086/" }' add_provider < "$R2FILE" > "$R1FILE"
+echo " OK"
+
+echo -n "Selecting secret to recover"
+anastasis-reducer -a '{"attribute_mask": 0, "providers" : [ { "version": 1, "url" : "http://localhost:8086/" } ] }' \
+ select_version < "$R1FILE" > "$R2FILE" 2>> test_reducer.err
-STATE=`jq -r -e .recovery_state < $R2FILE`
-if test "$STATE" != "CHALLENGE_SELECTING"
+STATE=$(jq -r -e .recovery_state < "$R2FILE")
+if [ "$STATE" != "CHALLENGE_SELECTING" ]
then
exit_fail "Expected new state to be 'CHALLENGE_SELECTING', got '$STATE'"
fi
echo " OK"
+cp "$R2FILE" "$R1FILE"
+sync_providers "$R1FILE" "$R2FILE"
+
echo -n "Running challenge selection logic ..."
-NAME_UUID=`jq -r -e .recovery_information.challenges[0].uuid < $R2FILE`
+UUID0=$(jq -r -e .recovery_information.challenges[0].uuid < "$R2FILE")
+UUID1=$(jq -r -e .recovery_information.challenges[1].uuid < "$R2FILE")
+UUID0Q=$(jq -r -e .recovery_information.challenges[0].instructions < "$R2FILE")
+UUID1Q=$(jq -r -e .recovery_information.challenges[1].instructions < "$R2FILE")
+
+if [ "$UUID1Q" = 'What is your name?' ]
+then
+ NAME_UUID=$UUID1
+ IBAN_UUID=$UUID0
+else
+ NAME_UUID=$UUID0
+ IBAN_UUID=$UUID1
+fi
+
+echo "OK"
+echo -n "Solving first challenge ..."
anastasis-reducer -a \
"$(jq -n '
{
@@ -393,64 +461,79 @@ anastasis-reducer -a \
}' \
--arg UUID "$NAME_UUID"
)" \
- select_challenge < $R2FILE > $R1FILE 2>> test_reducer.err
+ select_challenge < "$R2FILE" > "$R1FILE" 2>> test_reducer.err
+
+anastasis-reducer -a '{"answer": "Hans"}' \
+ solve_challenge < "$R1FILE" > "$R2FILE"
echo "OK"
+echo -n "Solving IBAN challenge ..."
+
+anastasis-reducer -a \
+ "$(jq -n '
+ {
+ uuid: $UUID
+ }' \
+ --arg UUID "$IBAN_UUID"
+ )" \
+ select_challenge < "$R2FILE" > "$R1FILE" 2>> test_reducer.err
+echo "OK"
+
-METHOD=`jq -r -e .challenge_feedback.\"$NAME_UUID\".method < $R1FILE`
-if test "$METHOD" != "iban"
+METHOD=$(jq -r -e .challenge_feedback.\"$IBAN_UUID\".state < "$R1FILE")
+if [ "$METHOD" != "iban-instructions" ]
then
- exit_fail "Expected method to be 'iban', got ${METHOD}"
+ exit_fail "Expected method to be 'iban-instructions', got ${METHOD}"
fi
-ACC=`jq -r -e .challenge_feedback.\"$NAME_UUID\".details.credit_iban < $R1FILE`
-if test "$ACC" != ${IBAN_CREDIT}
+ACC=$(jq -r -e .challenge_feedback.\"$IBAN_UUID\".target_iban < "$R1FILE")
+if [ "$ACC" != "${IBAN_CREDIT}" ]
then
exit_fail "Expected account to be ${IBAN_CREDIT}, got ${ACC}"
fi
anastasis-reducer \
- back < $R1FILE > $R2FILE 2>> test_reducer.err
+ back < "$R1FILE" > "$R2FILE" 2>> test_reducer.err
-AMOUNT=`jq -r -e .challenge_feedback.\"$NAME_UUID\".details.challenge_amount < $R1FILE`
-SUBJECT=`jq -r -e .challenge_feedback.\"$NAME_UUID\".details.wire_transfer_subject < $R1FILE`
+AMOUNT=$(jq -r -e .challenge_feedback.\"$IBAN_UUID\".challenge_amount < "$R1FILE")
+SUBJECT=$(jq -r -e .challenge_feedback.\"$IBAN_UUID\".wire_transfer_subject < "$R1FILE")
-echo -n "Performing authorization wire transfer ..."
+echo -n "Performing authorization wire transfer ${SUBJECT} ..."
wire_transfer_to_anastasis "${AMOUNT}" "${SUBJECT}"
echo " OK"
echo -n "Triggering inbound check ..."
-anastasis-helper-authorization-iban -c $CONF -t
+anastasis-helper-authorization-iban -c "$CONF" -t -L INFO
echo " OK"
# Now we should get the secret...
echo -n "Polling for recovery ..."
-anastasis-reducer poll < $R2FILE > $R1FILE
+anastasis-reducer poll -L INFO < "$R2FILE" > "$R1FILE"
echo " OK"
echo -n "Checking recovered secret ..."
# finally: check here that we recovered the secret...
-STATE=`jq -r -e .recovery_state < $R1FILE`
-if test "$STATE" != "RECOVERY_FINISHED"
+STATE=$(jq -r -e .recovery_state < "$R1FILE")
+if [ "$STATE" != "RECOVERY_FINISHED" ]
then
- jq -e . $R1FILE
+ jq -e . "$R1FILE"
exit_fail "Expected new state to be 'RECOVERY_FINISHED', got '$STATE'"
fi
-SECRET=`jq -r -e .core_secret.value < $R1FILE`
-if test "$SECRET" != "VERYHARDT0GVESSSECRET"
+SECRET=$(jq -r -e .core_secret.value < "$R1FILE")
+if [ "$SECRET" != "VERYHARDT0GVESSSECRET" ]
then
- jq -e . $R1FILE
+ jq -e . "$R1FILE"
exit_fail "Expected recovered secret to be 'VERYHARDT0GVESSSECRET', got '$SECRET'"
fi
-MIME=`jq -r -e .core_secret.mime < $R1FILE`
-if test "$MIME" != "text/plain"
+MIME=$(jq -r -e .core_secret.mime < "$R1FILE")
+if [ "$MIME" != "text/plain" ]
then
- jq -e . $R1FILE
+ jq -e . "$R1FILE"
exit_fail "Expected recovered mime to be 'text/plain', got '$MIME'"
fi
diff --git a/src/cli/test_reducer.conf b/src/cli/test_reducer.conf
index df68b14..4f26a79 100644
--- a/src/cli/test_reducer.conf
+++ b/src/cli/test_reducer.conf
@@ -26,9 +26,10 @@ COST = TESTKUDOS:0.0
[exchange]
+MASTER_PUBLIC_KEY = 3NX5DJDBD8XVGZYHV3PBF8C3Z4GK48XD59YY5GF3CZE8AJM04WSG
+AML_THRESHOLD = TESTKUDOS:1000000
MAX_KEYS_CACHING = forever
DB = postgres
-MASTER_PRIV_FILE = ${TALER_DATA_HOME}/exchange/offline-keys/master.priv
SERVE = tcp
UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http
UNIXPATH_MODE = 660
@@ -39,26 +40,40 @@ SIGNKEY_LEGAL_DURATION = 2 years
LEGAL_DURATION = 2 years
LOOKAHEAD_SIGN = 3 weeks 1 day
LOOKAHEAD_PROVIDE = 2 weeks 1 day
-KEYDIR = ${TALER_DATA_HOME}/exchange/live-keys/
-REVOCATION_DIR = ${TALER_DATA_HOME}/exchange/revocations/
TERMS_ETAG = 0
PRIVACY_ETAG = 0
+STEFAN_ABS = "TESTKUDOS:5"
+
+# Account of the EXCHANGE
+[exchange-account-1]
+# What is the exchange's bank account (with the "Taler Bank" demo system)?
+PAYTO_URI = payto://iban/SANDBOXX/DE989651?receiver-name=Exchange+Company
+ENABLE_DEBIT = YES
+ENABLE_CREDIT = YES
+
+[exchange-accountcredentials-1]
+WIRE_GATEWAY_URL = http://localhost:18082/accounts/exchange/taler-wire-gateway/
+WIRE_GATEWAY_AUTH_METHOD = basic
+USERNAME = exchange
+PASSWORD = x
+
+
+[exchange-account-2]
+PAYTO_URI = "payto://x-taler-bank/localhost/exchange?receiver-name=exchange"
+ENABLE_DEBIT = YES
+ENABLE_CREDIT = YES
+
+[exchange-accountcredentials-2]
+WIRE_GATEWAY_AUTH_METHOD = none
+WIRE_GATEWAY_URL = "http://localhost:18082/accounts/exchange/taler-wire-gateway/"
[merchant]
SERVE = tcp
PORT = 9966
UNIXPATH = ${TALER_RUNTIME_DIR}/merchant.http
UNIXPATH_MODE = 660
-DEFAULT_WIRE_FEE_AMORTIZATION = 1
DB = postgres
-WIREFORMAT = default
-# Set very low, so we can be sure that the database generated
-# will contain wire transfers "ready" for the aggregator.
-WIRE_TRANSFER_DELAY = 1 minute
-DEFAULT_PAY_DEADLINE = 1 day
-DEFAULT_MAX_DEPOSIT_FEE = TESTKUDOS:0.1
KEYFILE = ${TALER_DATA_HOME}/merchant/merchant.priv
-DEFAULT_MAX_WIRE_FEE = TESTKUDOS:0.10
# Ensure that merchant reports EVERY deposit confirmation to auditor
FORCE_AUDIT = YES
@@ -79,30 +94,41 @@ BASE_URL = "http://localhost:8083/"
DATABASE = postgres:///taler-auditor-basedb
MAX_DEBT = TESTKUDOS:50.0
MAX_DEBT_BANK = TESTKUDOS:100000.0
-HTTP_PORT = 8082
+HTTP_PORT = 18082
SUGGESTED_EXCHANGE = http://localhost:8081/
SUGGESTED_EXCHANGE_PAYTO = payto://x-taler-bank/localhost/2
ALLOW_REGISTRATIONS = YES
SERVE = http
+[libeufin-bank]
+CURRENCY = TESTKUDOS
+WIRE_TYPE = iban
+IBAN_PAYTO_BIC = SANDBOXX
+DEFAULT_CUSTOMER_DEBT_LIMIT = TESTKUDOS:200
+DEFAULT_ADMIN_DEBT_LIMIT = TESTKUDOS:2000
+REGISTRATION_BONUS_ENABLED = yes
+REGISTRATION_BONUS = TESTKUDOS:100
+SUGGESTED_WITHDRAWAL_EXCHANGE = http://localhost:8081/
+SERVE = tcp
+PORT = 18082
+
[exchangedb]
IDLE_RESERVE_EXPIRATION_TIME = 4 weeks
LEGAL_RESERVE_EXPIRATION_TIME = 7 years
-[exchange-account-1]
-PAYTO_URI = payto://x-taler-bank/localhost/Exchange
-enable_debit = yes
-enable_credit = yes
+[auditordb-postgres]
+CONFIG = "postgres:///talercheck"
-[exchange-accountcredentials-1]
-WIRE_GATEWAY_URL = "http://localhost:8082/taler-wire-gateway/Exchange/"
-WIRE_GATEWAY_AUTH_METHOD = basic
-USERNAME = Exchange
-PASSWORD = x
+[exchangedb-postgres]
+CONFIG = "postgres:///talercheck"
+
+[merchantdb-postgres]
+CONFIG = "postgres:///talercheck"
[merchant-exchange-default]
EXCHANGE_BASE_URL = http://localhost:8081/
CURRENCY = TESTKUDOS
+MASTER_KEY = 3NX5DJDBD8XVGZYHV3PBF8C3Z4GK48XD59YY5GF3CZE8AJM04WSG
[payments-generator]
currency = TESTKUDOS
@@ -123,6 +149,7 @@ fee_deposit = TESTKUDOS:0.01
fee_refresh = TESTKUDOS:0.01
fee_refund = TESTKUDOS:0.01
rsa_keysize = 1024
+CIPHER = RSA
[coin_kudos_ct_10]
value = TESTKUDOS:0.10
@@ -134,6 +161,7 @@ fee_deposit = TESTKUDOS:0.01
fee_refresh = TESTKUDOS:0.03
fee_refund = TESTKUDOS:0.01
rsa_keysize = 1024
+CIPHER = RSA
[coin_kudos_1]
value = TESTKUDOS:1
@@ -145,6 +173,7 @@ fee_deposit = TESTKUDOS:0.02
fee_refresh = TESTKUDOS:0.03
fee_refund = TESTKUDOS:0.01
rsa_keysize = 1024
+CIPHER = RSA
[coin_kudos_2]
value = TESTKUDOS:2
@@ -156,6 +185,7 @@ fee_deposit = TESTKUDOS:0.03
fee_refresh = TESTKUDOS:0.04
fee_refund = TESTKUDOS:0.02
rsa_keysize = 1024
+CIPHER = RSA
[coin_kudos_4]
value = TESTKUDOS:4
@@ -167,6 +197,7 @@ fee_deposit = TESTKUDOS:0.03
fee_refresh = TESTKUDOS:0.04
fee_refund = TESTKUDOS:0.02
rsa_keysize = 1024
+CIPHER = RSA
[coin_kudos_5]
value = TESTKUDOS:5
@@ -178,6 +209,7 @@ fee_deposit = TESTKUDOS:0.01
fee_refresh = TESTKUDOS:0.03
fee_refund = TESTKUDOS:0.01
rsa_keysize = 1024
+CIPHER = RSA
[coin_kudos_8]
value = TESTKUDOS:8
@@ -189,6 +221,7 @@ fee_deposit = TESTKUDOS:0.02
fee_refresh = TESTKUDOS:0.03
fee_refund = TESTKUDOS:0.04
rsa_keysize = 1024
+CIPHER = RSA
[coin_kudos_10]
value = TESTKUDOS:10
@@ -200,3 +233,4 @@ fee_deposit = TESTKUDOS:0.01
fee_refresh = TESTKUDOS:0.03
fee_refund = TESTKUDOS:0.01
rsa_keysize = 1024
+CIPHER = RSA
diff --git a/src/cli/test_reducer_free.conf b/src/cli/test_reducer_free.conf
new file mode 100644
index 0000000..4e46929
--- /dev/null
+++ b/src/cli/test_reducer_free.conf
@@ -0,0 +1,210 @@
+# This file is in the public domain.
+[PATHS]
+TALER_HOME = ${PWD}/test_reducer_home/
+TALER_DATA_HOME = $TALER_HOME/.local/share/taler/
+TALER_CONFIG_HOME = $TALER_HOME/.config/taler/
+TALER_CACHE_HOME = $TALER_HOME/.cache/taler/
+TALER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/${USER:-}/taler-system-runtime/
+
+[taler]
+CURRENCY = TESTKUDOS
+CURRENCY_ROUND_UNIT = TESTKUDOS:0.01
+
+[anastasis]
+DB = postgres
+ANNUAL_FEE = TESTKUDOS:0
+TRUTH_UPLOAD_FEE = TESTKUDOS:0.0
+UPLOAD_LIMIT_MB = 1
+ANNUAL_POLICY_UPLOAD_LIMIT = 128
+INSURANCE = TESTKUDOS:0
+
+[anastasis-merchant-backend]
+PAYMENT_BACKEND_URL = http://localhost:9966/
+
+[authorization-question]
+COST = TESTKUDOS:0.0
+
+
+[exchange]
+MAX_KEYS_CACHING = forever
+DB = postgres
+MASTER_PRIV_FILE = ${TALER_DATA_HOME}/exchange/offline-keys/master.priv
+SERVE = tcp
+UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http
+UNIXPATH_MODE = 660
+PORT = 8081
+BASE_URL = http://localhost:8081/
+SIGNKEY_DURATION = 2 weeks
+SIGNKEY_LEGAL_DURATION = 2 years
+LEGAL_DURATION = 2 years
+LOOKAHEAD_SIGN = 3 weeks 1 day
+LOOKAHEAD_PROVIDE = 2 weeks 1 day
+KEYDIR = ${TALER_DATA_HOME}/exchange/live-keys/
+REVOCATION_DIR = ${TALER_DATA_HOME}/exchange/revocations/
+TERMS_ETAG = 0
+PRIVACY_ETAG = 0
+
+[merchant]
+SERVE = tcp
+PORT = 9966
+UNIXPATH = ${TALER_RUNTIME_DIR}/merchant.http
+UNIXPATH_MODE = 660
+DEFAULT_WIRE_FEE_AMORTIZATION = 1
+DB = postgres
+WIREFORMAT = default
+# Set very low, so we can be sure that the database generated
+# will contain wire transfers "ready" for the aggregator.
+WIRE_TRANSFER_DELAY = 1 minute
+DEFAULT_PAY_DEADLINE = 1 day
+DEFAULT_MAX_DEPOSIT_FEE = TESTKUDOS:0.1
+KEYFILE = ${TALER_DATA_HOME}/merchant/merchant.priv
+DEFAULT_MAX_WIRE_FEE = TESTKUDOS:0.10
+
+# Ensure that merchant reports EVERY deposit confirmation to auditor
+FORCE_AUDIT = YES
+
+[auditor]
+DB = postgres
+AUDITOR_PRIV_FILE = ${TALER_DATA_HOME}/auditor/offline-keys/auditor.priv
+SERVE = tcp
+UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http
+UNIXPATH_MODE = 660
+PORT = 8083
+AUDITOR_URL = http://localhost:8083/
+TINY_AMOUNT = TESTKUDOS:0.01
+AUDITOR_PRIV_FILE = ${TALER_DATA_HOME}/auditor/offline-keys/auditor.priv
+BASE_URL = "http://localhost:8083/"
+
+[bank]
+DATABASE = postgres:///taler-auditor-basedb
+MAX_DEBT = TESTKUDOS:50.0
+MAX_DEBT_BANK = TESTKUDOS:100000.0
+HTTP_PORT = 8082
+SUGGESTED_EXCHANGE = http://localhost:8081/
+SUGGESTED_EXCHANGE_PAYTO = payto://x-taler-bank/localhost/2
+ALLOW_REGISTRATIONS = YES
+SERVE = http
+
+[exchangedb]
+IDLE_RESERVE_EXPIRATION_TIME = 4 weeks
+LEGAL_RESERVE_EXPIRATION_TIME = 7 years
+
+[exchange-account-1]
+PAYTO_URI = payto://x-taler-bank/localhost/Exchange
+enable_debit = yes
+enable_credit = yes
+
+[exchange-accountcredentials-1]
+WIRE_GATEWAY_URL = "http://localhost:8082/accounts/Exchange/taler-wire-gateway/"
+WIRE_GATEWAY_AUTH_METHOD = basic
+USERNAME = Exchange
+PASSWORD = x
+
+[merchant-exchange-default]
+EXCHANGE_BASE_URL = http://localhost:8081/
+CURRENCY = TESTKUDOS
+
+[payments-generator]
+currency = TESTKUDOS
+instance = default
+bank = http://localhost:8082/
+merchant = http://localhost:9966/
+exchange_admin = http://localhost:18080/
+exchange-admin = http://localhost:18080/
+exchange = http://localhost:8081/
+
+[coin_kudos_ct_1]
+value = TESTKUDOS:0.01
+duration_withdraw = 7 days
+duration_spend = 2 years
+duration_legal = 3 years
+fee_withdraw = TESTKUDOS:0.01
+fee_deposit = TESTKUDOS:0.01
+fee_refresh = TESTKUDOS:0.01
+fee_refund = TESTKUDOS:0.01
+rsa_keysize = 1024
+CIPHER = RSA
+
+[coin_kudos_ct_10]
+value = TESTKUDOS:0.10
+duration_withdraw = 7 days
+duration_spend = 2 years
+duration_legal = 3 years
+fee_withdraw = TESTKUDOS:0.01
+fee_deposit = TESTKUDOS:0.01
+fee_refresh = TESTKUDOS:0.03
+fee_refund = TESTKUDOS:0.01
+rsa_keysize = 1024
+CIPHER = RSA
+
+[coin_kudos_1]
+value = TESTKUDOS:1
+duration_withdraw = 7 days
+duration_spend = 2 years
+duration_legal = 3 years
+fee_withdraw = TESTKUDOS:0.02
+fee_deposit = TESTKUDOS:0.02
+fee_refresh = TESTKUDOS:0.03
+fee_refund = TESTKUDOS:0.01
+rsa_keysize = 1024
+CIPHER = RSA
+
+[coin_kudos_2]
+value = TESTKUDOS:2
+duration_withdraw = 7 days
+duration_spend = 2 years
+duration_legal = 3 years
+fee_withdraw = TESTKUDOS:0.03
+fee_deposit = TESTKUDOS:0.03
+fee_refresh = TESTKUDOS:0.04
+fee_refund = TESTKUDOS:0.02
+rsa_keysize = 1024
+CIPHER = RSA
+
+[coin_kudos_4]
+value = TESTKUDOS:4
+duration_withdraw = 7 days
+duration_spend = 2 years
+duration_legal = 3 years
+fee_withdraw = TESTKUDOS:0.03
+fee_deposit = TESTKUDOS:0.03
+fee_refresh = TESTKUDOS:0.04
+fee_refund = TESTKUDOS:0.02
+rsa_keysize = 1024
+CIPHER = RSA
+
+[coin_kudos_5]
+value = TESTKUDOS:5
+duration_withdraw = 7 days
+duration_spend = 2 years
+duration_legal = 3 years
+fee_withdraw = TESTKUDOS:0.01
+fee_deposit = TESTKUDOS:0.01
+fee_refresh = TESTKUDOS:0.03
+fee_refund = TESTKUDOS:0.01
+rsa_keysize = 1024
+CIPHER = RSA
+
+[coin_kudos_8]
+value = TESTKUDOS:8
+duration_withdraw = 7 days
+duration_spend = 2 years
+duration_legal = 3 years
+fee_withdraw = TESTKUDOS:0.05
+fee_deposit = TESTKUDOS:0.02
+fee_refresh = TESTKUDOS:0.03
+fee_refund = TESTKUDOS:0.04
+rsa_keysize = 1024
+CIPHER = RSA
+
+[coin_kudos_10]
+value = TESTKUDOS:10
+duration_withdraw = 7 days
+duration_spend = 2 years
+duration_legal = 3 years
+fee_withdraw = TESTKUDOS:0.01
+fee_deposit = TESTKUDOS:0.01
+fee_refresh = TESTKUDOS:0.03
+fee_refund = TESTKUDOS:0.01
+rsa_keysize = 1024
+CIPHER = RSA
diff --git a/src/cli/test_reducer_home/.local/share/taler/exchange-offline/master.priv b/src/cli/test_reducer_home/.local/share/taler/exchange-offline/master.priv
new file mode 100644
index 0000000..d990a05
--- /dev/null
+++ b/src/cli/test_reducer_home/.local/share/taler/exchange-offline/master.priv
@@ -0,0 +1 @@
+>en͙[z3pwTj?cn21 \ No newline at end of file