aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/exchange/taler-exchange-httpd.c33
-rw-r--r--src/exchange/taler-exchange-httpd.h6
-rw-r--r--src/exchange/taler-exchange-httpd_common_kyc.c136
-rw-r--r--src/exchange/taler-exchange-httpd_common_kyc.h2
-rw-r--r--src/exchangedb/0005-reserves_in.sql45
-rw-r--r--src/exchangedb/Makefile.am1
-rw-r--r--src/exchangedb/exchange_do_insert_kyc_attributes.sql13
-rw-r--r--src/exchangedb/pg_insert_kyc_attributes.c17
-rw-r--r--src/exchangedb/pg_insert_kyc_attributes.h14
-rw-r--r--src/exchangedb/pg_lookup_active_legitimization.c66
-rw-r--r--src/exchangedb/pg_lookup_active_legitimization.h49
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c3
-rw-r--r--src/include/taler_exchangedb_plugin.h33
-rw-r--r--src/include/taler_kyclogic_lib.h137
-rw-r--r--src/kyclogic/kyclogic_api.c76
15 files changed, 542 insertions, 89 deletions
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
index 510d36bac..a120cf47d 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -181,23 +181,11 @@ static char *toplevel_redirect_url;
char *TEH_currency;
/**
- * Name of the KYC-AML-trigger evaluation binary.
- */
-char *TEH_kyc_aml_trigger;
-
-/**
* Option set to #GNUNET_YES if rewards are enabled.
*/
int TEH_enable_rewards;
/**
- * What is the largest amount we allow a peer to
- * merge into a reserve before always triggering
- * an AML check?
- */
-struct TALER_Amount TEH_aml_threshold;
-
-/**
* Our base URL.
*/
char *TEH_base_url;
@@ -2170,17 +2158,6 @@ exchange_serve_process_config (void)
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (TEH_cfg,
"exchange",
- "KYC_AML_TRIGGER",
- &TEH_kyc_aml_trigger))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "exchange",
- "KYC_AML_TRIGGER");
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (TEH_cfg,
- "exchange",
"TOPLEVEL_REDIRECT_URL",
&toplevel_redirect_url))
{
@@ -2219,16 +2196,6 @@ exchange_serve_process_config (void)
if (GNUNET_OK !=
TALER_config_get_amount (TEH_cfg,
"exchange",
- "AML_THRESHOLD",
- &TEH_aml_threshold))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Need amount in section `exchange' under `AML_THRESHOLD'\n");
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK !=
- TALER_config_get_amount (TEH_cfg,
- "exchange",
"STEFAN_ABS",
&TEH_stefan_abs))
{
diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h
index 7740d2fac..293455af6 100644
--- a/src/exchange/taler-exchange-httpd.h
+++ b/src/exchange/taler-exchange-httpd.h
@@ -42,12 +42,6 @@ extern struct GNUNET_TIME_Relative TEH_max_keys_caching;
extern struct GNUNET_TIME_Relative TEH_reserve_closing_delay;
/**
- * Name of the KYC-AML-trigger evaluation binary.
- * FIXME: do we keep this?
- */
-extern char *TEH_kyc_aml_trigger;
-
-/**
* The exchange's configuration.
*/
extern const struct GNUNET_CONFIGURATION_Handle *TEH_cfg;
diff --git a/src/exchange/taler-exchange-httpd_common_kyc.c b/src/exchange/taler-exchange-httpd_common_kyc.c
index 141f99841..6b7b3f583 100644
--- a/src/exchange/taler-exchange-httpd_common_kyc.c
+++ b/src/exchange/taler-exchange-httpd_common_kyc.c
@@ -81,6 +81,26 @@ struct TEH_KycAmlTrigger
json_t *attributes;
/**
+ * Measures this KYC process is responding to.
+ */
+ json_t *jmeasures;
+
+ /**
+ * KYC history of the account.
+ */
+ json_t *kyc_history;
+
+ /**
+ * AML history of the account.
+ */
+ json_t *aml_history;
+
+ /**
+ * KYC measure the client is (trying to) satisfy.
+ */
+ uint32_t measure_index;
+
+ /**
* response to return to the HTTP client
*/
struct MHD_Response *response;
@@ -89,7 +109,7 @@ struct TEH_KycAmlTrigger
* Handle to an external process that evaluates the
* need to run AML on the account.
*/
- struct TALER_JSON_ExternalConversion *kyc_aml;
+ struct TALER_KYCLOGIC_AmlProgramRunnerHandle *kyc_aml;
/**
* HTTP status code of @e response
@@ -103,51 +123,55 @@ struct TEH_KycAmlTrigger
* Type of a callback that receives a JSON @a result.
*
* @param cls closure of type `struct TEH_KycAmlTrigger *`
- * @param status_type how did the process die
- * @param code termination status code from the process,
- * non-zero if AML checks are required next
- * @param result some JSON result, NULL if we failed to get an JSON output
+ * @param apr AML program result
*/
static void
kyc_aml_finished (void *cls,
- enum GNUNET_OS_ProcessStatusType status_type,
- unsigned long code,
- const json_t *result)
+ const struct TALER_KYCLOGIC_AmlProgramResult *apr)
{
struct TEH_KycAmlTrigger *kat = cls;
enum GNUNET_DB_QueryStatus qs;
size_t eas;
void *ea;
- const char *birthdate;
unsigned int birthday = 0;
struct GNUNET_AsyncScopeSave old_scope;
kat->kyc_aml = NULL;
GNUNET_async_scope_enter (&kat->scope,
&old_scope);
- birthdate = json_string_value (json_object_get (kat->attributes,
- TALER_ATTRIBUTE_BIRTHDATE));
- if ( (TEH_age_restriction_enabled) &&
- (NULL != birthdate) )
+ if (TALER_KYCLOGIC_AMLR_SUCCESS != apr->status)
{
- enum GNUNET_GenericReturnValue ret;
-
- ret = TALER_parse_coarse_date (birthdate,
- &TEH_age_restriction_config.mask,
- &birthday);
+ // FIXME ...
+ GNUNET_break (0); // not implemented!
+ }
+ {
+ const char *birthdate;
- if (GNUNET_OK != ret)
+ birthdate = json_string_value (
+ json_object_get (kat->attributes,
+ TALER_ATTRIBUTE_BIRTHDATE));
+ if ( (TEH_age_restriction_enabled) &&
+ (NULL != birthdate) )
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Failed to parse birthdate `%s' from KYC attributes\n",
- birthdate);
- if (NULL != kat->response)
- MHD_destroy_response (kat->response);
- kat->http_status = MHD_HTTP_BAD_REQUEST;
- kat->response = TALER_MHD_make_error (
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- TALER_ATTRIBUTE_BIRTHDATE);
- goto RETURN_RESULT;
+ enum GNUNET_GenericReturnValue ret;
+
+ ret = TALER_parse_coarse_date (birthdate,
+ &TEH_age_restriction_config.mask,
+ &birthday);
+
+ if (GNUNET_OK != ret)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Failed to parse birthdate `%s' from KYC attributes\n",
+ birthdate);
+ if (NULL != kat->response)
+ MHD_destroy_response (kat->response);
+ kat->http_status = MHD_HTTP_BAD_REQUEST;
+ kat->response = TALER_MHD_make_error (
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ TALER_ATTRIBUTE_BIRTHDATE);
+ goto RETURN_RESULT;
+ }
}
}
@@ -165,6 +189,11 @@ kyc_aml_finished (void *cls,
kat->provider_user_id,
kat->provider_legitimization_id,
kat->expiration,
+ apr->details.success.account_properties,
+ apr->details.success.new_rules,
+ apr->details.success.to_investigate,
+ apr->details.success.num_events,
+ apr->details.success.events,
eas,
ea,
0 != code);
@@ -209,6 +238,7 @@ TEH_kyc_finished (const struct GNUNET_AsyncScopeId *scope,
void *cb_cls)
{
struct TEH_KycAmlTrigger *kat;
+ enum GNUNET_DB_QueryStatus qs;
kat = GNUNET_new (struct TEH_KycAmlTrigger);
kat->scope = *scope;
@@ -228,14 +258,43 @@ TEH_kyc_finished (const struct GNUNET_AsyncScopeId *scope,
kat->response = response;
kat->cb = cb;
kat->cb_cls = cb_cls;
+ qs = TEH_plugin->lookup_active_legitimization (
+ TEH_plugin->cls,
+ process_row,
+ &kat->measure_index,
+ &kat->jmeasures);
+ switch (qs)
+ {
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ case GNUNET_DB_STATUS_SOFT_ERROR:
+ GNUNET_break (0);
+ TEH_kyc_finished_cancel (kat);
+ return NULL;
+ case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+ GNUNET_break (0);
+ TEH_kyc_finished_cancel (kat);
+ return NULL;
+ case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+ break;
+ }
+#if FIXME
+ qs = TEH_plugin->lookup_aml_history (
+ TEH_plugin->cls,
+ account_id,
+ &kat->aml_history,
+ &kat->kyc_history);
+#else
+ kat->aml_history = json_array ();
+ kat->kyc_history = json_array ();
+#endf
kat->kyc_aml
- = TALER_JSON_external_conversion_start (
- attributes,
- &kyc_aml_finished,
- kat,
- TEH_kyc_aml_trigger,
- TEH_kyc_aml_trigger,
- NULL);
+ = TALER_KYCLOGIC_run_aml_program (kat->attributes,
+ kat->aml_history,
+ kat->kyc_history,
+ kat->jmeasures,
+ kat->measure_index,
+ &kyc_aml_finished,
+ kat);
if (NULL == kat->kyc_aml)
{
GNUNET_break (0);
@@ -251,13 +310,16 @@ TEH_kyc_finished_cancel (struct TEH_KycAmlTrigger *kat)
{
if (NULL != kat->kyc_aml)
{
- TALER_JSON_external_conversion_stop (kat->kyc_aml);
+ TALER_KYCLOGIC_run_aml_program_cancel (kat->kyc_aml);
kat->kyc_aml = NULL;
}
GNUNET_free (kat->provider_name);
GNUNET_free (kat->provider_user_id);
GNUNET_free (kat->provider_legitimization_id);
+ json_decref (kat->jmeasures);
json_decref (kat->attributes);
+ json_decref (kat->aml_history);
+ json_decref (kat->kyc_history);
if (NULL != kat->response)
{
MHD_destroy_response (kat->response);
diff --git a/src/exchange/taler-exchange-httpd_common_kyc.h b/src/exchange/taler-exchange-httpd_common_kyc.h
index e391c8d3b..ccf94e9d6 100644
--- a/src/exchange/taler-exchange-httpd_common_kyc.h
+++ b/src/exchange/taler-exchange-httpd_common_kyc.h
@@ -59,7 +59,7 @@ struct TEH_KycAmlTrigger;
* in the database. Then call @a cb.
*
* @param scope the HTTP request logging scope
- * @param process_row legitimization process the webhook was about
+ * @param process_row legitimization process the data provided is about
* @param account_id account the webhook was about
* @param provider_name name of the provider with the logic that was run
* @param provider_user_id set to user ID at the provider, or NULL if not supported or unknown
diff --git a/src/exchangedb/0005-reserves_in.sql b/src/exchangedb/0005-reserves_in.sql
new file mode 100644
index 000000000..157e52308
--- /dev/null
+++ b/src/exchangedb/0005-reserves_in.sql
@@ -0,0 +1,45 @@
+--
+-- This file is part of TALER
+-- Copyright (C) 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/>
+--
+
+CREATE FUNCTION foreign_table_reserves_in5()
+RETURNS void
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ table_name TEXT DEFAULT 'reserves_in';
+BEGIN
+ EXECUTE FORMAT (
+ 'ALTER TABLE ' || table_name ||
+ ' ADD CONSTRAINT ' || table_name || '_wire_target_h_payto_foreign'
+ ' FOREIGN KEY (wire_source_h_payto)'
+ ' REFERENCES wire_targets (wire_target_h_payto)'
+ ' ON DELETE RESTRICT'
+ );
+END
+$$;
+
+INSERT INTO exchange_tables
+ (name
+ ,version
+ ,action
+ ,partitioned
+ ,by_range)
+ VALUES
+ ('reserves_in5'
+ ,'exchange-0005'
+ ,'foreign'
+ ,TRUE
+ ,FALSE);
diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am
index ae80a5123..e7619657e 100644
--- a/src/exchangedb/Makefile.am
+++ b/src/exchangedb/Makefile.am
@@ -171,6 +171,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \
pg_test_aml_officer.h pg_test_aml_officer.c \
pg_lookup_aml_officer.h pg_lookup_aml_officer.c \
pg_lookup_pending_legitimization.h pg_lookup_pending_legitimization.c \
+ pg_lookup_active_legitimization.h pg_lookup_active_legitimization.c \
pg_trigger_aml_process.h pg_trigger_aml_process.c \
pg_insert_aml_decision.h pg_insert_aml_decision.c \
pg_select_aggregation_transient.h pg_select_aggregation_transient.c \
diff --git a/src/exchangedb/exchange_do_insert_kyc_attributes.sql b/src/exchangedb/exchange_do_insert_kyc_attributes.sql
index 54ab51bbe..8ae2ff0c3 100644
--- a/src/exchangedb/exchange_do_insert_kyc_attributes.sql
+++ b/src/exchangedb/exchange_do_insert_kyc_attributes.sql
@@ -14,7 +14,9 @@
-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
--
-CREATE OR REPLACE FUNCTION exchange_do_insert_kyc_attributes(
+DELETE FUNCTION exchange_do_insert_kyc_attributes
+ IF EXISTS;
+CREATE FUNCTION exchange_do_insert_kyc_attributes(
IN in_process_row INT8,
IN in_h_payto BYTEA,
IN in_birthday INT4,
@@ -24,6 +26,9 @@ CREATE OR REPLACE FUNCTION exchange_do_insert_kyc_attributes(
IN in_collection_time_ts INT8,
IN in_expiration_time INT8,
IN in_expiration_time_ts INT8,
+ IN in_account_properties TEXT, -- FIXME: use!
+ IN in_new_rules TEXT, -- FIXME: use!
+ IN ina_events TEXT[], -- FIXME: use!
IN in_enc_attributes BYTEA,
IN in_require_aml BOOLEAN,
IN in_kyc_completed_notify_s TEXT,
@@ -41,12 +46,14 @@ INSERT INTO exchange.kyc_attributes
,expiration_time
,encrypted_attributes
,legitimization_serial
+ ,trigger_outcome_serial
) VALUES
(in_h_payto
,in_collection_time_ts
,in_expiration_time_ts
,in_enc_attributes
- ,in_process_row);
+ ,in_process_row
+ ,FIXME);
UPDATE legitimization_processes
SET provider_user_id=in_provider_account_id
@@ -102,5 +109,5 @@ INSERT INTO kyc_alerts
END $$;
-COMMENT ON FUNCTION exchange_do_insert_kyc_attributes(INT8, BYTEA, INT4, TEXT, TEXT, TEXT, INT8, INT8, INT8, BYTEA, BOOL, TEXT)
+COMMENT ON FUNCTION exchange_do_insert_kyc_attributes(INT8, BYTEA, INT4, TEXT, TEXT, TEXT, INT8, INT8, INT8, TEXT, TEXT, TEXT[], BYTEA, BOOL, TEXT)
IS 'Inserts new KYC attributes and updates the status of the legitimization process and the AML status for the account';
diff --git a/src/exchangedb/pg_insert_kyc_attributes.c b/src/exchangedb/pg_insert_kyc_attributes.c
index a72e4e67b..37e833863 100644
--- a/src/exchangedb/pg_insert_kyc_attributes.c
+++ b/src/exchangedb/pg_insert_kyc_attributes.c
@@ -37,9 +37,13 @@ TEH_PG_insert_kyc_attributes (
const char *provider_account_id,
const char *provider_legitimization_id,
struct GNUNET_TIME_Absolute expiration_time,
+ const json_t *account_properties,
+ const json_t *new_rules,
+ bool to_investigate,
+ unsigned int num_events,
+ const char **events,
size_t enc_attributes_size,
- const void *enc_attributes,
- bool require_aml)
+ const void *enc_attributes)
{
struct PostgresClosure *pg = cls;
struct GNUNET_TIME_Timestamp expiration
@@ -72,9 +76,14 @@ TEH_PG_insert_kyc_attributes (
GNUNET_PQ_query_param_timestamp (&collection_time),
GNUNET_PQ_query_param_absolute_time (&expiration_time),
GNUNET_PQ_query_param_timestamp (&expiration),
+ TALER_PQ_query_param_json (account_properties),
+ TALER_PQ_query_param_json (new_rules),
+ GNUNET_PQ_query_param_array_string (pg,
+ num_events,
+ events),
GNUNET_PQ_query_param_fixed_size (enc_attributes,
enc_attributes_size),
- GNUNET_PQ_query_param_bool (require_aml),
+ GNUNET_PQ_query_param_bool (to_investigate),
GNUNET_PQ_query_param_string (kyc_completed_notify_s),
GNUNET_PQ_query_param_end
};
@@ -94,7 +103,7 @@ TEH_PG_insert_kyc_attributes (
"SELECT "
" out_ok"
" FROM exchange_do_insert_kyc_attributes "
- "($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, $14, $15);");
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"insert_kyc_attributes",
params,
diff --git a/src/exchangedb/pg_insert_kyc_attributes.h b/src/exchangedb/pg_insert_kyc_attributes.h
index 09ebbf04a..e33f3a152 100644
--- a/src/exchangedb/pg_insert_kyc_attributes.h
+++ b/src/exchangedb/pg_insert_kyc_attributes.h
@@ -39,9 +39,13 @@
* @param provider_account_id provider account ID
* @param provider_legitimization_id provider legitimization ID
* @param expiration_time when does the data expire
+ * @param account_properties new account properties
+ * @param new_rules new KYC rules to apply to the account
+ * @param to_investigate true to flag account for investigation
+ * @param num_events length of the @a events array
+ * @param events array of KYC events to trigger
* @param enc_attributes_size number of bytes in @a enc_attributes
* @param enc_attributes encrypted attribute data
- * @param require_aml true to trigger AML
* @return database transaction status
*/
enum GNUNET_DB_QueryStatus
@@ -55,9 +59,13 @@ TEH_PG_insert_kyc_attributes (
const char *provider_account_id,
const char *provider_legitimization_id,
struct GNUNET_TIME_Absolute expiration_time,
+ const json_t *account_properties,
+ const json_t *new_rules,
+ bool to_investigate,
+ unsigned int num_events,
+ const char **events,
size_t enc_attributes_size,
- const void *enc_attributes,
- bool require_aml);
+ const void *enc_attributes);
#endif
diff --git a/src/exchangedb/pg_lookup_active_legitimization.c b/src/exchangedb/pg_lookup_active_legitimization.c
new file mode 100644
index 000000000..38c95fd4d
--- /dev/null
+++ b/src/exchangedb/pg_lookup_active_legitimization.c
@@ -0,0 +1,66 @@
+/*
+ This file is part of TALER
+ Copyright (C) 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_lookup_pending_legitimization.c
+ * @brief Implementation of the lookup_pending_legitimization 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_lookup_active_legitimization.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TEH_PG_lookup_active_legitimization (
+ void *cls,
+ uint64_t legitimization_process_serial_id,
+ uint32_t *measure_index,
+ json_t **jmeasures)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&legitimization_process_serial_id),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_result_spec_json (
+ "jmeasures",
+ jmeasures),
+ GNUNET_PQ_result_spec_uint32 (
+ "measure_index",
+ measure_index),
+ GNUNET_PQ_result_spec_end
+ };
+
+ PREPARE (pg,
+ "lookup_active_legitimization",
+ "SELECT "
+ " lm.jmeasures"
+ ",lp.measure_index"
+ " FROM legitimization_processes lp"
+ " JOIN legitimization_measures lm"
+ " USING (legitimization_measure_serial_id)"
+ " WHERE lp.legitimization_process_serial_id=$1"
+ " AND NOT lm.is_finished;");
+ return GNUNET_PQ_eval_prepared_singleton_select (
+ pg->conn,
+ "lookup_active_legitimization",
+ params,
+ rs);
+}
diff --git a/src/exchangedb/pg_lookup_active_legitimization.h b/src/exchangedb/pg_lookup_active_legitimization.h
new file mode 100644
index 000000000..f7bce41cb
--- /dev/null
+++ b/src/exchangedb/pg_lookup_active_legitimization.h
@@ -0,0 +1,49 @@
+/*
+ This file is part of TALER
+ Copyright (C) 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_lookup_active_legitimization.h
+ * @brief implementation of the lookup_active_legitimization function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef PG_LOOKUP_ACTIVE_LEGITIMIZATION_H
+#define PG_LOOKUP_ACTIVE_LEGITIMIZATION_H
+
+#include "taler_util.h"
+#include "taler_json_lib.h"
+#include "taler_exchangedb_plugin.h"
+
+
+/**
+ * Lookup measure data for an active legitimization process.
+ *
+ * @param cls closure
+ * @param legitimization_process_serial_id
+ * row in legitimization_processes table to access
+ * @param[out] measure_index set to the measure the
+ * process is trying to satisfy
+ * @param[out] jmeasures set to the legitimization
+ * measures that were put on the account
+ * @return database transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TEH_PG_lookup_active_legitimization (
+ void *cls,
+ uint64_t legitimization_process_serial_id,
+ uint32_t *measure_index,
+ json_t **jmeasures);
+
+
+#endif
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index c9ea6a752..3587ed2e0 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -54,6 +54,7 @@
#include "pg_lookup_kyc_status_by_token.h"
#include "pg_lookup_serial_by_table.h"
#include "pg_lookup_pending_legitimization.h"
+#include "pg_lookup_active_legitimization.h"
#include "pg_select_account_merges_above_serial_id.h"
#include "pg_select_all_purse_decisions_above_serial_id.h"
#include "pg_select_purse.h"
@@ -749,6 +750,8 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
= &TEH_PG_lookup_denomination_key;
plugin->lookup_pending_legitimization
= &TEH_PG_lookup_pending_legitimization;
+ plugin->lookup_active_legitimization
+ = &TEH_PG_lookup_active_legitimization;
plugin->insert_auditor_denom_sig
= &TEH_PG_insert_auditor_denom_sig;
plugin->select_auditor_denom_sig
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index bfd048bd9..3d49a1a6a 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -7084,6 +7084,11 @@ struct TALER_EXCHANGEDB_Plugin
* @param provider_account_id provider account ID
* @param provider_legitimization_id provider legitimization ID
* @param expiration_time when does the data expire
+ * @param account_properties new account properties
+ * @param new_rules new KYC rules to apply to the account
+ * @param to_investigate true to flag account for investigation
+ * @param num_events length of the @a events array
+ * @param events array of KYC events to trigger
* @param enc_attributes_size number of bytes in @a enc_attributes
* @param enc_attributes encrypted attribute data
* @param require_aml true to trigger AML
@@ -7100,9 +7105,13 @@ struct TALER_EXCHANGEDB_Plugin
const char *provider_account_id,
const char *provider_legitimization_id,
struct GNUNET_TIME_Absolute expiration_time,
+ const json_t *account_properties,
+ const json_t *new_rules,
+ bool to_investigate,
+ unsigned int num_events,
+ const char **events,
size_t enc_attributes_size,
- const void *enc_attributes,
- bool require_aml);
+ const void *enc_attributes);
/**
@@ -7328,6 +7337,26 @@ struct TALER_EXCHANGEDB_Plugin
/**
+ * Lookup measure data for an active legitimization process.
+ *
+ * @param cls closure
+ * @param legitimization_process_serial_id
+ * row in legitimization_processes table to access
+ * @param[out] measure_index set to the measure the
+ * process is trying to satisfy
+ * @param[out] jmeasures set to the legitimization
+ * measures that were put on the account
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_active_legitimization) (
+ void *cls,
+ uint64_t legitimization_process_serial_id,
+ uint32_t *measure_index,
+ json_t **jmeasures);
+
+
+ /**
* Insert an AML decision. Inserts into AML history and insert or updates AML
* status.
*
diff --git a/src/include/taler_kyclogic_lib.h b/src/include/taler_kyclogic_lib.h
index db62e41ee..c3145db3e 100644
--- a/src/include/taler_kyclogic_lib.h
+++ b/src/include/taler_kyclogic_lib.h
@@ -611,4 +611,141 @@ TALER_KYCLOGIC_get_measure_configuration (
json_t **pprograms,
json_t **pchecks);
+
+/**
+ * Handle to manage a running AML program.
+ */
+struct TALER_KYCLOGIC_AmlProgramRunnerHandle;
+
+
+/**
+ * Result from running an AML program.
+ */
+struct TALER_KYCLOGIC_AmlProgramResult
+{
+ /**
+ * Possible outcomes from running the AML program.
+ */
+ enum
+ {
+ /**
+ * The AML program completed successfully.
+ */
+ TALER_KYCLOGIC_AMLR_SUCCESS,
+
+ /**
+ * The AML program failed.
+ */
+ TALER_KYCLOGIC_AMLR_FAILURE
+
+ } status;
+
+ /**
+ * Detailed results depending on @e status.
+ */
+ union
+ {
+ /**
+ * Results if @e status is #TALER_KYCLOGIC_AMLR_SUCCESS.
+ */
+ struct
+ {
+ /**
+ * New account properties to set for the account.
+ */
+ const json_t *account_properties;
+
+ /**
+ * Array of events to trigger.
+ */
+ const char **events;
+
+ /**
+ * New AML/KYC rules to apply to the account.
+ */
+ const json_t *new_rules;
+
+ /**
+ * Length of the @e events array.
+ */
+ unsigned int num_events;
+
+ /**
+ * True if AML staff should investigate the account.
+ */
+ bool to_investigate;
+ } success;
+
+ /**
+ * Results if @e status is #TALER_KYCLOGIC_AMLR_FAILURE.
+ */
+ struct
+ {
+ /**
+ * Human-readable error message describing the
+ * failure (for logging).
+ */
+ const char *error_message;
+
+ /**
+ * Error code for the failure.
+ */
+ enum TALER_ErrorCode ec;
+
+ } failure;
+
+ } details;
+
+};
+
+
+/**
+ * Type of function called after AML program was run.
+ *
+ * @param cls closure
+ * @param apr result of the AML program.
+ */
+typedef void
+(*TALER_KYCLOGIC_AmlProgramResultCallback) (
+ void *cls,
+ const struct TALER_KYCLOGIC_AmlProgramResult *apr);
+
+
+/**
+ * Run AML program based on @a jmeasures using
+ * the the given inputs.
+ *
+ * @param attributes KYC attributes newly obtained
+ * @param aml_history AML history of the account
+ * @param kyc_history KYC history of the account
+ * @param jmeasures current KYC/AML rules to apply;
+ * they determine also the AML program and
+ * provide the context
+ * @param measure_index which KYC measure yielded the
+ * @a attributes
+ * @param aprc function to call with the result
+ * @param aprc_cls closure for @a aprc
+ * @return NULL if @a jmeasures is invalid for the
+ * selected @a measure_index or @a attributes
+ */
+struct TALER_KYCLOGIC_AmlProgramRunnerHandle *
+TALER_KYCLOGIC_run_aml_program (
+ const json_t *attributes,
+ const json_t *aml_history,
+ const json_t *kyc_history,
+ const json_t *jmeasures,
+ unsigned int measure_index,
+ TALER_KYCLOGIC_AmlProgramResultCallback aprc,
+ void *aprc_cls);
+
+
+/**
+ * Cancel running AML program.
+ *
+ * @param[in] aprh handle of program to cancel
+ */
+void
+TALER_KYCLOGIC_run_aml_program_cancel (
+ struct TALER_KYCLOGIC_AmlProgramRunnerHandle *aprh);
+
#endif
diff --git a/src/kyclogic/kyclogic_api.c b/src/kyclogic/kyclogic_api.c
index b698a4cbd..1c2bc13f8 100644
--- a/src/kyclogic/kyclogic_api.c
+++ b/src/kyclogic/kyclogic_api.c
@@ -2845,4 +2845,80 @@ TALER_KYCLOGIC_check_to_provider (const char *check_name)
}
+struct TALER_KYCLOGIC_AmlProgramRunnerHandle
+{
+ /**
+ * Function to call back with the result.
+ */
+ TALER_KYCLOGIC_AmlProgramResultCallback aprc;
+
+ /**
+ * Closure for @e aprc.
+ */
+ void *aprc_cls;
+
+ /**
+ * Handle to an external process.
+ */
+ struct TALER_JSON_ExternalConversion *proc;
+
+};
+
+/**
+ * Function that that receives a JSON @a result from
+ * the AML program.
+ *
+ * @param cls closure of type `struct TALER_KYCLOGIC_AmlProgramRunnerHandle`
+ * @param status_type how did the process die
+ * @param code termination status code from the process,
+ * non-zero if AML checks are required next
+ * @param result some JSON result, NULL if we failed to get an JSON output
+ */
+static void
+aml_prog_finished (void *cls,
+ enum GNUNET_OS_ProcessStatusType status_type,
+ unsigned long code,
+ const json_t *result)
+{
+ struct TALER_KYCLOGIC_AmlProgramRunnerHandle *aprh = cls;
+
+ // FIXME
+}
+
+
+struct TALER_KYCLOGIC_AmlProgramRunnerHandle *
+TALER_KYCLOGIC_run_aml_program (
+ const json_t *attributes,
+ const json_t *aml_history,
+ const json_t *kyc_history,
+ const json_t *jmeasures,
+ unsigned int measure_index,
+ TALER_KYCLOGIC_AmlProgramResultCallback aprc,
+ void *aprc_cls)
+{
+ struct TALER_KYCLOGIC_AmlProgramRunnerHandle *aprh;
+
+ aprh = GNUNET_new (struct TALER_KYCLOGIC_AmlProgramRunnerHandle);
+ aprh->aprc = aprc;
+ aprh->aprc_cls aprc_cls;
+
+ // FIXME ...
+ return arph;
+}
+
+
+void
+TALER_KYCLOGIC_run_aml_program_cancel (
+ struct TALER_KYCLOGIC_AmlProgramRunnerHandle *aprh)
+{
+
+ if (NULL != aprh->prog)
+ {
+ TALER_JSON_external_conversion_stop (aprh->prog);
+ aprh->prog = NULL;
+ }
+ GNUNET_free (aprh);
+}
+
+
/* end of kyclogic_api.c */