aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-08-05 20:51:23 +0200
committerChristian Grothoff <christian@grothoff.org>2024-08-05 20:51:44 +0200
commitd2eaf3bf7c9d6a0d86c92f2205d4a8b7969a1848 (patch)
treedb6f3ce7be73b5c18d3defa53f74b899b027ee15
parenta67d5495784b055e2fd3d7e3e7df262f40242195 (diff)
also allow kyc-proof authentication with most recent reserve_pub transfer subject key
-rw-r--r--src/exchange/taler-exchange-httpd_kyc-check.c13
-rw-r--r--src/exchangedb/exchange_do_lookup_kyc_requirement_by_row.sql96
-rw-r--r--src/exchangedb/pg_lookup_kyc_requirement_by_row.c60
-rw-r--r--src/exchangedb/pg_lookup_kyc_requirement_by_row.h5
-rw-r--r--src/exchangedb/procedures.sql.in1
-rw-r--r--src/include/taler_exchangedb_plugin.h5
6 files changed, 151 insertions, 29 deletions
diff --git a/src/exchange/taler-exchange-httpd_kyc-check.c b/src/exchange/taler-exchange-httpd_kyc-check.c
index d321e357a..9481ea002 100644
--- a/src/exchange/taler-exchange-httpd_kyc-check.c
+++ b/src/exchange/taler-exchange-httpd_kyc-check.c
@@ -187,6 +187,7 @@ TEH_handler_kyc_check (
json_t *jrules = NULL;
json_t *jlimits = NULL;
union TALER_AccountPublicKeyP account_pub;
+ union TALER_AccountPublicKeyP reserve_pub;
struct TALER_AccountAccessTokenP access_token;
bool aml_review;
bool kyc_required;
@@ -251,6 +252,7 @@ TEH_handler_kyc_check (
TEH_plugin->cls,
kyp->requirement_row,
&account_pub,
+ &reserve_pub.reserve_pub,
&access_token,
&jrules,
&aml_review,
@@ -274,9 +276,14 @@ TEH_handler_kyc_check (
}
}
- if (GNUNET_OK !=
- TALER_account_kyc_auth_verify (&account_pub,
- &kyp->account_sig))
+ if ( (GNUNET_is_zero (&account_pub) ||
+ (GNUNET_OK !=
+ TALER_account_kyc_auth_verify (&account_pub,
+ &kyp->account_sig)) ) &&
+ (GNUNET_is_zero (&reserve_pub) ||
+ (GNUNET_OK !=
+ TALER_account_kyc_auth_verify (&reserve_pub,
+ &kyp->account_sig)) ) )
{
char *diag;
MHD_RESULT mret;
diff --git a/src/exchangedb/exchange_do_lookup_kyc_requirement_by_row.sql b/src/exchangedb/exchange_do_lookup_kyc_requirement_by_row.sql
new file mode 100644
index 000000000..9c7f8f081
--- /dev/null
+++ b/src/exchangedb/exchange_do_lookup_kyc_requirement_by_row.sql
@@ -0,0 +1,96 @@
+--
+-- 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/>
+--
+-- @author: Christian Grothoff
+
+CREATE OR REPLACE FUNCTION exchange_do_lookup_kyc_requirement_by_row(
+ IN in_legitimization_serial_id INT8,
+ OUT out_account_pub BYTEA, -- NULL allowed
+ OUT out_reserve_pub BYTEA, -- NULL allowed
+ OUT out_access_token BYTEA, -- NULL if 'out_not_found'
+ OUT out_jrules TEXT, -- NULL allowed
+ OUT out_not_found BOOLEAN,
+ OUT out_aml_review BOOLEAN, -- NULL allowed
+ OUT out_kyc_required BOOLEAN)
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ my_h_payto BYTEA;
+ my_wtrec RECORD;
+ my_lorec RECORD;
+BEGIN
+
+-- Find the access token.
+SELECT access_token
+ INTO out_access_token
+ FROM legitimization_measures
+ WHERE legitimization_measure_serial_id=in_legitimization_serial_id;
+
+IF NOT FOUND
+THEN
+ out_not_found = TRUE;
+ out_kyc_required = FALSE;
+ RETURN;
+END IF;
+out_not_found = FALSE;
+
+-- Find the payto hash and the current account public key.
+SELECT target_pub
+ ,wire_target_h_payto
+ INTO my_wtrec
+ FROM wire_targets
+ WHERE access_token=out_access_token;
+
+out_account_pub = my_wtrec.target_pub;
+my_h_payto = my_wtrec.wire_target_h_payto;
+
+-- Check if there are active measures for the account.
+SELECT NOT is_finished
+ INTO out_kyc_required
+ FROM legitimization_measures
+ WHERE access_token=out_access_token
+ ORDER BY start_time DESC
+ LIMIT 1;
+
+IF NOT FOUND
+THEN
+ out_kyc_required=TRUE;
+END IF;
+
+-- Get currently applicable rules.
+-- Only one should ever be active per account.
+SELECT jnew_rules
+ ,to_investigate
+ INTO my_lorec
+ FROM legitimization_outcomes
+ WHERE h_payto=my_h_payto
+ AND is_active;
+
+IF FOUND
+THEN
+ out_jrules=my_lorec.jnew_rules;
+ out_aml_review=my_lorec.to_investigate;
+END IF;
+
+-- Get most recent reserve_in wire transfer, we also
+-- allow that one for authentication!
+SELECT reserve_pub
+ INTO out_reserve_pub
+ FROM reserves_in
+ WHERE wire_source_h_payto=my_h_payto
+ ORDER BY execution_date DESC
+ LIMIT 1;
+
+END $$;
diff --git a/src/exchangedb/pg_lookup_kyc_requirement_by_row.c b/src/exchangedb/pg_lookup_kyc_requirement_by_row.c
index 0079bf43b..e4a5ecbca 100644
--- a/src/exchangedb/pg_lookup_kyc_requirement_by_row.c
+++ b/src/exchangedb/pg_lookup_kyc_requirement_by_row.c
@@ -31,6 +31,7 @@ TEH_PG_lookup_kyc_requirement_by_row (
void *cls,
uint64_t requirement_row,
union TALER_AccountPublicKeyP *account_pub,
+ struct TALER_ReservePublicKeyP *reserve_pub,
struct TALER_AccountAccessTokenP *access_token,
json_t **jrules,
bool *aml_review,
@@ -41,13 +42,20 @@ TEH_PG_lookup_kyc_requirement_by_row (
GNUNET_PQ_query_param_uint64 (&requirement_row),
GNUNET_PQ_query_param_end
};
+ bool not_found;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_auto_from_type ("account_pub",
account_pub),
NULL),
- GNUNET_PQ_result_spec_auto_from_type ("access_token",
- access_token),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+ reserve_pub),
+ NULL),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_auto_from_type ("access_token",
+ access_token),
+ NULL),
GNUNET_PQ_result_spec_allow_null (
/* can be NULL due to LEFT JOIN */
TALER_PQ_result_spec_json ("jrules",
@@ -60,43 +68,43 @@ TEH_PG_lookup_kyc_requirement_by_row (
NULL),
GNUNET_PQ_result_spec_bool ("kyc_required",
kyc_required),
+ GNUNET_PQ_result_spec_bool ("not_found",
+ &not_found),
GNUNET_PQ_result_spec_end
};
+ enum GNUNET_DB_QueryStatus qs;
*jrules = NULL;
*aml_review = false;
memset (account_pub,
0,
sizeof (*account_pub));
+ memset (reserve_pub,
+ 0,
+ sizeof (*reserve_pub));
+ memset (access_token,
+ 0,
+ sizeof (*access_token));
PREPARE (pg,
"lookup_kyc_requirement_by_row",
"SELECT "
- " wt.target_pub AS account_pub"
- ",lm.access_token"
- ",lo.jnew_rules AS jrules"
- ",lo.to_investigate AS aml_review"
- ",NOT COALESCE(lm2.is_finished,TRUE)"
- " AS kyc_required"
- " FROM legitimization_measures lm"
- " JOIN wire_targets wt"
- " ON (lm.access_token = wt.access_token)"
- /* Select *unfinished* and more recent lm2
- for the same account - if one exists */
- " LEFT JOIN legitimization_measures lm2"
- " ON ( (lm.access_token = lm2.access_token)"
- " AND (lm2.start_time >= lm.start_time)"
- " AND NOT lm2.is_finished)"
- " LEFT JOIN legitimization_outcomes lo"
- " ON (wt.wire_target_h_payto = lo.h_payto)"
- " WHERE lm.legitimization_measure_serial_id=$1"
- /* Select the *currently active* lo, if any */
- " AND ( (lo.is_active IS NULL)"
- " OR lo.is_active)"
- " ORDER BY lo.is_active DESC NULLS LAST"
- " LIMIT 1;");
- return GNUNET_PQ_eval_prepared_singleton_select (
+ " out_account_pub AS account_pub"
+ ",out_reserve_pub AS reserve_pub"
+ ",out_access_token AS access_token"
+ ",out_jrules AS jrules"
+ ",out_not_found AS not_found"
+ ",out_aml_review AS aml_review"
+ ",out_kyc_required AS kyc_required"
+ " FROM exchange_do_lookup_kyc_requirement_by_row"
+ " ($1);");
+ qs = GNUNET_PQ_eval_prepared_singleton_select (
pg->conn,
"lookup_kyc_requirement_by_row",
params,
rs);
+ if (qs <= 0)
+ return qs;
+ if (not_found)
+ return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+ return qs;
}
diff --git a/src/exchangedb/pg_lookup_kyc_requirement_by_row.h b/src/exchangedb/pg_lookup_kyc_requirement_by_row.h
index e3cceebbd..05bab2e54 100644
--- a/src/exchangedb/pg_lookup_kyc_requirement_by_row.h
+++ b/src/exchangedb/pg_lookup_kyc_requirement_by_row.h
@@ -33,6 +33,10 @@
* @param requirement_row identifies requirement to look up (in legitimization_measures table)
* @param[out] account_pub set to public key of the account
* needed to authorize access, all zeros if not known
+ * @param[out] reserve_pub set to last reserve public key
+ * used for a wire transfer from the account to the
+ * exchange; alternatively used to authorize access,
+ * all zeros if not known
* @param[out] access_token set to the access token to begin
* work on KYC processes for this account
* @param[out] jrules set to active ``LegitimizationRuleSet``
@@ -48,6 +52,7 @@ TEH_PG_lookup_kyc_requirement_by_row (
void *cls,
uint64_t requirement_row,
union TALER_AccountPublicKeyP *account_pub,
+ struct TALER_ReservePublicKeyP *reserve_pub,
struct TALER_AccountAccessTokenP *access_token,
json_t **jrules,
bool *aml_review,
diff --git a/src/exchangedb/procedures.sql.in b/src/exchangedb/procedures.sql.in
index 1c8f05b24..a92ae77d6 100644
--- a/src/exchangedb/procedures.sql.in
+++ b/src/exchangedb/procedures.sql.in
@@ -51,5 +51,6 @@ SET search_path TO exchange;
#include "exchange_do_batch_coin_known.sql"
#include "exchange_do_kycauth_in_insert.sql"
#include "exchange_do_trigger_kyc_rule_for_account.sql"
+#include "exchange_do_lookup_kyc_requirement_by_row.sql"
COMMIT;
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 21b6a0e21..aa0339d0b 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -6978,6 +6978,10 @@ struct TALER_EXCHANGEDB_Plugin
* @param requirement_row identifies requirement to look up (in legitimization_measures table)
* @param[out] account_pub set to public key of the account
* needed to authorize access, all zeros if not known
+ * @param[out] reserve_pub set to last reserve public key
+ * used for a wire transfer from the account to the
+ * exchange; alternatively used to authorize access,
+ * all zeros if not known
* @param[out] access_token set to the access token to begin
* work on KYC processes for this account
* @param[out] jrules set to active ``LegitimizationRuleSet``
@@ -6993,6 +6997,7 @@ struct TALER_EXCHANGEDB_Plugin
void *cls,
uint64_t requirement_row,
union TALER_AccountPublicKeyP *account_pub,
+ struct TALER_ReservePublicKeyP *reserve_pub,
struct TALER_AccountAccessTokenP *access_token,
json_t **jrules,
bool *aml_review,