diff --git a/contrib/gana b/contrib/gana
index 14cb23ef0..3a616a04f 160000
--- a/contrib/gana
+++ b/contrib/gana
@@ -1 +1 @@
-Subproject commit 14cb23ef0e31d3470a0671fe165a1557eddc0590
+Subproject commit 3a616a04f1cd946bf0641b54cd71f1b858174f74
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
index 7d83e70c5..62bd9a9dc 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -488,13 +488,55 @@ handle_get_aml (struct TEH_RequestContext *rc,
TALER_EC_EXCHANGE_GENERIC_WRONG_NUMBER_OF_SEGMENTS,
"AML GET operations must specify an operation identifier");
}
- if (1) // FIXME: check AML officer GET signature!
{
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (rc->connection,
- MHD_HTTP_FORBIDDEN,
- TALER_EC_EXCHANGE_GENERIC_AML_OFFICER_GET_SIGNATURE_INVALID,
- NULL);
+ const char *sig_hdr;
+ struct TALER_AmlOfficerSignatureP officer_sig;
+
+ sig_hdr = MHD_lookup_connection_value (rc->connection,
+ MHD_HEADER_KIND,
+ TALER_AML_OFFICER_SIGNATURE_HEADER);
+ if ( (NULL == sig_hdr) ||
+ (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (sig_hdr,
+ strlen (sig_hdr),
+ &officer_sig,
+ sizeof (officer_sig))) ||
+ (GNUNET_OK !=
+ TALER_officer_aml_query_verify (&officer_pub,
+ &officer_sig)) )
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_EXCHANGE_GENERIC_AML_OFFICER_GET_SIGNATURE_INVALID,
+ sig_hdr);
+ }
+ TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
+ }
+
+ {
+ enum GNUNET_DB_QueryStatus qs;
+
+ qs = TEH_plugin->test_aml_officer (TEH_plugin->cls,
+ &officer_pub);
+ switch (qs)
+ {
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ case GNUNET_DB_STATUS_SOFT_ERROR:
+ GNUNET_break (0);
+ return TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ NULL);
+ case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_EXCHANGE_GENERIC_AML_OFFICER_ACCESS_DENIED,
+ NULL);
+ case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+ break;
+ }
}
for (unsigned int i = 0; NULL != h[i].op; i++)
if (0 == strcmp (h[i].op,
diff --git a/src/exchange/taler-exchange-httpd_aml-decision-get.c b/src/exchange/taler-exchange-httpd_aml-decision-get.c
index 09f9c8e86..e0252c614 100644
--- a/src/exchange/taler-exchange-httpd_aml-decision-get.c
+++ b/src/exchange/taler-exchange-httpd_aml-decision-get.c
@@ -101,7 +101,7 @@ static void
aml_history_cb (
void *cls,
const struct TALER_Amount *new_threshold,
- enum TALER_AmlDecisionState new_status,
+ enum TALER_AmlDecisionState new_state,
struct GNUNET_TIME_Timestamp decision_time,
const char *justification,
const struct TALER_AmlOfficerPublicKeyP *decider_pub,
@@ -120,8 +120,8 @@ aml_history_cb (
justification),
TALER_JSON_pack_amount ("new_threshold",
new_threshold),
- GNUNET_JSON_pack_int64 ("new_status",
- new_status),
+ GNUNET_JSON_pack_int64 ("new_state",
+ new_state),
GNUNET_JSON_pack_timestamp ("decision_time",
decision_time)
)));
@@ -134,7 +134,6 @@ TEH_handler_aml_decision_get (
const struct TALER_AmlOfficerPublicKeyP *officer_pub,
const char *const args[])
{
- struct TALER_AmlOfficerSignatureP officer_sig;
struct TALER_PaytoHashP h_payto;
if ( (NULL == args[0]) ||
@@ -159,30 +158,6 @@ TEH_handler_aml_decision_get (
TALER_EC_GENERIC_ENDPOINT_UNKNOWN,
args[1]);
}
- {
- const char *sig_hdr;
-
- sig_hdr = MHD_lookup_connection_value (rc->connection,
- MHD_HEADER_KIND,
- TALER_AML_OFFICER_SIGNATURE_HEADER);
- if ( (NULL == sig_hdr) ||
- (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (sig_hdr,
- strlen (sig_hdr),
- &officer_sig,
- sizeof (officer_sig))) ||
- (GNUNET_OK !=
- TALER_officer_aml_query_verify (officer_pub,
- &officer_sig)) )
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (rc->connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_EXCHANGE_GENERIC_AML_OFFICER_GET_SIGNATURE_INVALID,
- sig_hdr);
- }
- TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
- }
{
json_t *aml_history;
diff --git a/src/exchange/taler-exchange-httpd_aml-decision.c b/src/exchange/taler-exchange-httpd_aml-decision.c
index ae2667c1d..16dc0d965 100644
--- a/src/exchange/taler-exchange-httpd_aml-decision.c
+++ b/src/exchange/taler-exchange-httpd_aml-decision.c
@@ -76,7 +76,10 @@ TEH_handler_post_aml_decision (
if (GNUNET_SYSERR == res)
return MHD_NO; /* hard failure */
if (GNUNET_NO == res)
+ {
+ GNUNET_break_op (0);
return MHD_YES; /* failure */
+ }
}
new_state = (enum TALER_AmlDecisionState) new_state32;
TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
diff --git a/src/exchange/taler-exchange-httpd_aml-decisions-get.c b/src/exchange/taler-exchange-httpd_aml-decisions-get.c
index 7c4a137d9..ad160b821 100644
--- a/src/exchange/taler-exchange-httpd_aml-decisions-get.c
+++ b/src/exchange/taler-exchange-httpd_aml-decisions-get.c
@@ -79,7 +79,6 @@ TEH_handler_aml_decisions_get (
const struct TALER_AmlOfficerPublicKeyP *officer_pub,
const char *const args[])
{
- struct TALER_AmlOfficerSignatureP officer_sig;
enum TALER_AmlDecisionState decision;
int delta = -20;
unsigned long long start = INT64_MAX;
@@ -118,30 +117,6 @@ TEH_handler_aml_decisions_get (
TALER_EC_GENERIC_ENDPOINT_UNKNOWN,
args[1]);
}
- {
- const char *sig_hdr;
-
- sig_hdr = MHD_lookup_connection_value (rc->connection,
- MHD_HEADER_KIND,
- TALER_AML_OFFICER_SIGNATURE_HEADER);
- if ( (NULL == sig_hdr) ||
- (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (sig_hdr,
- strlen (sig_hdr),
- &officer_sig,
- sizeof (officer_sig))) ||
- (GNUNET_OK !=
- TALER_officer_aml_query_verify (officer_pub,
- &officer_sig)) )
- {
- GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (rc->connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_EXCHANGE_GENERIC_AML_OFFICER_GET_SIGNATURE_INVALID,
- sig_hdr);
- }
- TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
- }
{
const char *p;
diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am
index 8ea9a4123..e8ef104e1 100644
--- a/src/exchangedb/Makefile.am
+++ b/src/exchangedb/Makefile.am
@@ -136,7 +136,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \
pg_select_similar_kyc_attributes.h pg_select_similar_kyc_attributes.c \
pg_select_kyc_attributes.h pg_select_kyc_attributes.c \
pg_insert_aml_officer.h pg_insert_aml_officer.c \
- pg_update_aml_officer.h pg_update_aml_officer.c \
+ pg_test_aml_officer.h pg_test_aml_officer.c \
pg_lookup_aml_officer.h pg_lookup_aml_officer.c \
pg_trigger_aml_process.h pg_trigger_aml_process.c \
pg_select_aml_process.h pg_select_aml_process.c \
diff --git a/src/exchangedb/exchange_do_insert_aml_decision.sql b/src/exchangedb/exchange_do_insert_aml_decision.sql
index b3f77c8c4..ef3e60048 100644
--- a/src/exchangedb/exchange_do_insert_aml_decision.sql
+++ b/src/exchangedb/exchange_do_insert_aml_decision.sql
@@ -56,8 +56,8 @@ THEN
RETURN;
END IF;
UPDATE exchange.aml_status
- SET threshold_val=in_threshold_val
- ,threshold_frac=in_threshold_frac
+ SET threshold_val=in_new_threshold_val
+ ,threshold_frac=in_new_threshold_frac
,status=in_new_status
WHERE h_payto=in_h_payto;
ASSERT FOUND, 'cannot have AML decision history but no AML status';
@@ -70,8 +70,8 @@ ELSE
,status)
VALUES
(in_h_payto
- ,in_threshold_val
- ,in_threshold_frac
+ ,in_new_threshold_val
+ ,in_new_threshold_frac
,in_new_status);
END IF;
diff --git a/src/exchangedb/pg_select_aml_history.c b/src/exchangedb/pg_select_aml_history.c
index ac7fe5842..c54a3ef0c 100644
--- a/src/exchangedb/pg_select_aml_history.c
+++ b/src/exchangedb/pg_select_aml_history.c
@@ -138,18 +138,13 @@ TEH_PG_select_aml_history (
PREPARE (pg,
"lookup_aml_history",
"SELECT"
- " aggregation_serial_id"
- ",deposits.h_contract_terms"
- ",payto_uri"
- ",wire_targets.wire_target_h_payto"
- ",kc.coin_pub"
- ",deposits.merchant_pub"
- ",wire_out.execution_date"
- ",deposits.amount_with_fee_val"
- ",deposits.amount_with_fee_frac"
- ",denom.fee_deposit_val"
- ",denom.fee_deposit_frac"
- ",denom.denom_pub"
+ " new_threshold_val"
+ ",new_threshold_frac"
+ ",new_status"
+ ",decision_time"
+ ",justification"
+ ",decider_pub"
+ ",decider_sig"
" FROM aml_history"
" WHERE h_payto=$1;");
qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
diff --git a/src/exchangedb/pg_update_aml_officer.c b/src/exchangedb/pg_test_aml_officer.c
similarity index 55%
rename from src/exchangedb/pg_update_aml_officer.c
rename to src/exchangedb/pg_test_aml_officer.c
index 2f5b0ff90..b00828244 100644
--- a/src/exchangedb/pg_update_aml_officer.c
+++ b/src/exchangedb/pg_test_aml_officer.c
@@ -14,49 +14,35 @@
TALER; see the file COPYING. If not, see
*/
/**
- * @file exchangedb/pg_update_aml_officer.c
- * @brief Implementation of the update_aml_officer function for Postgres
+ * @file exchangedb/pg_test_aml_officer.c
+ * @brief Implementation of the test_aml_officer function for Postgres
* @author Christian Grothoff
*/
#include "platform.h"
#include "taler_error_codes.h"
#include "taler_dbevents.h"
#include "taler_pq_lib.h"
-#include "pg_update_aml_officer.h"
+#include "pg_test_aml_officer.h"
#include "pg_helper.h"
enum GNUNET_DB_QueryStatus
-TEH_PG_update_aml_officer (
+TEH_PG_test_aml_officer (
void *cls,
- const struct TALER_AmlOfficerPublicKeyP *decider_pub,
- const struct TALER_MasterSignatureP *master_sig,
- const char *decider_name,
- bool is_active,
- bool read_only,
- struct GNUNET_TIME_Absolute last_change)
+ const struct TALER_AmlOfficerPublicKeyP *decider_pub)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (decider_pub),
- GNUNET_PQ_query_param_auto_from_type (master_sig),
- GNUNET_PQ_query_param_string (decider_name),
- GNUNET_PQ_query_param_bool (is_active),
- GNUNET_PQ_query_param_bool (read_only),
- GNUNET_PQ_query_param_absolute_time (&last_change),
GNUNET_PQ_query_param_end
};
PREPARE (pg,
- "update_aml_staff",
- "UPDATE aml_staff SET "
- " master_sig=$2"
- ",decider_name=$3"
- ",is_active=$4"
- ",read_only=$5"
- ",last_change=$6"
- " WHERE decider_pub=$1 AND last_change < $6;");
+ "test_aml_staff",
+ "SELECT 1 FROM aml_staff"
+ " WHERE decider_pub=$1"
+ " AND is_active;");
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "update_aml_staff",
+ "test_aml_staff",
params);
}
diff --git a/src/exchangedb/pg_update_aml_officer.h b/src/exchangedb/pg_test_aml_officer.h
similarity index 65%
rename from src/exchangedb/pg_update_aml_officer.h
rename to src/exchangedb/pg_test_aml_officer.h
index 8e3592395..9cecd6f03 100644
--- a/src/exchangedb/pg_update_aml_officer.h
+++ b/src/exchangedb/pg_test_aml_officer.h
@@ -27,25 +27,17 @@
/**
- * Update AML staff record.
+ * Test if the given AML staff member is active
+ * (at least read-only).
*
* @param cls closure
* @param decider_pub public key of the staff member
- * @param master_sig offline signature affirming the AML officer
- * @param decider_name full name of the staff member
- * @param is_active true to enable, false to set as inactive
- * @param read_only true to set read-only access
- * @param last_change when was the change made effective
- * @return database transaction status
+ * @return database transaction status, if member is unknown or not active, 1 if member is active
*/
enum GNUNET_DB_QueryStatus
-TEH_PG_update_aml_officer (
+TEH_PG_test_aml_officer (
void *cls,
- const struct TALER_AmlOfficerPublicKeyP *decider_pub,
- const struct TALER_MasterSignatureP *master_sig,
- const char *decider_name,
- bool is_active,
- bool read_only,
- struct GNUNET_TIME_Absolute last_change);
+ const struct TALER_AmlOfficerPublicKeyP *decider_pub);
+
#endif
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index cd5773a05..a6e932211 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -210,7 +210,7 @@
#include "pg_select_similar_kyc_attributes.h"
#include "pg_select_kyc_attributes.h"
#include "pg_insert_aml_officer.h"
-#include "pg_update_aml_officer.h"
+#include "pg_test_aml_officer.h"
#include "pg_lookup_aml_officer.h"
#include "pg_trigger_aml_process.h"
#include "pg_select_aml_process.h"
@@ -761,8 +761,8 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
= &TEH_PG_select_kyc_attributes;
plugin->insert_aml_officer
= &TEH_PG_insert_aml_officer;
- plugin->update_aml_officer
- = &TEH_PG_update_aml_officer;
+ plugin->test_aml_officer
+ = &TEH_PG_test_aml_officer;
plugin->lookup_aml_officer
= &TEH_PG_lookup_aml_officer;
plugin->trigger_aml_process
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 4eb0a8410..3e40c985e 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -6616,26 +6616,17 @@ struct TALER_EXCHANGEDB_Plugin
/**
- * Update AML staff record.
+ * Test if the given AML staff member is active
+ * (at least read-only).
*
* @param cls closure
* @param decider_pub public key of the staff member
- * @param master_sig offline signature affirming the AML officer
- * @param decider_name full name of the staff member
- * @param is_active true to enable, false to set as inactive
- * @param read_only true to set read-only access
- * @param last_change when was the change made effective
- * @return database transaction status
+ * @return database transaction status, if member is unknown or not active, 1 if member is active
*/
enum GNUNET_DB_QueryStatus
- (*update_aml_officer)(
+ (*test_aml_officer)(
void *cls,
- const struct TALER_AmlOfficerPublicKeyP *decider_pub,
- const struct TALER_MasterSignatureP *master_sig,
- const char *decider_name,
- bool is_active,
- bool read_only,
- struct GNUNET_TIME_Absolute last_change);
+ const struct TALER_AmlOfficerPublicKeyP *decider_pub);
/**
diff --git a/src/lib/exchange_api_add_aml_decision.c b/src/lib/exchange_api_add_aml_decision.c
index 0a1b70cdf..5e5383f25 100644
--- a/src/lib/exchange_api_add_aml_decision.c
+++ b/src/lib/exchange_api_add_aml_decision.c
@@ -188,7 +188,7 @@ TALER_EXCHANGE_add_aml_decision (
&officer_sig),
GNUNET_JSON_pack_data_auto ("h_payto",
h_payto),
- GNUNET_JSON_pack_uint64 ("state",
+ GNUNET_JSON_pack_uint64 ("new_state",
(uint32_t) new_state),
TALER_JSON_pack_amount ("new_threshold",
new_threshold),
diff --git a/src/lib/exchange_api_lookup_aml_decision.c b/src/lib/exchange_api_lookup_aml_decision.c
index 409a35c08..897a21f10 100644
--- a/src/lib/exchange_api_lookup_aml_decision.c
+++ b/src/lib/exchange_api_lookup_aml_decision.c
@@ -262,6 +262,12 @@ handle_lookup_finished (void *cls,
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
break;
+ case MHD_HTTP_FORBIDDEN:
+ lr.hr.ec = TALER_JSON_get_error_code (j);
+ lr.hr.hint = TALER_JSON_get_error_hint (j);
+ /* Nothing really to verify, exchange says this coin was not melted; we
+ should pass the JSON reply to the application */
+ break;
case MHD_HTTP_NOT_FOUND:
lr.hr.ec = TALER_JSON_get_error_code (j);
lr.hr.hint = TALER_JSON_get_error_hint (j);
@@ -280,7 +286,7 @@ handle_lookup_finished (void *cls,
lr.hr.ec = TALER_JSON_get_error_code (j);
lr.hr.hint = TALER_JSON_get_error_hint (j);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange link\n",
+ "Unexpected response code %u/%d for exchange lookup AML decision\n",
(unsigned int) response_code,
(int) lr.hr.ec);
break;
@@ -332,7 +338,7 @@ TALER_EXCHANGE_lookup_aml_decision (
*end = '\0';
GNUNET_snprintf (arg_str,
sizeof (arg_str),
- "/aml/%s/decision/%s",
+ "aml/%s/decision/%s",
pub_str,
pt_str);
}
diff --git a/src/lib/exchange_api_lookup_aml_decisions.c b/src/lib/exchange_api_lookup_aml_decisions.c
index da17aa784..3b1db4556 100644
--- a/src/lib/exchange_api_lookup_aml_decisions.c
+++ b/src/lib/exchange_api_lookup_aml_decisions.c
@@ -202,6 +202,12 @@ handle_lookup_finished (void *cls,
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
break;
+ case MHD_HTTP_FORBIDDEN:
+ lr.hr.ec = TALER_JSON_get_error_code (j);
+ lr.hr.hint = TALER_JSON_get_error_hint (j);
+ /* Nothing really to verify, exchange says this coin was not melted; we
+ should pass the JSON reply to the application */
+ break;
case MHD_HTTP_NOT_FOUND:
lr.hr.ec = TALER_JSON_get_error_code (j);
lr.hr.hint = TALER_JSON_get_error_hint (j);
@@ -220,7 +226,7 @@ handle_lookup_finished (void *cls,
lr.hr.ec = TALER_JSON_get_error_code (j);
lr.hr.hint = TALER_JSON_get_error_hint (j);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange link\n",
+ "Unexpected response code %u/%d for lookup AML decisions\n",
(unsigned int) response_code,
(int) lr.hr.ec);
break;
@@ -279,7 +285,7 @@ TALER_EXCHANGE_lookup_aml_decisions (
*end = '\0';
GNUNET_snprintf (arg_str,
sizeof (arg_str),
- "/aml/%s/decisions/%s",
+ "aml/%s/decisions/%s",
pub_str,
state_str);
}
diff --git a/src/testing/test_kyc_api.c b/src/testing/test_kyc_api.c
index 44f302c6d..517138530 100644
--- a/src/testing/test_kyc_api.c
+++ b/src/testing/test_kyc_api.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2022 Taler Systems SA
+ Copyright (C) 2014-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as
@@ -410,7 +410,72 @@ run (void *cls,
MHD_HTTP_OK),
TALER_TESTING_cmd_end ()
};
-
+ struct TALER_TESTING_Command aml[] = {
+ /* Trigger something upon which an AML officer could act */
+ TALER_TESTING_cmd_wallet_kyc_get ("wallet-trigger-kyc-for-aml",
+ NULL,
+ "EUR:1000",
+ MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS),
+ TALER_TESTING_cmd_set_officer ("create-aml-officer-1",
+ NULL,
+ "Peter Falk",
+ true,
+ false),
+ TALER_TESTING_cmd_sleep ("sleep-1a",
+ 1),
+ TALER_TESTING_cmd_set_officer ("create-aml-officer-1-disable",
+ "create-aml-officer-1",
+ "Peter Falk",
+ true,
+ true),
+ /* Test that we are not allowed to take AML decisions as our
+ AML staff account is on read-only */
+ TALER_TESTING_cmd_take_aml_decision ("aml-decide-while-disabled",
+ "create-aml-officer-1",
+ "wallet-trigger-kyc-for-aml",
+ "EUR:10000",
+ "party time",
+ TALER_AML_NORMAL,
+ MHD_HTTP_FORBIDDEN),
+ /* Check that no decision was taken, but that we are allowed
+ to read this information */
+ TALER_TESTING_cmd_check_aml_decision ("check-aml-decision-empty",
+ "create-aml-officer-1",
+ "aml-decide-while-disabled",
+ MHD_HTTP_NO_CONTENT),
+ TALER_TESTING_cmd_sleep ("sleep-1b",
+ 1),
+ TALER_TESTING_cmd_set_officer ("create-aml-officer-1-enable",
+ "create-aml-officer-1",
+ "Peter Falk",
+ true,
+ false),
+ TALER_TESTING_cmd_take_aml_decision ("aml-decide",
+ "create-aml-officer-1",
+ "wallet-trigger-kyc-for-aml",
+ "EUR:10000",
+ "party time",
+ TALER_AML_NORMAL,
+ MHD_HTTP_NO_CONTENT),
+ TALER_TESTING_cmd_check_aml_decision ("check-aml-decision",
+ "create-aml-officer-1",
+ "aml-decide",
+ MHD_HTTP_OK),
+ TALER_TESTING_cmd_sleep ("sleep-1c",
+ 1),
+ TALER_TESTING_cmd_set_officer ("create-aml-officer-1-disable",
+ "create-aml-officer-1",
+ "Peter Falk",
+ false,
+ true),
+ /* Test that we are NOT allowed to read AML decisions now that
+ our AML staff account is disabled */
+ TALER_TESTING_cmd_check_aml_decision ("check-aml-decision-disabled",
+ "create-aml-officer-1",
+ "aml-decide",
+ MHD_HTTP_FORBIDDEN),
+ TALER_TESTING_cmd_end ()
+ };
struct TALER_TESTING_Command commands[] = {
TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees",
@@ -452,6 +517,8 @@ run (void *cls,
push),
TALER_TESTING_cmd_batch ("pull",
pull),
+ TALER_TESTING_cmd_batch ("aml",
+ aml),
TALER_TESTING_cmd_end ()
};
diff --git a/src/testing/testing_api_cmd_check_aml_decision.c b/src/testing/testing_api_cmd_check_aml_decision.c
index 89939a41e..d77e9b6b9 100644
--- a/src/testing/testing_api_cmd_check_aml_decision.c
+++ b/src/testing/testing_api_cmd_check_aml_decision.c
@@ -107,7 +107,6 @@ check_aml_decision_cb (void *cls,
TALER_TESTING_interpreter_fail (ds->is);
return;
}
- // FIXME: check returned details...
GNUNET_assert (GNUNET_OK ==
TALER_TESTING_get_trait_aml_justification (ref,
&justification));
@@ -117,7 +116,7 @@ check_aml_decision_cb (void *cls,
GNUNET_assert (GNUNET_OK ==
TALER_TESTING_get_trait_amount (ref,
&amount));
- for (unsigned int i = 1; idetails.success.aml_history_length; i++)
+ for (unsigned int i = 0; idetails.success.aml_history_length; i++)
{
const struct TALER_EXCHANGE_AmlDecisionDetail *aml_history
= &adr->details.success.aml_history[i];