exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit ceb2b95a60570d7cb4d97a683773a8c95530b3e6
parent 6f0afcaad430dba29d8a404a041cf53d37c39387
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon,  6 May 2024 14:08:14 +0200

kyclogic API planning

Diffstat:
Msrc/exchangedb/Makefile.am | 2+-
Asrc/exchangedb/pg_get_kyc_rules.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/pg_get_kyc_rules.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/exchangedb/pg_select_satisfied_kyc_processes.c | 141-------------------------------------------------------------------------------
Dsrc/exchangedb/pg_select_satisfied_kyc_processes.h | 47-----------------------------------------------
Msrc/include/taler_exchangedb_plugin.h | 28+++++++---------------------
Msrc/include/taler_kyclogic_lib.h | 155++++++++++++++++++++++++++++++-------------------------------------------------
Msrc/kyclogic/kyclogic_api.c | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
8 files changed, 239 insertions(+), 315 deletions(-)

diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am @@ -105,7 +105,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \ pg_reserves_update.h pg_reserves_update.c \ pg_select_aggregation_amounts_for_kyc_check.h pg_select_aggregation_amounts_for_kyc_check.c \ pg_lookup_wire_fee_by_time.h pg_lookup_wire_fee_by_time.c \ - pg_select_satisfied_kyc_processes.h pg_select_satisfied_kyc_processes.c \ + pg_get_kyc_rules.h pg_get_kyc_rules.c \ pg_get_pending_kyc_requirement_process.h pg_get_pending_kyc_requirement_process.c \ pg_kyc_provider_account_lookup.h pg_kyc_provider_account_lookup.c \ pg_insert_kyc_requirement_for_account.h pg_insert_kyc_requirement_for_account.c \ diff --git a/src/exchangedb/pg_get_kyc_rules.c b/src/exchangedb/pg_get_kyc_rules.c @@ -0,0 +1,62 @@ +/* + This file is part of TALER + Copyright (C) 2022-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 + 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/> + */ +/** + * @file exchangedb/pg_get_kyc_rules.c + * @brief Implementation of the get_kyc_rules 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_get_kyc_rules.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +TEH_PG_get_kyc_rules ( + void *cls, + const struct TALER_PaytoHashP *h_payto, + struct GNUNET_TIME_Timestamp *expiration_time, + json_t **jrules) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_json ("jnew_rules", + jrules), + GNUNET_PQ_result_spec_timestamp ("expiration_time", + expiration_time), + GNUNET_PQ_result_spec_end + }; + + PREPARE (pg, + "get_kyc_rules", + "SELECT" + " jnew_rules" + " ,expiration_time" + " FROM legitimization_outcomes" + " WHERE h_payto=$1" + " AND is_active;"); + return GNUNET_PQ_eval_prepared_singleton_select ( + pg->conn, + "get_kyc_rules", + params, + rs); +} diff --git a/src/exchangedb/pg_get_kyc_rules.h b/src/exchangedb/pg_get_kyc_rules.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2022-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 + 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/> + */ +/** + * @file exchangedb/pg_get_kyc_rules.h + * @brief implementation of the get_kyc_rules function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_GET_KYC_RULES_H +#define PG_GET_KYC_RULES_H + +#include "taler_util.h" +#include "taler_json_lib.h" +#include "taler_exchangedb_plugin.h" + + +/** + * Return KYC rules that apply to the given account. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param h_payto account identifier + * @param[out] expiration_time when do the @a jrules expire + * @param[out] jrules set to the active KYC rules for the + * given account, set to NULL if no custom rules are active + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +TEH_PG_get_kyc_rules ( + void *cls, + const struct TALER_PaytoHashP *h_payto, + struct GNUNET_TIME_Timestamp *expiration_time, + json_t **jrules); + +#endif diff --git a/src/exchangedb/pg_select_satisfied_kyc_processes.c b/src/exchangedb/pg_select_satisfied_kyc_processes.c @@ -1,141 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022 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/> - */ -/** - * @file exchangedb/pg_select_satisfied_kyc_processes.c - * @brief Implementation of the select_satisfied_kyc_processes 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_select_satisfied_kyc_processes.h" -#include "pg_helper.h" - - -/** - * Closure for #get_legitimizations_cb(). - */ -struct GetLegitimizationsContext -{ - /** - * Function to call per result. - */ - TALER_EXCHANGEDB_SatisfiedProviderCallback cb; - - /** - * Closure for @e cb. - */ - void *cb_cls; - - /** - * Plugin context. - */ - struct PostgresClosure *pg; - - /** - * Flag set to #GNUNET_OK as long as everything is fine. - */ - enum GNUNET_GenericReturnValue status; - -}; - - -/** - * Invoke the callback for each result. - * - * @param cls a `struct GetLegitimizationsContext *` - * @param result SQL result - * @param num_results number of rows in @a result - */ -static void -get_legitimizations_cb (void *cls, - PGresult *result, - unsigned int num_results) -{ - struct GetLegitimizationsContext *ctx = cls; - - for (unsigned int i = 0; i < num_results; i++) - { - char *provider_section; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_string ("provider_section", - &provider_section), - GNUNET_PQ_result_spec_end - }; - - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, - rs, - i)) - { - GNUNET_break (0); - ctx->status = GNUNET_SYSERR; - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Found satisfied LEGI: %s\n", - provider_section); - ctx->cb (ctx->cb_cls, - provider_section); - GNUNET_PQ_cleanup_result (rs); - } -} - - -enum GNUNET_DB_QueryStatus -TEH_PG_select_satisfied_kyc_processes ( - void *cls, - const struct TALER_PaytoHashP *h_payto, - TALER_EXCHANGEDB_SatisfiedProviderCallback spc, - void *spc_cls) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_TIME_Absolute now - = GNUNET_TIME_absolute_get (); - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (h_payto), - GNUNET_PQ_query_param_absolute_time (&now), - GNUNET_PQ_query_param_end - }; - struct GetLegitimizationsContext ctx = { - .cb = spc, - .cb_cls = spc_cls, - .pg = pg, - .status = GNUNET_OK - }; - enum GNUNET_DB_QueryStatus qs; - - PREPARE (pg, - "get_satisfied_legitimizations", - "SELECT " - " provider_section" - " FROM legitimization_processes" - " WHERE h_payto=$1" - " AND expiration_time>=$2;"); - qs = GNUNET_PQ_eval_prepared_multi_select ( - pg->conn, - "get_satisfied_legitimizations", - params, - &get_legitimizations_cb, - &ctx); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Satisfied LEGI check returned %d\n", - qs); - if (GNUNET_OK != ctx.status) - return GNUNET_DB_STATUS_HARD_ERROR; - return qs; -} diff --git a/src/exchangedb/pg_select_satisfied_kyc_processes.h b/src/exchangedb/pg_select_satisfied_kyc_processes.h @@ -1,47 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022 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/> - */ -/** - * @file exchangedb/pg_select_satisfied_kyc_processes.h - * @brief implementation of the select_satisfied_kyc_processes function for Postgres - * @author Christian Grothoff - */ -#ifndef PG_SELECT_SATISFIED_KYC_PROCESSES_H -#define PG_SELECT_SATISFIED_KYC_PROCESSES_H - -#include "taler_util.h" -#include "taler_json_lib.h" -#include "taler_exchangedb_plugin.h" - -/** - * Call us on KYC processes satisfied for the given - * account. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param h_payto account identifier - * @param spc function to call for each satisfied KYC process - * @param spc_cls closure for @a spc - * @return transaction status code - */ - - -enum GNUNET_DB_QueryStatus -TEH_PG_select_satisfied_kyc_processes ( - void *cls, - const struct TALER_PaytoHashP *h_payto, - TALER_EXCHANGEDB_SatisfiedProviderCallback spc, - void *spc_cls); - -#endif diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h @@ -1112,20 +1112,6 @@ typedef void /** - * Function called on all KYC process names that the given - * account has already passed. - * - * @param cls closure - * @param kyc_provider_section_name configuration section - * of the respective KYC process - */ -typedef void -(*TALER_EXCHANGEDB_SatisfiedProviderCallback)( - void *cls, - const char *kyc_provider_section_name); - - -/** * Function called on all legitimization operations * we have performed for the given account so far * (and that have not yet expired). @@ -6874,21 +6860,21 @@ struct TALER_EXCHANGEDB_Plugin /** - * Call us on KYC processes satisfied for the given - * account. + * Return KYC rules that apply to the given account. * * @param cls the @e cls of this struct with the plugin-specific state * @param h_payto account identifier - * @param spc function to call for each satisfied KYC process - * @param spc_cls closure for @a spc + * @param[out] expiration_time when do the @a jrules expire + * @param[out] jrules set to the active KYC rules for the + * given account, set to NULL if no custom rules are active * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*select_satisfied_kyc_processes)( + (*get_kyc_rules)( void *cls, const struct TALER_PaytoHashP *h_payto, - TALER_EXCHANGEDB_SatisfiedProviderCallback spc, - void *spc_cls); + struct GNUNET_TIME_Timestamp *expiration_time, + json_t **jrules); /** diff --git a/src/include/taler_kyclogic_lib.h b/src/include/taler_kyclogic_lib.h @@ -151,21 +151,36 @@ typedef void /** - * Call us on KYC processes satisfied for the given - * account. Must match the ``select_satisfied_kyc_processes`` of the exchange database plugin. + * Rule that triggers some measure(s). + */ +struct TALER_KYCLOGIC_KycRule; + +/** + * Set of rules that applies to an account. + */ +struct TALER_KYCLOGIC_KycRuleSet; + + +/** + * Parse set of rules that applies to an account. * - * @param cls the @e cls of this struct with the plugin-specific state - * @param h_payto account identifier - * @param spc function to call for each satisfied KYC process - * @param spc_cls closure for @a spc - * @return transaction status code + * @param jrules JSON representation to parse + * @param[out] lrs set to rule set + * @return #GNUNET_SYSERR JSON is invalid */ -typedef enum GNUNET_DB_QueryStatus -(*TALER_KYCLOGIC_KycSatisfiedIterator)( - void *cls, - const struct TALER_PaytoHashP *h_payto, - TALER_EXCHANGEDB_SatisfiedProviderCallback spc, - void *spc_cls); +enum GNUNET_GenericReturnValue +TALER_KYCLOGIC_rules_parse ( + const json_t *jrules, + struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs); + + +/** + * Free set of legitimization rules. + * + * @param[in] lrs set of rules to free + */ +void +TALER_KYCLOGIC_rules_free (struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs); /** @@ -177,55 +192,30 @@ typedef enum GNUNET_DB_QueryStatus * @param event what type of operation is triggering the * test if KYC is required * @param h_payto account the event is about - * @param ki callback that returns list of already - * satisfied KYC checks, implemented by ``select_satisfied_kyc_processes`` of the exchangedb - * @param ki_cls closure for @a ki + * @param lrs legitimization rules for @a h_payto * @param ai callback offered to inquire about historic * amounts involved in this type of operation * at the given account * @param ai_cls closure for @a ai - * @param[out] required set to NULL if no check is needed, - * otherwise space-separated list of required checks + * @param[out] triggered_rule set to NULL if no rule + * is triggered, otherwise the rule with measures + * that must be satisfied (will be the highest + * applicable rule by display priority) * @return transaction status */ enum GNUNET_DB_QueryStatus TALER_KYCLOGIC_kyc_test_required ( enum TALER_KYCLOGIC_KycTriggerEvent event, const struct TALER_PaytoHashP *h_payto, - TALER_KYCLOGIC_KycSatisfiedIterator ki, - void *ki_cls, + const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs, TALER_KYCLOGIC_KycAmountIterator ai, void *ai_cls, - char **required); + struct TALER_KYCLOGIC_KycRule **triggered_rule); /** - * Check if the @a requirements are now satsified for - * @a h_payto account. - * - * @param[in,out] requirements space-spearated list of requirements, - * already satisfied requirements are removed from the list - * @param h_payto hash over the account - * @param[out] kyc_details if satisfied, set to what kind of - * KYC information was collected - * @param ki iterator over satisfied providers - * @param ki_cls closure for @a ki - * @param[out] satisfied set to true if the KYC check was satisfied - * @return transaction status (from @a ki) - */ -enum GNUNET_DB_QueryStatus -TALER_KYCLOGIC_check_satisfied ( - char **requirements, - const struct TALER_PaytoHashP *h_payto, - json_t **kyc_details, - TALER_KYCLOGIC_KycSatisfiedIterator ki, - void *ki_cls, - bool *satisfied); - - -/** - * Iterate over all thresholds that are applicable - * to a particular type of @a event + * Iterate over all thresholds that are applicable to a particular type of @a + * event under exposed global rules. * * @param event thresholds to look up * @param it function to call on each @@ -239,61 +229,25 @@ TALER_KYCLOGIC_kyc_iterate_thresholds ( /** - * Function called with the provider details and - * associated plugin closures for matching logics. + * Check if a given @a rule can be satisfied in principle. * - * @param cls closure - * @param pd provider details of a matching logic - * @param plugin_cls closure of the plugin - * @return #GNUNET_OK to continue to iterate + * @param rule the rule to check if it is verboten + * @return true if the check can be satisfied, + * false if the check can never be satisfied, */ -typedef enum GNUNET_GenericReturnValue -(*TALER_KYCLOGIC_DetailsCallback)( - void *cls, - const struct TALER_KYCLOGIC_ProviderDetails *pd, - void *plugin_cls); +bool +TALER_KYCLOGIC_is_satisfiable ( + const struct TALER_KYCLOGIC_KycRule *rule); /** - * Call @a cb for all logics with name @a logic_name, - * providing the plugin closure and the @a pd configurations. + * Obtain the provider logic for a given set of @a lrs + * and a specific @a kyc_rule from @a lrs that was + * triggered and the choosen @a measure_name from the + * list of measures of that @a kyc_rule. * - * @param logic_name name of the logic to match - * @param cb function to call on matching results - * @param cb_cls closure for @a cb - */ -void -TALER_KYCLOGIC_kyc_get_details ( - const char *logic_name, - TALER_KYCLOGIC_DetailsCallback cb, - void *cb_cls); - - -/** - * Check if a given @a check_name is a legal name (properly - * configured) and can be satisfied in principle. - * - * @param check_name name of the check to see if it is configured - * @return #GNUNET_OK if the check can be satisfied, - * #GNUNET_NO if the check can never be satisfied, - * #GNUNET_SYSERR if the type of the check is unknown - */ -enum GNUNET_GenericReturnValue -TALER_KYCLOGIC_check_satisfiable ( - const char *check_name); - - -/** - * Return list of all KYC checks that are possible. - * - * @return JSON array of strings with the allowed KYC checks - */ -json_t * -TALER_KYCLOGIC_get_satisfiable (void); - - -/** - * Obtain the provider logic for a given set of @a requirements. + * FIXME: we probably want to instead set up the logic + * with the context instead of just returning it here! * * @param requirements space-separated list of required checks * @param ut type of the entity performing the check @@ -303,7 +257,9 @@ TALER_KYCLOGIC_get_satisfiable (void); */ enum GNUNET_GenericReturnValue TALER_KYCLOGIC_requirements_to_logic ( - const char *requirements, + const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs, + const struct TALER_KYCLOGIC_KycRule *kyc_rule, + const char *measure_name, struct TALER_KYCLOGIC_Plugin **plugin, struct TALER_KYCLOGIC_ProviderDetails **pd, const char **configuration_section); @@ -326,6 +282,10 @@ TALER_KYCLOGIC_lookup_logic ( const char **configuration_section); +// FIXME: we probably want to instead have some +// functionality that returns information that +// is more directly applicable for /keys or /config +// and not this: /** * Obtain array of KYC checks provided by the provider * configured in @a section_name. @@ -341,4 +301,5 @@ TALER_KYCLOGIC_lookup_checks ( unsigned int *num_checks, char ***provided_checks); + #endif diff --git a/src/kyclogic/kyclogic_api.c b/src/kyclogic/kyclogic_api.c @@ -232,10 +232,73 @@ struct TALER_KYCLOGIC_KycRule */ bool exposed; + /** + * True if any of the measures is 'verboten' and + * thus this rule cannot ever be satisfied. + */ + bool verboten; + }; /** + * Set of rules that applies to an account. + */ +struct TALER_KYCLOGIC_LegitimizationRuleSet +{ + + /** + * When does this rule set expire? + */ + struct GNUNET_TIME_Timestamp expiration_time; + + /** + * Name of the successor measure after expiration. + * NULL for default rules. + */ + char *successor_measure; + + /** + * Array of the rules. + */ + struct TALER_KYCLOGIC_KycRule **kyc_rules; + + /** + * Array of custom measures the @e kyc_rules may refer + * to. + */ + struct TALER_KYCLOGIC_Measures *custom_measures; + + /** + * Length of the @e kyc_rules array. + */ + unsigned int num_kyc_rules; + + /** + * Length of the @e custom_measures array. + */ + unsigned int num_custom_measures; +}; + + +enum GNUNET_GenericReturnValue +TALER_KYCLOGIC_rules_parse ( + const json_t *jrules, + struct TALER_KYCLOGIC_KycRuleSet *rules) +{ + // FIXME! + return GNUNET_SYSERR; +} + + +void +TALER_KYCLOGIC_rules_free (struct TALER_KYCLOGIC_KycRuleSet *krs) +{ + // fIXME +} + + +/** * AML programs. */ struct TALER_KYCLOGIC_AmlProgram @@ -317,15 +380,9 @@ static struct TALER_KYCLOGIC_KycCheck **kyc_checks; static unsigned int num_kyc_checks; /** - * Array of configured rules that apply if we do - * not have an AMLA record. - */ -static struct TALER_KYCLOGIC_KycRule **kyc_rules; - -/** - * Length of the #kyc_rules array. + * Rules that apply if we do not have an AMLA record. */ -static unsigned int num_kyc_rules; +static struct TALER_KYCLOGIC_KycRuleSet default_rules; /** * Array of available AML programs.