commit a666b706247f7e2b152a396999f0c9e787190b30
parent c39040ad2c4939b21d6ad57240a8a47dbc8f68e3
Author: Christian Grothoff <christian@grothoff.org>
Date: Thu, 5 Sep 2024 13:30:04 +0200
exchange-side implementation of #9156
Diffstat:
12 files changed, 99 insertions(+), 10 deletions(-)
diff --git a/src/exchange/taler-exchange-httpd_aml-decision.c b/src/exchange/taler-exchange-httpd_aml-decision.c
@@ -45,6 +45,7 @@ TEH_handler_post_aml_decision (
struct GNUNET_TIME_Timestamp decision_time;
const json_t *new_rules;
const json_t *properties = NULL;
+ const char *payto_uri = NULL;
struct TALER_PaytoHashP h_payto;
struct TALER_AmlOfficerSignatureP officer_sig;
struct GNUNET_JSON_Specification spec[] = {
@@ -55,6 +56,10 @@ TEH_handler_post_aml_decision (
NULL),
GNUNET_JSON_spec_string ("justification",
&justification),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_string ("payto_uri",
+ &payto_uri),
+ NULL),
GNUNET_JSON_spec_fixed_auto ("h_payto",
&h_payto),
GNUNET_JSON_spec_object_const ("new_rules",
@@ -88,6 +93,25 @@ TEH_handler_post_aml_decision (
return MHD_YES; /* failure */
}
}
+ if (NULL != payto_uri)
+ {
+ struct TALER_PaytoHashP h_payto2;
+
+ TALER_payto_hash (payto_uri,
+ &h_payto2);
+ if (0 !=
+ GNUNET_memcmp (&h_payto,
+ &h_payto2))
+ {
+ GNUNET_break (0);
+ return TALER_MHD_reply_with_error (
+ connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "payto_uri");
+ }
+ }
+
TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
if (GNUNET_OK !=
TALER_officer_aml_decision_verify (
@@ -152,6 +176,7 @@ TEH_handler_post_aml_decision (
/* We keep 'new_measures' around mostly so that
the auditor can later verify officer_sig */
qs = TEH_plugin->insert_aml_decision (TEH_plugin->cls,
+ payto_uri,
&h_payto,
decision_time,
expiration_time,
diff --git a/src/exchangedb/exchange_do_insert_aml_decision.sql b/src/exchangedb/exchange_do_insert_aml_decision.sql
@@ -16,14 +16,15 @@
DROP FUNCTION IF EXISTS exchange_do_insert_aml_decision;
CREATE FUNCTION exchange_do_insert_aml_decision(
+ IN in_payto_uri TEXT, -- can be NULL!
IN in_h_payto BYTEA,
IN in_decision_time INT8,
IN in_expiration_time INT8,
- IN in_properties TEXT,
+ IN in_properties TEXT, -- can be NULL
IN in_new_rules TEXT,
IN in_to_investigate BOOLEAN,
- IN in_new_measure_name TEXT,
- IN in_jmeasures TEXT,
+ IN in_new_measure_name TEXT, -- can be NULL
+ IN in_jmeasures TEXT, -- can be NULL
IN in_justification TEXT,
IN in_decider_pub BYTEA,
IN in_decider_sig BYTEA,
@@ -78,17 +79,29 @@ ELSE
out_last_date = 0;
END IF;
--- FIXME-9156: need in_payto_uri *in* case
--- in_h_payto is not already in wire_targets!
SELECT access_token
INTO my_access_token
FROM wire_targets
WHERE wire_target_h_payto=in_h_payto;
--- Very strange, should never happen that we
--- take an AML decision on an unknown account!
IF NOT FOUND
THEN
+ IF in_payto_uri IS NULL
+ THEN
+ -- AML decision on an unknown account without payto_uri => fail.
+ out_account_unknown=TRUE;
+ RETURN;
+ END IF;
+
+ INSERT INTO wire_targets
+ (wire_target_h_payto
+ ,payto_uri)
+ VALUES
+ (in_h_payto
+ ,in_payto_uri)
+ RETURNING access_token
+ INTO my_access_token;
+
out_account_unknown=TRUE;
RETURN;
END IF;
@@ -189,5 +202,5 @@ EXECUTE FORMAT (
END $$;
-COMMENT ON FUNCTION exchange_do_insert_aml_decision(BYTEA, INT8, INT8, TEXT, TEXT, BOOLEAN, TEXT, TEXT, TEXT, BYTEA, BYTEA, TEXT)
+COMMENT ON FUNCTION exchange_do_insert_aml_decision(TEXT, BYTEA, INT8, INT8, TEXT, TEXT, BOOLEAN, TEXT, TEXT, TEXT, BYTEA, BYTEA, TEXT)
IS 'Checks whether the AML officer is eligible to make AML decisions and if so inserts the decision into the table';
diff --git a/src/exchangedb/pg_insert_aml_decision.c b/src/exchangedb/pg_insert_aml_decision.c
@@ -30,6 +30,7 @@
enum GNUNET_DB_QueryStatus
TEH_PG_insert_aml_decision (
void *cls,
+ const char *payto_uri,
const struct TALER_PaytoHashP *h_payto,
struct GNUNET_TIME_Timestamp decision_time,
struct GNUNET_TIME_Timestamp expiration_time,
@@ -54,6 +55,9 @@ TEH_PG_insert_aml_decision (
char *notify_s
= GNUNET_PQ_get_event_notify_channel (&rep.header);
struct GNUNET_PQ_QueryParam params[] = {
+ NULL == payto_uri
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_string (payto_uri),
GNUNET_PQ_query_param_auto_from_type (h_payto),
GNUNET_PQ_query_param_timestamp (&decision_time),
GNUNET_PQ_query_param_timestamp (&expiration_time),
@@ -92,7 +96,7 @@ TEH_PG_insert_aml_decision (
",out_account_unknown"
",out_last_date"
" FROM exchange_do_insert_aml_decision"
- "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);");
+ "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);");
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"do_insert_aml_decision",
params,
diff --git a/src/exchangedb/pg_insert_aml_decision.h b/src/exchangedb/pg_insert_aml_decision.h
@@ -31,6 +31,8 @@
* status.
*
* @param cls closure
+ * @param payto_uri full URI of the account, optional,
+ * can be NULL if the backend already knows the account
* @param h_payto account for which the attribute data is stored
* @param decision_time when was the decision made
* @param expiration_time when does the decision expire
@@ -52,6 +54,7 @@
enum GNUNET_DB_QueryStatus
TEH_PG_insert_aml_decision (
void *cls,
+ const char *payto_uri,
const struct TALER_PaytoHashP *h_payto,
struct GNUNET_TIME_Timestamp decision_time,
struct GNUNET_TIME_Timestamp expiration_time,
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
@@ -6393,6 +6393,8 @@ struct TALER_EXCHANGE_AccountRule
* @param url HTTP base URL for the exchange
* @param h_payto payto URI hash of the account the
* decision is about
+ * @param payto_uri payto URI of the account, can
+ * be NULL if the exchange already knows the account
* @param decision_time when was the decision made
* @param successor_measure measure to activate after @a expiration_time if no rule applied
* @param new_measures space-separated list of measures
@@ -6417,6 +6419,7 @@ TALER_EXCHANGE_post_aml_decision (
struct GNUNET_CURL_Context *ctx,
const char *url,
const struct TALER_PaytoHashP *h_payto,
+ const char *payto_uri,
struct GNUNET_TIME_Timestamp decision_time,
const char *successor_measure,
const char *new_measures,
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
@@ -7653,6 +7653,8 @@ struct TALER_EXCHANGEDB_Plugin
* status.
*
* @param cls closure
+ * @param payto_uri full URI of the account, optional,
+ * can be NULL if the backend already knows the account
* @param h_payto account for which the attribute data is stored
* @param decision_time when was the decision made
* @param expiration_time when does the decision expire
@@ -7674,6 +7676,7 @@ struct TALER_EXCHANGEDB_Plugin
enum GNUNET_DB_QueryStatus
(*insert_aml_decision)(
void *cls,
+ const char *payto_uri,
const struct TALER_PaytoHashP *h_payto,
struct GNUNET_TIME_Timestamp decision_time,
struct GNUNET_TIME_Timestamp expiration_time,
diff --git a/src/kyclogic/plugin_kyclogic_kycaid.c b/src/kyclogic/plugin_kyclogic_kycaid.c
@@ -1393,6 +1393,10 @@ kycaid_webhook (void *cls,
* @return NULL on error, otherwise a `struct TALER_KYCLOGIC_Plugin`
*/
void *
+libtaler_plugin_kyclogic_kycaid_init (void *cls);
+
+/* declaration to avoid compiler warning */
+void *
libtaler_plugin_kyclogic_kycaid_init (void *cls)
{
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
@@ -1455,6 +1459,10 @@ libtaler_plugin_kyclogic_kycaid_init (void *cls)
* @return NULL (always)
*/
void *
+libtaler_plugin_kyclogic_kycaid_done (void *cls);
+
+/* declaration to avoid compiler warning */
+void *
libtaler_plugin_kyclogic_kycaid_done (void *cls)
{
struct TALER_KYCLOGIC_Plugin *plugin = cls;
diff --git a/src/kyclogic/plugin_kyclogic_oauth2.c b/src/kyclogic/plugin_kyclogic_oauth2.c
@@ -1696,6 +1696,10 @@ oauth2_webhook_cancel (struct TALER_KYCLOGIC_WebhookHandle *wh)
* @return NULL on error, otherwise a `struct TALER_KYCLOGIC_Plugin`
*/
void *
+libtaler_plugin_kyclogic_oauth2_init (void *cls);
+
+/* declaration to avoid compiler warning */
+void *
libtaler_plugin_kyclogic_oauth2_init (void *cls)
{
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
@@ -1757,6 +1761,10 @@ libtaler_plugin_kyclogic_oauth2_init (void *cls)
* @return NULL (always)
*/
void *
+libtaler_plugin_kyclogic_oauth2_done (void *cls);
+
+/* declaration to avoid compiler warning */
+void *
libtaler_plugin_kyclogic_oauth2_done (void *cls)
{
struct TALER_KYCLOGIC_Plugin *plugin = cls;
diff --git a/src/kyclogic/plugin_kyclogic_persona.c b/src/kyclogic/plugin_kyclogic_persona.c
@@ -2169,6 +2169,10 @@ persona_webhook (void *cls,
* @return NULL on error, otherwise a `struct TALER_KYCLOGIC_Plugin`
*/
void *
+libtaler_plugin_kyclogic_persona_init (void *cls);
+
+/* declaration to avoid compiler warning */
+void *
libtaler_plugin_kyclogic_persona_init (void *cls)
{
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
@@ -2240,6 +2244,11 @@ libtaler_plugin_kyclogic_persona_init (void *cls)
* @return NULL (always)
*/
void *
+libtaler_plugin_kyclogic_persona_done (void *cls);
+
+/* declaration to avoid compiler warning */
+
+void *
libtaler_plugin_kyclogic_persona_done (void *cls)
{
struct TALER_KYCLOGIC_Plugin *plugin = cls;
diff --git a/src/kyclogic/plugin_kyclogic_template.c b/src/kyclogic/plugin_kyclogic_template.c
@@ -384,6 +384,10 @@ template_webhook (void *cls,
* @return NULL on error, otherwise a `struct TALER_KYCLOGIC_Plugin`
*/
void *
+libtaler_plugin_kyclogic_template_init (void *cls);
+
+/* declaration to avoid compiler warning */
+void *
libtaler_plugin_kyclogic_template_init (void *cls)
{
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
@@ -446,6 +450,10 @@ libtaler_plugin_kyclogic_template_init (void *cls)
* @return NULL (always)
*/
void *
+libtaler_plugin_kyclogic_template_done (void *cls);
+
+/* declaration to avoid compiler warning */
+void *
libtaler_plugin_kyclogic_template_done (void *cls)
{
struct TALER_KYCLOGIC_Plugin *plugin = cls;
diff --git a/src/lib/exchange_api_add_aml_decision.c b/src/lib/exchange_api_add_aml_decision.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2023 Taler Systems SA
+ Copyright (C) 2023, 2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -128,6 +128,7 @@ TALER_EXCHANGE_post_aml_decision (
struct GNUNET_CURL_Context *ctx,
const char *url,
const struct TALER_PaytoHashP *h_payto,
+ const char *payto_uri,
struct GNUNET_TIME_Timestamp decision_time,
const char *successor_measure,
const char *new_measures,
@@ -269,6 +270,9 @@ TALER_EXCHANGE_post_aml_decision (
justification),
GNUNET_JSON_pack_data_auto ("h_payto",
h_payto),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("payto_uri",
+ payto_uri)),
GNUNET_JSON_pack_object_steal ("new_rules",
new_rules),
GNUNET_JSON_pack_object_incref ("properties",
diff --git a/src/testing/testing_api_cmd_take_aml_decision.c b/src/testing/testing_api_cmd_take_aml_decision.c
@@ -354,6 +354,7 @@ take_aml_decision_run (void *cls,
TALER_TESTING_interpreter_get_context (is),
exchange_url,
h_payto,
+ NULL, /* payto_uri */
now,
ds->successor_measure,
new_measures,