commit d9a2f5aa6b1bf0f669bc25446caee5c7ae75f2f2
parent d160847fceb35fb80b3e9dc559b177003bff18f5
Author: Christian Grothoff <christian@grothoff.org>
Date: Tue, 22 Apr 2025 23:18:30 +0200
persist submitter class and form_id in kyc_attributes table; fixes #9661
Diffstat:
14 files changed, 139 insertions(+), 9 deletions(-)
diff --git a/src/exchange/taler-exchange-httpd_aml-decision.c b/src/exchange/taler-exchange-httpd_aml-decision.c
@@ -357,9 +357,12 @@ TEH_handler_post_aml_decision (
struct GNUNET_HashCode h_attr = { 0 };
size_t eas = 0;
void *ea = NULL;
+ const char *form_id = NULL;
if (NULL != attributes)
{
+ form_id = json_string_value (json_object_get (attributes,
+ "FORM_ID"));
TALER_json_hash (attributes,
&h_attr);
TALER_CRYPTO_kyc_attributes_encrypt (&TEH_attribute_key,
@@ -400,6 +403,7 @@ TEH_handler_post_aml_decision (
&officer_sig,
num_events,
sevents,
+ form_id,
eas, /* enc_attributes_size*/
ea, /* enc_attributes*/
&h_attr, /* attributes_hash */
diff --git a/src/exchange/taler-exchange-httpd_common_kyc.c b/src/exchange/taler-exchange-httpd_common_kyc.c
@@ -291,6 +291,7 @@ TEH_kyc_store_attributes (
unsigned int birthday = 0;
size_t eas = 0;
void *ea = NULL;
+ const char *form_id = NULL;
if (TEH_age_restriction_enabled)
{
@@ -316,8 +317,11 @@ TEH_kyc_store_attributes (
}
}
}
+
if (NULL != new_attributes)
{
+ form_id = json_string_value (json_object_get (new_attributes,
+ "FORM_ID"));
TALER_CRYPTO_kyc_attributes_encrypt (&TEH_attribute_key,
new_attributes,
&ea,
@@ -332,6 +336,7 @@ TEH_kyc_store_attributes (
provider_legitimization_id,
birthday,
expiration,
+ form_id,
eas,
ea);
GNUNET_free (ea);
@@ -706,6 +711,7 @@ handle_aml_fallback_result (
NULL, /* decider_sig */
apr->details.success.num_events,
apr->details.success.events,
+ NULL, /* form_id */
0, /* enc_attributes_size*/
NULL, /* enc_attributes*/
NULL, /* attributes_hash */
diff --git a/src/exchangedb/.gitignore b/src/exchangedb/.gitignore
@@ -19,3 +19,4 @@ exchange-0006.sql
exchange-0007.sql
exchange-0008.sql
exchange-0009.sql
+exchange-0010.sql
diff --git a/src/exchangedb/0010-kyc-attributes.sql b/src/exchangedb/0010-kyc-attributes.sql
@@ -0,0 +1,60 @@
+--
+-- This file is part of TALER
+-- Copyright (C) 2025 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+CREATE OR REPLACE FUNCTION alter_table_kyc_attributes10(
+ IN partition_suffix TEXT DEFAULT NULL
+)
+RETURNS VOID
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ table_name TEXT DEFAULT 'kyc_attributes';
+BEGIN
+ PERFORM create_partitioned_table(
+ 'ALTER TABLE %I'
+ ' ADD COLUMN form_name TEXT DEFAULT(NULL)'
+ ',ADD COLUMN by_aml_officer BOOL NOT NULL DEFAULT(FALSE)'
+ ';'
+ ,table_name
+ ,''
+ ,partition_suffix
+ );
+ PERFORM comment_partitioned_column(
+ 'Name of the form (FORM_ID) that is captured in the attributes.'
+ ,'form_name'
+ ,table_name
+ ,partition_suffix
+ );
+ PERFORM comment_partitioned_column(
+ 'TRUE if the attributes were submitted by an AML officer.'
+ ,'by_aml_officer'
+ ,table_name
+ ,partition_suffix
+ );
+END $$;
+
+INSERT INTO exchange_tables
+ (name
+ ,version
+ ,action
+ ,partitioned
+ ,by_range)
+ VALUES
+ ('kyc_attributes10'
+ ,'exchange-0010'
+ ,'alter'
+ ,TRUE
+ ,FALSE);
diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am
@@ -33,6 +33,7 @@ sqlinputs = \
0007-*.sql \
0008-*.sql \
0009-*.sql \
+ 0010-*.sql \
exchange-0002.sql.in \
exchange-0003.sql.in \
exchange-0004.sql.in \
@@ -40,7 +41,8 @@ sqlinputs = \
exchange-0006.sql.in \
exchange-0007.sql.in \
exchange-0008.sql.in \
- exchange-0009.sql.in
+ exchange-0009.sql.in \
+ exchange-0010.sql.in
sql_DATA = \
benchmark-0001.sql \
@@ -55,6 +57,7 @@ sql_DATA = \
exchange-0007.sql \
exchange-0008.sql \
exchange-0009.sql \
+ exchange-0010.sql \
drop.sql \
procedures.sql \
tops-0001.sql
@@ -74,6 +77,7 @@ CLEANFILES = \
exchange-0007.sql \
exchange-0008.sql \
exchange-0009.sql \
+ exchange-0010.sql \
procedures.sql
procedures.sql: procedures.sql.in exchange_do_*.sql exchange_statistics_helpers.sql
@@ -121,6 +125,11 @@ exchange-0009.sql: exchange-0009.sql.in 0009-*.sql
gcc -E -P -undef - < exchange-0009.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@
chmod ugo-w $@
+exchange-0010.sql: exchange-0010.sql.in 0010-*.sql
+ chmod +w $@ 2> /dev/null || true
+ gcc -E -P -undef - < exchange-0010.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@
+ chmod ugo-w $@
+
check_SCRIPTS = \
test_idempotency.sh
diff --git a/src/exchangedb/exchange-0010.sql.in b/src/exchangedb/exchange-0010.sql.in
@@ -0,0 +1,23 @@
+--
+-- This file is part of TALER
+-- Copyright (C) 2025 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+
+BEGIN;
+
+SELECT _v.register_patch('exchange-0010', NULL, NULL);
+SET search_path TO exchange;
+
+#include "0010-kyc-attributes.sql"
+
+COMMIT;
diff --git a/src/exchangedb/exchange_do_insert_aml_decision.sql b/src/exchangedb/exchange_do_insert_aml_decision.sql
@@ -34,6 +34,7 @@ CREATE FUNCTION exchange_do_insert_aml_decision(
IN in_decider_sig BYTEA, -- can be NULL
IN in_notify_s TEXT,
IN ina_events TEXT[],
+ IN in_form_name TEXT, -- can be NULL
OUT out_invalid_officer BOOLEAN,
OUT out_account_unknown BOOLEAN,
OUT out_last_date INT8,
@@ -233,12 +234,16 @@ THEN
(h_payto
,collection_time
,expiration_time
+ ,form_name
+ ,by_aml_officer
,encrypted_attributes
,legitimization_serial
) VALUES
(in_h_normalized_payto
,in_decision_time
,in_kyc_attributes_expiration
+ ,in_form_name
+ ,TRUE
,in_kyc_attributes_enc
,my_legitimization_process_serial_id
)
@@ -295,5 +300,5 @@ EXECUTE FORMAT (
END $$;
-COMMENT ON FUNCTION exchange_do_insert_aml_decision(TEXT, BYTEA, BYTEA, INT8, INT8, TEXT, BYTEA, BYTEA, INT8, TEXT, BOOLEAN, TEXT, TEXT, TEXT, BYTEA, BYTEA, TEXT, TEXT[])
+COMMENT ON FUNCTION exchange_do_insert_aml_decision(TEXT, BYTEA, BYTEA, INT8, INT8, TEXT, BYTEA, BYTEA, INT8, TEXT, BOOLEAN, TEXT, TEXT, TEXT, BYTEA, BYTEA, TEXT, TEXT[], 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/exchange_do_persist_kyc_attributes.sql b/src/exchangedb/exchange_do_persist_kyc_attributes.sql
@@ -27,6 +27,7 @@ CREATE FUNCTION exchange_do_persist_kyc_attributes(
IN in_expiration_time_ts INT8, -- rounded to timestamp
IN in_enc_attributes BYTEA,
IN in_kyc_completed_notify_s TEXT,
+ IN in_form_name TEXT, -- can be NULL
OUT out_ok BOOLEAN) -- set to true if we had a legi process matching in_process_row and in_provider_name for this account
LANGUAGE plpgsql
AS $$
@@ -36,12 +37,16 @@ INSERT INTO kyc_attributes
(h_payto
,collection_time
,expiration_time
+ ,form_name
+ ,by_aml_officer
,encrypted_attributes
,legitimization_serial
) VALUES
(in_h_payto
,in_collection_time_ts
,in_expiration_time_ts
+ ,in_form_name
+ ,FALSE
,in_enc_attributes
,in_process_row);
@@ -86,5 +91,5 @@ INSERT INTO kyc_alerts
END $$;
-COMMENT ON FUNCTION exchange_do_persist_kyc_attributes(INT8, BYTEA, INT4, TEXT, TEXT, TEXT, INT8, INT8, INT8, BYTEA, TEXT)
+COMMENT ON FUNCTION exchange_do_persist_kyc_attributes(INT8, BYTEA, INT4, TEXT, TEXT, TEXT, INT8, INT8, INT8, BYTEA, TEXT, TEXT)
IS 'Inserts new KYC attributes and updates the status of the legitimization process';
diff --git a/src/exchangedb/exchangedb_aml.c b/src/exchangedb/exchangedb_aml.c
@@ -93,6 +93,7 @@ TALER_EXCHANGEDB_persist_aml_program_result (
NULL, /* decider_sig */
apr->details.success.num_events,
apr->details.success.events,
+ NULL, /* form ID */
0, /* enc_attributes_size*/
NULL, /* enc_attributes*/
NULL, /* attributes_hash */
diff --git a/src/exchangedb/pg_insert_aml_decision.c b/src/exchangedb/pg_insert_aml_decision.c
@@ -44,6 +44,7 @@ TEH_PG_insert_aml_decision (
const struct TALER_AmlOfficerSignatureP *decider_sig,
size_t num_events,
const char *events[static num_events],
+ const char *form_name,
size_t enc_attributes_size,
const void *enc_attributes,
struct GNUNET_HashCode *attributes_hash,
@@ -123,6 +124,9 @@ TEH_PG_insert_aml_decision (
GNUNET_PQ_query_param_array_ptrs_string (num_events,
events,
pg->conn),
+ (NULL == form_name)
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_string (form_name),
GNUNET_PQ_query_param_end
};
char *rpayto = NULL;
@@ -162,7 +166,7 @@ TEH_PG_insert_aml_decision (
",out_legitimization_measure_serial_id"
",out_payto_uri"
" FROM exchange_do_insert_aml_decision"
- "($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18);");
+ "($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19);");
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
@@ -49,6 +49,7 @@
* @param events array of events to trigger
* @param enc_attributes_size number of bytes in @a enc_attributes
* @param enc_attributes encrypted attribute data
+ * @param form_name name of the form from which @a enc_attributes originate, can be NULL
* @param attributes_hash hash of the unencrypted attribute data
* @param attributes_expiration_time when does the attribute data expire
* @param[out] invalid_officer set to TRUE if @a decider_pub is not allowed to make decisions right now
@@ -77,6 +78,7 @@ TEH_PG_insert_aml_decision (
const struct TALER_AmlOfficerSignatureP *decider_sig,
size_t num_events,
const char *events[static num_events],
+ const char *form_name,
size_t enc_attributes_size,
const void *enc_attributes,
struct GNUNET_HashCode *attributes_hash,
diff --git a/src/exchangedb/pg_persist_kyc_attributes.c b/src/exchangedb/pg_persist_kyc_attributes.c
@@ -36,6 +36,7 @@ TEH_PG_persist_kyc_attributes (
const char *provider_legitimization_id,
uint32_t birthday,
struct GNUNET_TIME_Absolute expiration_time,
+ const char *form_name,
size_t enc_attributes_size,
const void *enc_attributes)
{
@@ -72,6 +73,9 @@ TEH_PG_persist_kyc_attributes (
: GNUNET_PQ_query_param_fixed_size (enc_attributes,
enc_attributes_size),
GNUNET_PQ_query_param_string (kyc_completed_notify_s),
+ (NULL == form_name)
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_string (form_name),
GNUNET_PQ_query_param_end
};
bool ok;
@@ -91,7 +95,7 @@ TEH_PG_persist_kyc_attributes (
"SELECT "
" out_ok"
" FROM exchange_do_persist_kyc_attributes "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);");
+ "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);");
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"persist_kyc_attributes",
params,
diff --git a/src/exchangedb/pg_persist_kyc_attributes.h b/src/exchangedb/pg_persist_kyc_attributes.h
@@ -37,6 +37,7 @@
* @param provider_legitimization_id provider legitimization ID
* @param birthday birthdate of user, in days after 1990, or 0 if unknown or definitively adult
* @param expiration_time when does the data expire
+ * @param form_name name of the form from which the @a enc_attributes originate, can be NULL
* @param enc_attributes_size number of bytes in @a enc_attributes
* @param enc_attributes encrypted attribute data
* @return database transaction status
@@ -51,6 +52,7 @@ TEH_PG_persist_kyc_attributes (
const char *provider_legitimization_id,
uint32_t birthday,
struct GNUNET_TIME_Absolute expiration_time,
+ const char *form_name,
size_t enc_attributes_size,
const void *enc_attributes);
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
@@ -8034,10 +8034,11 @@ struct TALER_EXCHANGEDB_Plugin
* @param decider_sig signature of the staff member
* @param num_events length of the @a events array
* @param events array of events to trigger
- * @param enc_attributes_size number of bytes in @a enc_attributes
- * @param enc_attributes encrypted attribute data
- * @param attributes_hash hash of the unencrypted attribute data
- * @param attributes_expiration_time when does the attribute data expire
+ * @param form_name name of the form from which @a enc_attributes originate, can be NULL
+ * @param enc_attributes_size number of bytes in @a enc_attributes
+ * @param enc_attributes encrypted attribute data
+ * @param attributes_hash hash of the unencrypted attribute data
+ * @param attributes_expiration_time when does the attribute data expire
* @param[out] invalid_officer set to TRUE if @a decider_pub is not allowed to make decisions right now
* @param[out] unknown_account set to TRUE if @a h_payto does not refer to a known account and @a jmeasures was given
* @param[out] last_date set to the previous decision time;
@@ -8064,6 +8065,7 @@ struct TALER_EXCHANGEDB_Plugin
const struct TALER_AmlOfficerSignatureP *decider_sig,
size_t num_events,
const char *events[static num_events],
+ const char *form_name,
size_t enc_attributes_size,
const void *enc_attributes,
struct GNUNET_HashCode *attributes_hash,
@@ -8086,6 +8088,7 @@ struct TALER_EXCHANGEDB_Plugin
* @param provider_legitimization_id provider legitimization ID
* @param birthday birthdate of user, in days after 1990, or 0 if unknown or definitively adult
* @param expiration_time when does the data expire
+ * @param form_name name of the form from which the @a enc_attributes originate, can be NULL
* @param enc_attributes_size number of bytes in @a enc_attributes
* @param enc_attributes encrypted attribute data
* @return database transaction status
@@ -8100,6 +8103,7 @@ struct TALER_EXCHANGEDB_Plugin
const char *provider_legitimization_id,
uint32_t birthday,
struct GNUNET_TIME_Absolute expiration_time,
+ const char *form_name,
size_t enc_attributes_size,
const void *enc_attributes);