gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: begin API change to allow AML of


From: gnunet
Subject: [taler-exchange] branch master updated: begin API change to allow AML officers to trigger KYC process
Date: Tue, 14 Feb 2023 14:26:04 +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 afe3f70d begin API change to allow AML officers to trigger KYC process
afe3f70d is described below

commit afe3f70d336e151598e02ebedb6498e13122530e
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Tue Feb 14 14:26:00 2023 +0100

    begin API change to allow AML officers to trigger KYC process
---
 src/exchange/taler-exchange-httpd_aml-decision.c   | 14 ++++++++++++++
 src/exchangedb/0003-aml_history.sql                |  8 +++++++-
 src/exchangedb/exchange_do_insert_aml_decision.sql |  7 +++++--
 src/exchangedb/pg_insert_aml_decision.c            | 11 ++++++++++-
 src/exchangedb/pg_insert_aml_decision.h            |  2 ++
 src/include/taler_crypto_lib.h                     |  6 ++++++
 src/include/taler_exchange_service.h               |  2 ++
 src/include/taler_exchangedb_plugin.h              |  1 +
 src/include/taler_testing_lib.h                    |  2 ++
 src/lib/exchange_api_add_aml_decision.c            |  5 +++++
 src/testing/test_kyc_api.c                         |  3 +++
 src/testing/testing_api_cmd_take_aml_decision.c    | 19 +++++++++++++++++++
 src/util/aml_signatures.c                          | 14 ++++++++++++++
 13 files changed, 90 insertions(+), 4 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_aml-decision.c 
b/src/exchange/taler-exchange-httpd_aml-decision.c
index 56935df5..0f586279 100644
--- a/src/exchange/taler-exchange-httpd_aml-decision.c
+++ b/src/exchange/taler-exchange-httpd_aml-decision.c
@@ -50,6 +50,7 @@ TEH_handler_post_aml_decision (
   uint32_t new_state32;
   enum TALER_AmlDecisionState new_state;
   struct TALER_AmlOfficerSignatureP officer_sig;
+  json_t *kyc_requirements = NULL;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_fixed_auto ("officer_sig",
                                  &officer_sig),
@@ -64,6 +65,10 @@ TEH_handler_post_aml_decision (
                                 &decision_time),
     GNUNET_JSON_spec_uint32 ("new_state",
                              &new_state32),
+    GNUNET_JSON_spec_mark_optional (
+      GNUNET_JSON_spec_json ("kyc_requirements",
+                             &kyc_requirements),
+      NULL),
     GNUNET_JSON_spec_end ()
   };
 
@@ -89,6 +94,7 @@ TEH_handler_post_aml_decision (
                                          &new_threshold,
                                          &h_payto,
                                          new_state,
+                                         kyc_requirements,
                                          officer_pub,
                                          &officer_sig))
   {
@@ -99,6 +105,8 @@ TEH_handler_post_aml_decision (
       TALER_EC_EXCHANGE_AML_DECISION_ADD_SIGNATURE_INVALID,
       NULL);
   }
+
+  // FIXME: check kyc_requirements is well-formed!
   {
     enum GNUNET_DB_QueryStatus qs;
     struct GNUNET_TIME_Timestamp last_date;
@@ -112,6 +120,7 @@ TEH_handler_post_aml_decision (
                                             new_state,
                                             decision_time,
                                             justification,
+                                            kyc_requirements,
                                             officer_pub,
                                             &officer_sig,
                                             &invalid_officer,
@@ -127,6 +136,11 @@ TEH_handler_post_aml_decision (
                                          TALER_EC_GENERIC_DB_STORE_FAILED,
                                          "add aml_decision");
     }
+    if (NULL != kyc_requirements)
+    {
+      // FIXME: act on these!
+    }
+
     if (invalid_officer)
     {
       GNUNET_break_op (0);
diff --git a/src/exchangedb/0003-aml_history.sql 
b/src/exchangedb/0003-aml_history.sql
index 36c0b386..b411a6fb 100644
--- a/src/exchangedb/0003-aml_history.sql
+++ b/src/exchangedb/0003-aml_history.sql
@@ -32,6 +32,7 @@ BEGIN
       ',new_status INT4 NOT NULL DEFAULT(0)'
       ',decision_time INT8 NOT NULL DEFAULT(0)'
       ',justification VARCHAR NOT NULL'
+      ',kyc_requirements VARCHAR'
       ',decider_pub BYTEA CHECK (LENGTH(decider_pub)=32)'
       ',decider_sig BYTEA CHECK (LENGTH(decider_sig)=64)'
     ') %s ;'
@@ -80,6 +81,12 @@ BEGIN
     ,table_name
     ,partition_suffix
   );
+  PERFORM comment_partitioned_column(
+     'Additional KYC requirements imposed by the AML staff member. Serialized 
JSON array of strings.'
+    ,'kyc_requirements'
+    ,table_name
+    ,partition_suffix
+  );
   PERFORM comment_partitioned_column(
      'Signature key of the staff member affirming the AML decision; of type 
AML_DECISION'
     ,'decider_sig'
@@ -114,7 +121,6 @@ BEGIN
   );
 END $$;
 
--- FIXME: also have INSERT on AML decisions to update AML status!
 
 INSERT INTO exchange_tables
     (name
diff --git a/src/exchangedb/exchange_do_insert_aml_decision.sql 
b/src/exchangedb/exchange_do_insert_aml_decision.sql
index 0009ecb4..8e22c57f 100644
--- a/src/exchangedb/exchange_do_insert_aml_decision.sql
+++ b/src/exchangedb/exchange_do_insert_aml_decision.sql
@@ -24,6 +24,7 @@ CREATE OR REPLACE FUNCTION exchange_do_insert_aml_decision(
   IN in_decider_pub BYTEA,
   IN in_decider_sig BYTEA,
   IN in_notify_s VARCHAR,
+  IN in_kyc_requirements VARCHAR,
   OUT out_invalid_officer BOOLEAN,
   OUT out_last_date INT8)
 LANGUAGE plpgsql
@@ -84,6 +85,7 @@ INSERT INTO exchange.aml_history
   ,new_status
   ,decision_time
   ,justification
+  ,kyc_requirements
   ,decider_pub
   ,decider_sig
   ) VALUES
@@ -93,6 +95,7 @@ INSERT INTO exchange.aml_history
   ,in_new_status
   ,in_decision_time
   ,in_justification
+  ,in_kyc_requirements
   ,in_decider_pub
   ,in_decider_sig);
 
@@ -105,7 +108,7 @@ THEN
     ,trigger_type)
     VALUES
     (in_h_payto,1);
-    
+
    EXECUTE FORMAT (
      'NOTIFY %s'
     ,in_notify_s);
@@ -116,5 +119,5 @@ END IF;
 END $$;
 
 
-COMMENT ON FUNCTION exchange_do_insert_aml_decision(BYTEA, INT8, INT4, INT4, 
INT8, VARCHAR, BYTEA, BYTEA, VARCHAR)
+COMMENT ON FUNCTION exchange_do_insert_aml_decision(BYTEA, INT8, INT4, INT4, 
INT8, VARCHAR, BYTEA, BYTEA, VARCHAR, VARCHAR)
   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 7bdd0f57..5a1b7123 100644
--- a/src/exchangedb/pg_insert_aml_decision.c
+++ b/src/exchangedb/pg_insert_aml_decision.c
@@ -35,6 +35,7 @@ TEH_PG_insert_aml_decision (
   enum TALER_AmlDecisionState new_status,
   struct GNUNET_TIME_Timestamp decision_time,
   const char *justification,
+  const json_t *kyc_requirements,
   const struct TALER_AmlOfficerPublicKeyP *decider_pub,
   const struct TALER_AmlOfficerSignatureP *decider_sig,
   bool *invalid_officer,
@@ -48,6 +49,9 @@ TEH_PG_insert_aml_decision (
     .h_payto = *h_payto
   };
   char *notify_s = GNUNET_PG_get_event_notify_channel (&rep.header);
+  char *kyc_s = (NULL != kyc_requirements)
+    ? json_dumps (kyc_requirements, JSON_COMPACT)
+    : NULL;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (h_payto),
     TALER_PQ_query_param_amount (new_threshold),
@@ -57,6 +61,9 @@ TEH_PG_insert_aml_decision (
     GNUNET_PQ_query_param_auto_from_type (decider_pub),
     GNUNET_PQ_query_param_auto_from_type (decider_sig),
     GNUNET_PQ_query_param_string (notify_s),
+    NULL != kyc_requirements
+    ? GNUNET_PQ_query_param_string (kyc_s)
+    : GNUNET_PQ_query_param_null (),
     GNUNET_PQ_query_param_end
   };
   struct GNUNET_PQ_ResultSpec rs[] = {
@@ -74,11 +81,13 @@ 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);");
+           "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);");
   qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                  "do_insert_aml_decision",
                                                  params,
                                                  rs);
   GNUNET_free (notify_s);
+  if (NULL != kyc_s)
+    free (kyc_s);
   return qs;
 }
diff --git a/src/exchangedb/pg_insert_aml_decision.h 
b/src/exchangedb/pg_insert_aml_decision.h
index b539945a..4d4ca6e5 100644
--- a/src/exchangedb/pg_insert_aml_decision.h
+++ b/src/exchangedb/pg_insert_aml_decision.h
@@ -36,6 +36,7 @@
  * @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 JSON array with KYC requirements
  * @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
@@ -51,6 +52,7 @@ TEH_PG_insert_aml_decision (
   enum TALER_AmlDecisionState new_status,
   struct GNUNET_TIME_Timestamp decision_time,
   const char *justification,
+  const json_t *kyc_requirements,
   const struct TALER_AmlOfficerPublicKeyP *decider_pub,
   const struct TALER_AmlOfficerSignatureP *decider_sig,
   bool *invalid_officer,
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 5f627491..20ffaf0c 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -2406,6 +2406,8 @@ TALER_officer_aml_query_verify (
  * @param h_payto payto URI hash of the account the
  *                      decision is about
  * @param new_state updated AML state
+ * @param kyc_requirements additional KYC requirements to
+ *           impose, can be NULL
  * @param officer_priv private key of AML officer
  * @param[out] officer_sig where to write the signature
  */
@@ -2416,6 +2418,7 @@ TALER_officer_aml_decision_sign (
   const struct TALER_Amount *new_threshold,
   const struct TALER_PaytoHashP *h_payto,
   enum TALER_AmlDecisionState new_state,
+  const json_t *kyc_requirements,
   const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
   struct TALER_AmlOfficerSignatureP *officer_sig);
 
@@ -2430,6 +2433,8 @@ TALER_officer_aml_decision_sign (
  * @param h_payto payto URI hash of the account the
  *                      decision is about
  * @param new_state updated AML state
+ * @param kyc_requirements additional KYC requirements to
+ *           impose, can be NULL
  * @param officer_pub public key of AML officer
  * @param officer_sig signature to verify
  * @return #GNUNET_OK if the signature is valid
@@ -2441,6 +2446,7 @@ TALER_officer_aml_decision_verify (
   const struct TALER_Amount *new_threshold,
   const struct TALER_PaytoHashP *h_payto,
   enum TALER_AmlDecisionState new_state,
+  const json_t *kyc_requirements,
   const struct TALER_AmlOfficerPublicKeyP *officer_pub,
   const struct TALER_AmlOfficerSignatureP *officer_sig);
 
diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index 15329ad1..5cfe6a98 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -4608,6 +4608,7 @@ typedef void
  * @param h_payto payto URI hash of the account the
  *                      decision is about
  * @param new_state updated AML state
+ * @param kyc_requirements JSON array of KYC requirements being imposed, NULL 
for none
  * @param officer_priv private key of the deciding AML officer
  * @param cb function to call with the exchange's result
  * @param cb_cls closure for @a cb
@@ -4622,6 +4623,7 @@ TALER_EXCHANGE_add_aml_decision (
   const struct TALER_Amount *new_threshold,
   const struct TALER_PaytoHashP *h_payto,
   enum TALER_AmlDecisionState new_state,
+  const json_t *kyc_requirements,
   const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
   TALER_EXCHANGE_AddAmlDecisionCallback cb,
   void *cb_cls);
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 0a389bd6..f4397e29 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -6704,6 +6704,7 @@ struct TALER_EXCHANGEDB_Plugin
     enum TALER_AmlDecisionState new_status,
     struct GNUNET_TIME_Timestamp decision_time,
     const char *justification,
+    const json_t *kyc_requirements,
     const struct TALER_AmlOfficerPublicKeyP *decider_pub,
     const struct TALER_AmlOfficerSignatureP *decider_sig,
     bool *invalid_officer,
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index cf427951..37d347c3 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -2741,6 +2741,7 @@ TALER_TESTING_cmd_set_officer (
  * @param new_threshold new threshold to set
  * @param justification justification given for the decision
  * @param new_state new AML state for the account
+ * @param kyc_requirement KYC requirement to impose
  * @param expected_response expected HTTP return status
  * @return the command
  */
@@ -2752,6 +2753,7 @@ TALER_TESTING_cmd_take_aml_decision (
   const char *new_threshold,
   const char *justification,
   enum TALER_AmlDecisionState new_state,
+  const char *kyc_requirement,
   unsigned int expected_response);
 
 
diff --git a/src/lib/exchange_api_add_aml_decision.c 
b/src/lib/exchange_api_add_aml_decision.c
index 5e5383f2..7245db3b 100644
--- a/src/lib/exchange_api_add_aml_decision.c
+++ b/src/lib/exchange_api_add_aml_decision.c
@@ -132,6 +132,7 @@ TALER_EXCHANGE_add_aml_decision (
   const struct TALER_Amount *new_threshold,
   const struct TALER_PaytoHashP *h_payto,
   enum TALER_AmlDecisionState new_state,
+  const json_t *kyc_requirements,
   const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
   TALER_EXCHANGE_AddAmlDecisionCallback cb,
   void *cb_cls)
@@ -149,6 +150,7 @@ TALER_EXCHANGE_add_aml_decision (
                                    new_threshold,
                                    h_payto,
                                    new_state,
+                                   kyc_requirements,
                                    officer_priv,
                                    &officer_sig);
   wh = GNUNET_new (struct TALER_EXCHANGE_AddAmlDecision);
@@ -190,6 +192,9 @@ TALER_EXCHANGE_add_aml_decision (
                                 h_payto),
     GNUNET_JSON_pack_uint64 ("new_state",
                              (uint32_t) new_state),
+    GNUNET_JSON_pack_allow_null (
+      GNUNET_JSON_pack_array_incref ("kyc_requirements",
+                                     (json_t *) kyc_requirements)),
     TALER_JSON_pack_amount ("new_threshold",
                             new_threshold),
     GNUNET_JSON_pack_timestamp ("decision_time",
diff --git a/src/testing/test_kyc_api.c b/src/testing/test_kyc_api.c
index feeed3c7..12f69569 100644
--- a/src/testing/test_kyc_api.c
+++ b/src/testing/test_kyc_api.c
@@ -448,6 +448,7 @@ run (void *cls,
                                          "EUR:10000",
                                          "party time",
                                          TALER_AML_NORMAL,
+                                         NULL,
                                          MHD_HTTP_FORBIDDEN),
     /* Check that no decision was taken, but that we are allowed
        to read this information */
@@ -468,6 +469,7 @@ run (void *cls,
                                          "EUR:10000",
                                          "party time",
                                          TALER_AML_NORMAL,
+                                         NULL,
                                          MHD_HTTP_NO_CONTENT),
     TALER_TESTING_cmd_check_aml_decisions ("check-decisions-one-normal",
                                            "create-aml-officer-1",
@@ -489,6 +491,7 @@ run (void *cls,
                                          "EUR:1000",
                                          "party over",
                                          TALER_AML_FROZEN,
+                                         NULL,
                                          MHD_HTTP_NO_CONTENT),
     TALER_TESTING_cmd_check_aml_decisions ("check-decisions-one-frozen",
                                            "create-aml-officer-1",
diff --git a/src/testing/testing_api_cmd_take_aml_decision.c 
b/src/testing/testing_api_cmd_take_aml_decision.c
index 0992945d..871cdb71 100644
--- a/src/testing/testing_api_cmd_take_aml_decision.c
+++ b/src/testing/testing_api_cmd_take_aml_decision.c
@@ -72,6 +72,11 @@ struct AmlDecisionState
    */
   const char *justification;
 
+  /**
+   * KYC requirement to add.
+   */
+  const char *kyc_requirement;
+
   /**
    * Threshold transaction amount.
    */
@@ -133,6 +138,7 @@ take_aml_decision_run (void *cls,
   const struct TALER_PaytoHashP *h_payto;
   const struct TALER_AmlOfficerPrivateKeyP *officer_priv;
   const struct TALER_TESTING_Command *ref;
+  json_t *kyc_requirements = NULL;
 
   (void) cmd;
   now = GNUNET_TIME_timestamp_get ();
@@ -160,6 +166,15 @@ take_aml_decision_run (void *cls,
                  TALER_TESTING_get_trait_officer_priv (ref,
                                                        &officer_priv));
   ds->h_payto = *h_payto;
+  if (NULL != ds->kyc_requirement)
+  {
+    kyc_requirements = json_array ();
+    GNUNET_assert (NULL != kyc_requirements);
+    GNUNET_assert (0 ==
+                   json_array_append (kyc_requirements,
+                                      json_string (ds->kyc_requirement)));
+  }
+
   ds->dh = TALER_EXCHANGE_add_aml_decision (
     is->ctx,
     is->exchange_url,
@@ -168,9 +183,11 @@ take_aml_decision_run (void *cls,
     &ds->new_threshold,
     h_payto,
     ds->new_state,
+    kyc_requirements,
     officer_priv,
     &take_aml_decision_cb,
     ds);
+  json_decref (kyc_requirements);
   if (NULL == ds->dh)
   {
     GNUNET_break (0);
@@ -246,6 +263,7 @@ TALER_TESTING_cmd_take_aml_decision (
   const char *new_threshold,
   const char *justification,
   enum TALER_AmlDecisionState new_state,
+  const char *kyc_requirement,
   unsigned int expected_response)
 {
   struct AmlDecisionState *ds;
@@ -253,6 +271,7 @@ TALER_TESTING_cmd_take_aml_decision (
   ds = GNUNET_new (struct AmlDecisionState);
   ds->officer_ref_cmd = ref_officer;
   ds->account_ref_cmd = ref_operation;
+  ds->kyc_requirement = kyc_requirement;
   if (GNUNET_OK !=
       TALER_string_to_amount (new_threshold,
                               &ds->new_threshold))
diff --git a/src/util/aml_signatures.c b/src/util/aml_signatures.c
index cad2e748..6d90b25c 100644
--- a/src/util/aml_signatures.c
+++ b/src/util/aml_signatures.c
@@ -56,6 +56,12 @@ struct TALER_AmlDecisionPS
    */
   struct TALER_PaytoHashP h_payto GNUNET_PACKED;
 
+  /**
+   * Hash over JSON array with KYC requirements that were imposed. All zeros
+   * for none.
+   */
+  struct GNUNET_HashCode h_kyc_requirements;
+
   /**
    * What is the new AML status?
    */
@@ -72,6 +78,7 @@ TALER_officer_aml_decision_sign (
   const struct TALER_Amount *new_threshold,
   const struct TALER_PaytoHashP *h_payto,
   enum TALER_AmlDecisionState new_state,
+  const json_t *kyc_requirements,
   const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
   struct TALER_AmlOfficerSignatureP *officer_sig)
 {
@@ -87,6 +94,9 @@ TALER_officer_aml_decision_sign (
                       &ad.h_justification);
   TALER_amount_hton (&ad.new_threshold,
                      new_threshold);
+  if (NULL != kyc_requirements)
+    TALER_json_hash (kyc_requirements,
+                     &ad.h_kyc_requirements);
   GNUNET_CRYPTO_eddsa_sign (&officer_priv->eddsa_priv,
                             &ad,
                             &officer_sig->eddsa_signature);
@@ -100,6 +110,7 @@ TALER_officer_aml_decision_verify (
   const struct TALER_Amount *new_threshold,
   const struct TALER_PaytoHashP *h_payto,
   enum TALER_AmlDecisionState new_state,
+  const json_t *kyc_requirements,
   const struct TALER_AmlOfficerPublicKeyP *officer_pub,
   const struct TALER_AmlOfficerSignatureP *officer_sig)
 {
@@ -115,6 +126,9 @@ TALER_officer_aml_decision_verify (
                       &ad.h_justification);
   TALER_amount_hton (&ad.new_threshold,
                      new_threshold);
+  if (NULL != kyc_requirements)
+    TALER_json_hash (kyc_requirements,
+                     &ad.h_kyc_requirements);
   return GNUNET_CRYPTO_eddsa_verify (
     TALER_SIGNATURE_AML_DECISION,
     &ad,

-- 
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]