commit 19173147e396d0431859d66bf94c6fa8a8c350a0
parent 3665a932b381d5e539b2bd8fdb65209cf8b8ed56
Author: Christian Grothoff <christian@grothoff.org>
Date: Tue, 22 Apr 2025 13:00:05 +0200
fix #9767: filter rules by payto wire method
Diffstat:
4 files changed, 121 insertions(+), 22 deletions(-)
diff --git a/src/exchange/taler-exchange-httpd_common_kyc.c b/src/exchange/taler-exchange-httpd_common_kyc.c
@@ -417,6 +417,7 @@ TEH_kyc_run_measure_for_attributes (
kat->kyc_aml
= TALER_KYCLOGIC_run_aml_program (
kat->jmeasures,
+ kat->is_wallet,
kat->measure_index,
&TALER_EXCHANGEDB_current_attributes_builder,
&hbc,
@@ -550,6 +551,7 @@ TEH_kyc_run_measure_directly (
kat->kyc_aml
= TALER_KYCLOGIC_run_aml_program3 (
+ kat->is_wallet,
instant_ms,
&TALER_EXCHANGEDB_current_attributes_builder,
&hbc,
@@ -800,6 +802,7 @@ TEH_kyc_fallback (
= TALER_KYCLOGIC_run_aml_program2 (
kcc.prog_name,
kcc.context,
+ is_wallet,
&TALER_EXCHANGEDB_current_attributes_builder,
&hbc,
&TALER_EXCHANGEDB_current_rule_builder,
diff --git a/src/exchangedb/exchangedb_aml.c b/src/exchangedb/exchangedb_aml.c
@@ -471,6 +471,7 @@ run_measure (struct TALER_EXCHANGEDB_RuleUpdater *ru,
m->prog_name);
GNUNET_assert (NULL == ru->t);
ru->amlh = TALER_KYCLOGIC_run_aml_program3 (
+ ru->is_wallet,
m,
&TALER_EXCHANGEDB_current_attributes_builder,
&hbc,
diff --git a/src/include/taler_kyclogic_lib.h b/src/include/taler_kyclogic_lib.h
@@ -920,6 +920,7 @@ typedef json_t *
* @param jmeasures current KYC/AML rules to apply;
* they determine also the AML program and
* provide the context
+ * @param is_wallet true if this is for a wallet
* @param measure_index which KYC measure yielded the
* @a attributes
* @param current_attributes_cb function to get current KYC attributes
@@ -943,6 +944,7 @@ typedef json_t *
struct TALER_KYCLOGIC_AmlProgramRunnerHandle *
TALER_KYCLOGIC_run_aml_program (
const json_t *jmeasures,
+ bool is_wallet,
unsigned int measure_index,
TALER_KYCLOGIC_HistoryBuilderCallback current_attributes_cb,
void *current_attributes_cb_cls,
@@ -962,6 +964,7 @@ TALER_KYCLOGIC_run_aml_program (
*
* @param prog_name name of AML program to run
* @param context context to run with
+ * @param is_wallet true if this is for a wallet
* @param current_attributes_cb function to get current KYC attributes
* @param current_attributes_cb_cls closure for @a current_attributes_cb
* @param current_rules_cb callback to get current KYC rules that apply to the account
@@ -984,6 +987,7 @@ struct TALER_KYCLOGIC_AmlProgramRunnerHandle *
TALER_KYCLOGIC_run_aml_program2 (
const char *prog_name,
const json_t *context,
+ bool is_wallet,
TALER_KYCLOGIC_HistoryBuilderCallback current_attributes_cb,
void *current_attributes_cb_cls,
TALER_KYCLOGIC_HistoryBuilderCallback current_rules_cb,
@@ -1001,6 +1005,7 @@ TALER_KYCLOGIC_run_aml_program2 (
* Run AML program specified by the given
* measure.
*
+ * @param is_wallet true if this is for a wallet
* @param measure measure with program name and context
* to run
* @param current_attributes_cb function to get current KYC attributes
@@ -1023,6 +1028,7 @@ TALER_KYCLOGIC_run_aml_program2 (
*/
struct TALER_KYCLOGIC_AmlProgramRunnerHandle *
TALER_KYCLOGIC_run_aml_program3 (
+ bool is_wallet,
const struct TALER_KYCLOGIC_Measure *measure,
TALER_KYCLOGIC_HistoryBuilderCallback current_attributes_cb,
void *current_attributes_cb_cls,
diff --git a/src/kyclogic/kyclogic_api.c b/src/kyclogic/kyclogic_api.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2022-2024 Taler Systems SA
+ Copyright (C) 2022-2025 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -23,6 +23,11 @@
#include "taler_kyclogic_lib.h"
/**
+ * Log verbosely, including possibly privacy-sensitive data.
+ */
+#define DEBUG 1
+
+/**
* Name of the KYC measure that may never be passed. Useful if some
* operations/amounts are categorically forbidden.
*/
@@ -142,12 +147,6 @@ struct TALER_KYCLOGIC_LegitimizationRuleSet
char *successor_measure;
/**
- * This object in JSON format. Excludes *default* measures even
- * if these are the default rules.
- */
- json_t *jlrs;
-
- /**
* Array of the rules.
*/
struct TALER_KYCLOGIC_KycRule *kyc_rules;
@@ -341,6 +340,18 @@ static char *cfg_filename;
*/
static char *my_currency;
+/**
+ * Default LegitimizationRuleSet for wallets. Excludes *default* measures
+ * even if these are the default rules.
+ */
+static json_t *wallet_default_lrs;
+
+/**
+ * Default LegitimizationRuleSet for bank accounts. Excludes *default* measures
+ * even if these are the default rules.
+ */
+static json_t *bankaccount_default_lrs;
+
struct GNUNET_TIME_Timestamp
TALER_KYCLOGIC_rules_get_expiration (
@@ -728,9 +739,6 @@ TALER_KYCLOGIC_rules_parse (const json_t *jlrs)
}
}
-
- lrs->jlrs
- = json_incref ((json_t *) jlrs);
lrs->kyc_rules
= GNUNET_new_array (lrs->num_kyc_rules,
struct TALER_KYCLOGIC_KycRule);
@@ -870,7 +878,6 @@ TALER_KYCLOGIC_rules_free (struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs)
json_decref (measure->context);
}
GNUNET_free (lrs->kyc_rules);
- json_decref (lrs->jlrs);
GNUNET_free (lrs->custom_measures);
GNUNET_free (lrs->successor_measure);
GNUNET_free (lrs);
@@ -2837,7 +2844,8 @@ TALER_KYCLOGIC_kyc_init (
.cfg = cfg,
.result = true
};
- json_t *jkyc_rules;
+ json_t *jkyc_rules_w;
+ json_t *jkyc_rules_a;
if (NULL != cfg_fn)
cfg_filename = GNUNET_strdup (cfg_fn);
@@ -2891,8 +2899,10 @@ TALER_KYCLOGIC_kyc_init (
default_rules.num_kyc_rules,
sizeof (struct TALER_KYCLOGIC_KycRule),
&sort_by_timeframe);
- jkyc_rules = json_array ();
- GNUNET_assert (NULL != jkyc_rules);
+ jkyc_rules_w = json_array ();
+ GNUNET_assert (NULL != jkyc_rules_w);
+ jkyc_rules_a = json_array ();
+ GNUNET_assert (NULL != jkyc_rules_a);
for (unsigned int i=0; i<default_rules.num_kyc_rules; i++)
{
@@ -2950,16 +2960,73 @@ TALER_KYCLOGIC_kyc_init (
GNUNET_JSON_pack_bool ("is_and_combinator",
rule->is_and_combinator)
);
- GNUNET_assert (0 ==
- json_array_append_new (jkyc_rules,
- jrule));
+ switch (rule->trigger)
+ {
+ case TALER_KYCLOGIC_KYC_TRIGGER_NONE:
+ GNUNET_break (0);
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW:
+ GNUNET_assert (0 ==
+ json_array_append (jkyc_rules_a,
+ jrule));
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT:
+ GNUNET_assert (0 ==
+ json_array_append (jkyc_rules_a,
+ jrule));
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE:
+ GNUNET_assert (0 ==
+ json_array_append (jkyc_rules_w,
+ jrule));
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE:
+ GNUNET_assert (0 ==
+ json_array_append (jkyc_rules_w,
+ jrule));
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE:
+ GNUNET_assert (0 ==
+ json_array_append (jkyc_rules_a,
+ jrule));
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE:
+ GNUNET_assert (0 ==
+ json_array_append (jkyc_rules_a,
+ jrule));
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION:
+ GNUNET_assert (0 ==
+ json_array_append (jkyc_rules_a,
+ jrule));
+ GNUNET_assert (0 ==
+ json_array_append (jkyc_rules_w,
+ jrule));
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_REFUND:
+ GNUNET_assert (0 ==
+ json_array_append (jkyc_rules_a,
+ jrule));
+ GNUNET_assert (0 ==
+ json_array_append (jkyc_rules_w,
+ jrule));
+ break;
+ }
+ json_decref (jrule);
}
- default_rules.jlrs
+ wallet_default_lrs
= GNUNET_JSON_PACK (
GNUNET_JSON_pack_timestamp ("expiration_time",
GNUNET_TIME_UNIT_FOREVER_TS),
GNUNET_JSON_pack_array_steal ("rules",
- jkyc_rules)
+ jkyc_rules_w)
+ );
+ bankaccount_default_lrs
+ = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_timestamp ("expiration_time",
+ GNUNET_TIME_UNIT_FOREVER_TS),
+ GNUNET_JSON_pack_array_steal ("rules",
+ jkyc_rules_a)
);
for (unsigned int i=0; i<default_rules.num_custom_measures; i++)
@@ -4011,12 +4078,14 @@ handle_aml_output (
GNUNET_SCHEDULER_cancel (aprh->async_cb);
aprh->async_cb = NULL;
}
+#if DEBUG
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"AML program %s output is:\n",
aprh->program->program_name);
json_dumpf (result,
stderr,
JSON_INDENT (2));
+#endif
memset (apr,
0,
sizeof (*apr));
@@ -4306,6 +4375,7 @@ handle_aml_timeout (void *cls)
struct TALER_KYCLOGIC_AmlProgramRunnerHandle *
TALER_KYCLOGIC_run_aml_program (
const json_t *jmeasures,
+ bool is_wallet,
unsigned int measure_index,
TALER_KYCLOGIC_HistoryBuilderCallback current_attributes_cb,
void *current_attributes_cb_cls,
@@ -4339,6 +4409,7 @@ TALER_KYCLOGIC_run_aml_program (
}
return TALER_KYCLOGIC_run_aml_program2 (prog_name,
context,
+ is_wallet,
current_attributes_cb,
current_attributes_cb_cls,
current_rules_cb,
@@ -4357,6 +4428,7 @@ struct TALER_KYCLOGIC_AmlProgramRunnerHandle *
TALER_KYCLOGIC_run_aml_program2 (
const char *prog_name,
const json_t *context,
+ bool is_wallet,
TALER_KYCLOGIC_HistoryBuilderCallback current_attributes_cb,
void *current_attributes_cb_cls,
TALER_KYCLOGIC_HistoryBuilderCallback current_rules_cb,
@@ -4390,6 +4462,7 @@ TALER_KYCLOGIC_run_aml_program2 (
if (0 != (API_ATTRIBUTES & prog->input_mask))
{
attributes = current_attributes_cb (current_attributes_cb_cls);
+#if DEBUG
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"KYC attributes for AML program %s are:\n",
prog_name);
@@ -4398,6 +4471,7 @@ TALER_KYCLOGIC_run_aml_program2 (
JSON_INDENT (2));
fprintf (stderr,
"\n");
+#endif
for (unsigned int i = 0; i<prog->num_required_attributes; i++)
{
const char *rattr = prog->required_attributes[i];
@@ -4409,9 +4483,11 @@ TALER_KYCLOGIC_run_aml_program2 (
"KYC attributes lack required attribute `%s' for AML program %s\n",
rattr,
prog->program_name);
+#if DEBUG
json_dumpf (attributes,
stderr,
JSON_INDENT (2));
+#endif
aprh->apr.status = TALER_KYCLOGIC_AMLR_FAILURE;
aprh->apr.details.failure.fallback_measure
= prog->fallback;
@@ -4443,9 +4519,11 @@ TALER_KYCLOGIC_run_aml_program2 (
"Context lacks required field `%s' for AML program %s\n",
rctx,
prog->program_name);
+#if DEBUG
json_dumpf (context,
stderr,
JSON_INDENT (2));
+#endif
aprh->apr.status = TALER_KYCLOGIC_AMLR_FAILURE;
aprh->apr.details.failure.fallback_measure
= prog->fallback;
@@ -4477,7 +4555,10 @@ TALER_KYCLOGIC_run_aml_program2 (
else
current_rules = current_rules_cb (current_rules_cb_cls);
if (0 != (API_DEFAULT_RULES & prog->input_mask))
- jdefault_rules = default_rules.jlrs;
+ jdefault_rules =
+ (is_wallet
+ ? wallet_default_lrs
+ : bankaccount_default_lrs);
else
jdefault_rules = NULL;
{
@@ -4516,9 +4597,11 @@ TALER_KYCLOGIC_run_aml_program2 (
extra_args);
GNUNET_assert (NULL != args);
GNUNET_assert (NULL != args[0]);
+#if DEBUG
json_dumpf (input,
stderr,
JSON_INDENT (2));
+#endif
aprh->proc = TALER_JSON_external_conversion_start (
input,
&handle_aml_output,
@@ -4538,6 +4621,7 @@ TALER_KYCLOGIC_run_aml_program2 (
struct TALER_KYCLOGIC_AmlProgramRunnerHandle *
TALER_KYCLOGIC_run_aml_program3 (
+ bool is_wallet,
const struct TALER_KYCLOGIC_Measure *measure,
TALER_KYCLOGIC_HistoryBuilderCallback current_attributes_cb,
void *current_attributes_cb_cls,
@@ -4554,6 +4638,7 @@ TALER_KYCLOGIC_run_aml_program3 (
return TALER_KYCLOGIC_run_aml_program2 (
measure->prog_name,
measure->context,
+ is_wallet,
current_attributes_cb,
current_attributes_cb_cls,
current_rules_cb,
@@ -4674,8 +4759,12 @@ TALER_KYCLOGIC_get_zero_limits ()
json_t *
TALER_KYCLOGIC_get_default_legi_rules (bool for_wallet)
{
- // FIXME-#9767: specialize based on 'for_wallet'!
- return json_incref ((json_t *) default_rules.jlrs);
+ const json_t *r;
+
+ r = (for_wallet
+ ? wallet_default_lrs
+ : bankaccount_default_lrs);
+ return json_incref ((json_t *) r);
}