gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated: more towards actually allowing A


From: gnunet
Subject: [taler-exchange] branch master updated: more towards actually allowing AML decisions to trigger KYC
Date: Fri, 17 Feb 2023 18:24:23 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new aa5e7d2a more towards actually allowing AML decisions to trigger KYC
aa5e7d2a is described below

commit aa5e7d2ad5e712434f32ab41b63d53bb897c6105
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Fri Feb 17 18:24:20 2023 +0100

    more towards actually allowing AML decisions to trigger KYC
---
 src/exchange/taler-exchange-httpd_aml-decision.c   | 85 ++++++++++++++++++++--
 src/exchange/taler-exchange-httpd_batch-withdraw.c | 15 +++-
 src/exchange/taler-exchange-httpd_kyc-check.c      | 13 +++-
 src/exchange/taler-exchange-httpd_kyc-wallet.c     |  2 +-
 src/exchangedb/0003-aml_history.sql                |  7 ++
 src/exchangedb/exchange_do_insert_aml_decision.sql |  5 +-
 src/exchangedb/pg_insert_aml_decision.c            |  4 +-
 src/exchangedb/pg_insert_aml_decision.h            |  2 +
 src/include/taler_exchangedb_plugin.h              |  3 +
 src/include/taler_kyclogic_lib.h                   |  5 +-
 src/kyclogic/kyclogic_api.c                        | 31 +++++++-
 11 files changed, 157 insertions(+), 15 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_aml-decision.c 
b/src/exchange/taler-exchange-httpd_aml-decision.c
index 0fd58b9e..2830e54e 100644
--- a/src/exchange/taler-exchange-httpd_aml-decision.c
+++ b/src/exchange/taler-exchange-httpd_aml-decision.c
@@ -103,6 +103,85 @@ make_aml_decision (void *cls,
   enum GNUNET_DB_QueryStatus qs;
   struct GNUNET_TIME_Timestamp last_date;
   bool invalid_officer;
+  uint64_t requirement_row = 0;
+
+  if ( (NULL != dc->kyc_requirements) &&
+       (0 != json_array_size (dc->kyc_requirements)) )
+  {
+    char *res = NULL;
+    size_t idx;
+    json_t *req;
+    bool satisfied;
+
+    json_array_foreach (dc->kyc_requirements, idx, req)
+    {
+      const char *r = json_string_value (req);
+
+      if (NULL == res)
+      {
+        res = GNUNET_strdup (r);
+      }
+      else
+      {
+        char *tmp;
+
+        GNUNET_asprintf (&tmp,
+                         "%s %s",
+                         res,
+                         r);
+        GNUNET_free (res);
+        res = tmp;
+      }
+    }
+
+    {
+      json_t *kyc_details = NULL;
+
+      qs = TALER_KYCLOGIC_check_satisfied (
+        &res,
+        &dc->h_payto,
+        &kyc_details,
+        TEH_plugin->select_satisfied_kyc_processes,
+        TEH_plugin->cls,
+        &satisfied);
+      json_decref (kyc_details);
+    }
+    if (qs < 0)
+    {
+      if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
+      {
+        GNUNET_break (0);
+        *mhd_ret = TALER_MHD_reply_with_error (connection,
+                                               MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                               
TALER_EC_GENERIC_DB_FETCH_FAILED,
+                                               
"select_satisfied_kyc_processes");
+        return GNUNET_DB_STATUS_HARD_ERROR;
+      }
+      return qs;
+    }
+    if (! satisfied)
+    {
+      qs = TEH_plugin->insert_kyc_requirement_for_account (
+        TEH_plugin->cls,
+        res,
+        &dc->h_payto,
+        &requirement_row);
+      if (qs < 0)
+      {
+        if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
+        {
+          GNUNET_break (0);
+          *mhd_ret = TALER_MHD_reply_with_error (connection,
+                                                 
MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                                 
TALER_EC_GENERIC_DB_STORE_FAILED,
+                                                 
"insert_kyc_requirement_for_account");
+          return GNUNET_DB_STATUS_HARD_ERROR;
+        }
+        return qs;
+      }
+    }
+    GNUNET_free (res);
+  }
 
   qs = TEH_plugin->insert_aml_decision (TEH_plugin->cls,
                                         &dc->h_payto,
@@ -111,6 +190,7 @@ make_aml_decision (void *cls,
                                         dc->decision_time,
                                         dc->justification,
                                         dc->kyc_requirements,
+                                        requirement_row,
                                         dc->officer_pub,
                                         &dc->officer_sig,
                                         &invalid_officer,
@@ -151,11 +231,6 @@ make_aml_decision (void *cls,
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
 
-  if (NULL != dc->kyc_requirements)
-  {
-    // FIXME: act on these!
-  }
-
   return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
 }
 
diff --git a/src/exchange/taler-exchange-httpd_batch-withdraw.c 
b/src/exchange/taler-exchange-httpd_batch-withdraw.c
index e6be54a5..493a2bc7 100644
--- a/src/exchange/taler-exchange-httpd_batch-withdraw.c
+++ b/src/exchange/taler-exchange-httpd_batch-withdraw.c
@@ -210,7 +210,7 @@ batch_withdraw_transaction (void *cls,
   enum GNUNET_DB_QueryStatus qs;
   bool balance_ok = false;
   bool found = false;
-  const char *kyc_required;
+  char *kyc_required;
   struct TALER_PaytoHashP reserve_h_payto;
 
   wc->now = GNUNET_TIME_timestamp_get ();
@@ -349,11 +349,22 @@ batch_withdraw_transaction (void *cls,
   {
     /* insert KYC requirement into DB! */
     wc->kyc.ok = false;
-    return TEH_plugin->insert_kyc_requirement_for_account (
+    qs = TEH_plugin->insert_kyc_requirement_for_account (
       TEH_plugin->cls,
       kyc_required,
       &wc->h_payto,
       &wc->kyc.requirement_row);
+    GNUNET_free (kyc_required);
+    if (qs < 0)
+    {
+      GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+      if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+        *mhd_ret = TALER_MHD_reply_with_error (connection,
+                                               MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                               
TALER_EC_GENERIC_DB_STORE_FAILED,
+                                               
"insert_kyc_requirement_for_account");
+    }
+    return qs;
   }
   wc->kyc.ok = true;
   qs = TEH_plugin->do_batch_withdraw (TEH_plugin->cls,
diff --git a/src/exchange/taler-exchange-httpd_kyc-check.c 
b/src/exchange/taler-exchange-httpd_kyc-check.c
index 07b8dc66..57ac8389 100644
--- a/src/exchange/taler-exchange-httpd_kyc-check.c
+++ b/src/exchange/taler-exchange-httpd_kyc-check.c
@@ -332,7 +332,7 @@ kyc_check (void *cls,
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
   qs = TALER_KYCLOGIC_check_satisfied (
-    requirements,
+    &requirements,
     &h_payto,
     &kyp->kyc_details,
     TEH_plugin->select_satisfied_kyc_processes,
@@ -389,6 +389,17 @@ kyc_check (void *cls,
     NULL,
     NULL,
     &kyp->process_row);
+  if (qs < 0)
+  {
+    if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+      return qs;
+    GNUNET_break (0);
+    *mhd_ret = TALER_MHD_reply_with_error (connection,
+                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                           TALER_EC_GENERIC_DB_STORE_FAILED,
+                                           "insert_kyc_requirement_process");
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Initiating KYC check with logic %s\n",
               kyp->ih_logic->name);
diff --git a/src/exchange/taler-exchange-httpd_kyc-wallet.c 
b/src/exchange/taler-exchange-httpd_kyc-wallet.c
index e56204ef..77f2dea7 100644
--- a/src/exchange/taler-exchange-httpd_kyc-wallet.c
+++ b/src/exchange/taler-exchange-httpd_kyc-wallet.c
@@ -237,7 +237,7 @@ TEH_handler_kyc_wallet (
       NULL,
       0);
   }
-  GNUNET_free (kyc.required);
+  GNUNET_free (krc.required);
   return TEH_RESPONSE_reply_kyc_required (rc->connection,
                                           &krc.h_payto,
                                           &krc.kyc);
diff --git a/src/exchangedb/0003-aml_history.sql 
b/src/exchangedb/0003-aml_history.sql
index b411a6fb..e57a2313 100644
--- a/src/exchangedb/0003-aml_history.sql
+++ b/src/exchangedb/0003-aml_history.sql
@@ -33,6 +33,7 @@ BEGIN
       ',decision_time INT8 NOT NULL DEFAULT(0)'
       ',justification VARCHAR NOT NULL'
       ',kyc_requirements VARCHAR'
+      ',kyc_req_row INT8 NOT NULL DEFAULT(0)'
       ',decider_pub BYTEA CHECK (LENGTH(decider_pub)=32)'
       ',decider_sig BYTEA CHECK (LENGTH(decider_sig)=64)'
     ') %s ;'
@@ -87,6 +88,12 @@ BEGIN
     ,table_name
     ,partition_suffix
   );
+  PERFORM comment_partitioned_column(
+     'Row in the KYC table for this KYC requirement, 0 for none.'
+    ,'kyc_req_row'
+    ,table_name
+    ,partition_suffix
+  );
   PERFORM comment_partitioned_column(
      'Signature key of the staff member affirming the AML decision; of type 
AML_DECISION'
     ,'decider_sig'
diff --git a/src/exchangedb/exchange_do_insert_aml_decision.sql 
b/src/exchangedb/exchange_do_insert_aml_decision.sql
index 8e22c57f..00f80375 100644
--- a/src/exchangedb/exchange_do_insert_aml_decision.sql
+++ b/src/exchangedb/exchange_do_insert_aml_decision.sql
@@ -25,6 +25,7 @@ CREATE OR REPLACE FUNCTION exchange_do_insert_aml_decision(
   IN in_decider_sig BYTEA,
   IN in_notify_s VARCHAR,
   IN in_kyc_requirements VARCHAR,
+  IN in_requirement_row INT8,
   OUT out_invalid_officer BOOLEAN,
   OUT out_last_date INT8)
 LANGUAGE plpgsql
@@ -86,6 +87,7 @@ INSERT INTO exchange.aml_history
   ,decision_time
   ,justification
   ,kyc_requirements
+  ,kyc_req_row
   ,decider_pub
   ,decider_sig
   ) VALUES
@@ -96,6 +98,7 @@ INSERT INTO exchange.aml_history
   ,in_decision_time
   ,in_justification
   ,in_kyc_requirements
+  ,in_requirement_row
   ,in_decider_pub
   ,in_decider_sig);
 
@@ -119,5 +122,5 @@ END IF;
 END $$;
 
 
-COMMENT ON FUNCTION exchange_do_insert_aml_decision(BYTEA, INT8, INT4, INT4, 
INT8, VARCHAR, BYTEA, BYTEA, VARCHAR, VARCHAR)
+COMMENT ON FUNCTION exchange_do_insert_aml_decision(BYTEA, INT8, INT4, INT4, 
INT8, VARCHAR, BYTEA, BYTEA, VARCHAR, VARCHAR, INT8)
   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/pg_insert_aml_decision.c 
b/src/exchangedb/pg_insert_aml_decision.c
index 5a1b7123..62645c2a 100644
--- a/src/exchangedb/pg_insert_aml_decision.c
+++ b/src/exchangedb/pg_insert_aml_decision.c
@@ -36,6 +36,7 @@ TEH_PG_insert_aml_decision (
   struct GNUNET_TIME_Timestamp decision_time,
   const char *justification,
   const json_t *kyc_requirements,
+  uint64_t requirements_row,
   const struct TALER_AmlOfficerPublicKeyP *decider_pub,
   const struct TALER_AmlOfficerSignatureP *decider_sig,
   bool *invalid_officer,
@@ -64,6 +65,7 @@ TEH_PG_insert_aml_decision (
     NULL != kyc_requirements
     ? GNUNET_PQ_query_param_string (kyc_s)
     : GNUNET_PQ_query_param_null (),
+    GNUNET_PQ_query_param_uint64 (&requirements_row),
     GNUNET_PQ_query_param_end
   };
   struct GNUNET_PQ_ResultSpec rs[] = {
@@ -81,7 +83,7 @@ TEH_PG_insert_aml_decision (
            " out_invalid_officer"
            ",out_last_date"
            " FROM exchange_do_insert_aml_decision"
-           "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);");
+           "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);");
   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
index 4d4ca6e5..073a2f50 100644
--- a/src/exchangedb/pg_insert_aml_decision.h
+++ b/src/exchangedb/pg_insert_aml_decision.h
@@ -37,6 +37,7 @@
  * @param decision_time when was the decision made
  * @param justification human-readable text justifying the decision
  * @param kyc_requirements JSON array with KYC requirements
+ * @param requirements_row row in the KYC table for this process, 0 for none
  * @param decider_pub public key of the staff member
  * @param decider_sig signature of the staff member
  * @param[out] invalid_officer set to TRUE if @a decider_pub is not allowed to 
make decisions right now
@@ -53,6 +54,7 @@ TEH_PG_insert_aml_decision (
   struct GNUNET_TIME_Timestamp decision_time,
   const char *justification,
   const json_t *kyc_requirements,
+  uint64_t requirements_row,
   const struct TALER_AmlOfficerPublicKeyP *decider_pub,
   const struct TALER_AmlOfficerSignatureP *decider_sig,
   bool *invalid_officer,
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index f4397e29..44dd912f 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -6689,6 +6689,8 @@ struct TALER_EXCHANGEDB_Plugin
    * @param new_status AML decision status
    * @param decision_time when was the decision made
    * @param justification human-readable text justifying the decision
+   * @param kyc_requirements specific KYC requiremnts being imposed
+   * @param requirements_row row in the KYC table for this process, 0 for none
    * @param decider_pub public key of the staff member
    * @param decider_sig signature of the staff member
    * @param[out] invalid_officer set to TRUE if @a decider_pub is not allowed 
to make decisions right now
@@ -6705,6 +6707,7 @@ struct TALER_EXCHANGEDB_Plugin
     struct GNUNET_TIME_Timestamp decision_time,
     const char *justification,
     const json_t *kyc_requirements,
+    uint64_t requirements_row,
     const struct TALER_AmlOfficerPublicKeyP *decider_pub,
     const struct TALER_AmlOfficerSignatureP *decider_sig,
     bool *invalid_officer,
diff --git a/src/include/taler_kyclogic_lib.h b/src/include/taler_kyclogic_lib.h
index 98233b35..34a42912 100644
--- a/src/include/taler_kyclogic_lib.h
+++ b/src/include/taler_kyclogic_lib.h
@@ -232,7 +232,8 @@ TALER_KYCLOGIC_kyc_test_required (enum 
TALER_KYCLOGIC_KycTriggerEvent event,
  * Check if the @a requirements are now satsified for
  * @a h_payto account.
  *
- * @param requirements space-spearated list of requirements
+ * @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
@@ -242,7 +243,7 @@ TALER_KYCLOGIC_kyc_test_required (enum 
TALER_KYCLOGIC_KycTriggerEvent event,
  * @return transaction status (from @a ki)
  */
 enum GNUNET_DB_QueryStatus
-TALER_KYCLOGIC_check_satisfied (const char *requirements,
+TALER_KYCLOGIC_check_satisfied (char **requirements,
                                 const struct TALER_PaytoHashP *h_payto,
                                 json_t **kyc_details,
                                 TALER_KYCLOGIC_KycSatisfiedIterator ki,
diff --git a/src/kyclogic/kyclogic_api.c b/src/kyclogic/kyclogic_api.c
index e1aff020..9f35743c 100644
--- a/src/kyclogic/kyclogic_api.c
+++ b/src/kyclogic/kyclogic_api.c
@@ -1228,7 +1228,7 @@ TALER_KYCLOGIC_kyc_get_details (
 
 
 enum GNUNET_DB_QueryStatus
-TALER_KYCLOGIC_check_satisfied (const char *requirements,
+TALER_KYCLOGIC_check_satisfied (char **requirements,
                                 const struct TALER_PaytoHashP *h_payto,
                                 json_t **kyc_details,
                                 TALER_KYCLOGIC_KycSatisfiedIterator ki,
@@ -1244,13 +1244,14 @@ TALER_KYCLOGIC_check_satisfied (const char 
*requirements,
     return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
   }
   {
-    char *req = GNUNET_strdup (requirements);
+    char *req = *requirements;
 
     for (const char *tok = strtok (req, " ");
          NULL != tok;
          tok = strtok (NULL, " "))
       needed[needed_cnt++] = add_check (tok);
     GNUNET_free (req);
+    *requirements = NULL;
   }
 
   {
@@ -1286,6 +1287,32 @@ TALER_KYCLOGIC_check_satisfied (const char *requirements,
     }
   }
   *satisfied = (0 == needed_cnt);
+
+  {
+    char *res = NULL;
+
+    for (unsigned int i = 0; i<needed_cnt; i++)
+    {
+      const struct TALER_KYCLOGIC_KycCheck *need = needed[i];
+
+      if (NULL == res)
+      {
+        res = GNUNET_strdup (need->name);
+      }
+      else
+      {
+        char *tmp;
+
+        GNUNET_asprintf (&tmp,
+                         "%s %s",
+                         res,
+                         need->name);
+        GNUNET_free (res);
+        res = tmp;
+      }
+    }
+    *requirements = res;
+  }
   return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
 }
 

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]