gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: draft for the AML GET decision e


From: gnunet
Subject: [taler-exchange] branch master updated: draft for the AML GET decision endpoint
Date: Thu, 02 Feb 2023 12:03:58 +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 eab95d01 draft for the AML GET decision endpoint
eab95d01 is described below

commit eab95d015412833c96568fb91d25aa23c53c45cd
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu Feb 2 12:03:55 2023 +0100

    draft for the AML GET decision endpoint
---
 src/exchange/Makefile.am                           |   1 +
 src/exchange/taler-exchange-httpd.c                |   2 -
 .../taler-exchange-httpd_aml-decision-get.c        | 258 +++++++++++++++++++++
 src/exchange/taler-exchange-httpd_aml-decision.h   |  18 ++
 .../taler-exchange-httpd_aml-decisions-get.c       |  44 ++--
 src/exchangedb/pg_select_aml_history.c             |   6 +-
 src/include/taler_exchangedb_plugin.h              |   2 +-
 7 files changed, 304 insertions(+), 27 deletions(-)

diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am
index bf6b1b1a..364ab396 100644
--- a/src/exchange/Makefile.am
+++ b/src/exchange/Makefile.am
@@ -124,6 +124,7 @@ taler_exchange_httpd_SOURCES = \
   taler-exchange-httpd.c taler-exchange-httpd.h \
   taler-exchange-httpd_auditors.c taler-exchange-httpd_auditors.h \
   taler-exchange-httpd_aml-decision.c taler-exchange-httpd_aml-decision.h \
+  taler-exchange-httpd_aml-decision-get.c \
   taler-exchange-httpd_aml-decisions-get.c \
   taler-exchange-httpd_batch-deposit.c taler-exchange-httpd_batch-deposit.h \
   taler-exchange-httpd_batch-withdraw.c taler-exchange-httpd_batch-withdraw.h \
diff --git a/src/exchange/taler-exchange-httpd.c 
b/src/exchange/taler-exchange-httpd.c
index 11b2d35f..4bab9afa 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -450,12 +450,10 @@ handle_get_aml (struct TEH_RequestContext *rc,
       .op = "decisions",
       .handler = &TEH_handler_aml_decisions_get
     },
-#if FIXME_AML_GET_DECISIONS_NOT_IMPLEMENTED
     {
       .op = "decision",
       .handler = &TEH_handler_aml_decision_get
     },
-#endif
     {
       .op = NULL,
       .handler = NULL
diff --git a/src/exchange/taler-exchange-httpd_aml-decision-get.c 
b/src/exchange/taler-exchange-httpd_aml-decision-get.c
new file mode 100644
index 00000000..0754c0b8
--- /dev/null
+++ b/src/exchange/taler-exchange-httpd_aml-decision-get.c
@@ -0,0 +1,258 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2023 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Affero 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 Affero General Public License for more 
details.
+
+  You should have received a copy of the GNU Affero General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler-exchange-httpd_aml-decision-get.c
+ * @brief Return summary information about AML decision
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <jansson.h>
+#include <microhttpd.h>
+#include <pthread.h>
+#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
+#include "taler_signatures.h"
+#include "taler-exchange-httpd.h"
+#include "taler_exchangedb_plugin.h"
+#include "taler-exchange-httpd_aml-decision.h"
+#include "taler-exchange-httpd_metrics.h"
+
+
+/**
+ * Maximum number of records we return per request.
+ */
+#define MAX_RECORDS 1024
+
+/**
+ * Callback with KYC attributes about a particular user.
+ *
+ * @param[in,out] cls closure with a `json_t *` array to update
+ * @param h_payto account for which the attribute data is stored
+ * @param provider_section provider that must be checked
+ * @param birthdate birthdate of user, in format YYYY-MM-DD; can be NULL;
+ *        digits can be 0 if exact day, month or year are unknown
+ * @param collection_time when was the data collected
+ * @param expiration_time when does the data expire
+ * @param enc_attributes_size number of bytes in @a enc_attributes
+ * @param enc_attributes encrypted attribute data
+ */
+static void
+kyc_attribute_cb (
+  void *cls,
+  const struct TALER_PaytoHashP *h_payto,
+  const char *provider_section,
+  const char *birthdate,
+  struct GNUNET_TIME_Timestamp collection_time,
+  struct GNUNET_TIME_Timestamp expiration_time,
+  size_t enc_attributes_size,
+  const void *enc_attributes)
+{
+  json_t *kyc_attributes = cls;
+  json_t *attributes;
+
+  attributes = NULL; // FIXME
+
+  GNUNET_assert (
+    0 ==
+    json_array_append (
+      kyc_attributes,
+      GNUNET_JSON_PACK (
+        GNUNET_JSON_pack_string ("provider_section",
+                                 provider_section),
+        GNUNET_JSON_pack_timestamp ("collection_time",
+                                    collection_time),
+        GNUNET_JSON_pack_timestamp ("expiration_time",
+                                    expiration_time),
+        GNUNET_JSON_pack_object_steal ("attributes",
+                                       attributes)
+        )));
+}
+
+
+/**
+ * Return historic AML decision(s).
+ *
+ * @param[in,out] cls closure with a `json_t *` array to update
+ * @param new_threshold new monthly threshold that would trigger an AML check
+ * @param new_status AML decision status
+ * @param decision_time when was the decision made
+ * @param justification human-readable text justifying the decision
+ * @param decider_pub public key of the staff member
+ * @param decider_sig signature of the staff member
+ */
+static void
+aml_history_cb (
+  void *cls,
+  const struct TALER_Amount *new_threshold,
+  enum TALER_AmlDecisionState new_status,
+  struct GNUNET_TIME_Timestamp decision_time,
+  const char *justification,
+  const struct TALER_AmlOfficerPublicKeyP *decider_pub,
+  const struct TALER_AmlOfficerSignatureP *decider_sig)
+{
+  json_t *aml_history = cls;
+
+  GNUNET_assert (
+    0 ==
+    json_array_append (
+      aml_history,
+      GNUNET_JSON_PACK (
+        GNUNET_JSON_pack_data_auto ("decider_pub",
+                                    decider_pub),
+        GNUNET_JSON_pack_string ("justification",
+                                 justification),
+        TALER_JSON_pack_amount ("new_threshold",
+                                new_threshold),
+        GNUNET_JSON_pack_int64 ("new_status",
+                                new_status),
+        GNUNET_JSON_pack_timestamp ("decision_time",
+                                    decision_time)
+        )));
+}
+
+
+MHD_RESULT
+TEH_handler_aml_decision_get (
+  struct TEH_RequestContext *rc,
+  const struct TALER_AmlOfficerPublicKeyP *officer_pub,
+  const char *const args[])
+{
+  struct TALER_AmlOfficerSignatureP officer_sig;
+  struct TALER_PaytoHashP h_payto;
+
+  if ( (NULL == args[0]) ||
+       (GNUNET_OK !=
+        GNUNET_STRINGS_string_to_data (args[0],
+                                       strlen (args[0]),
+                                       &h_payto,
+                                       sizeof (h_payto))) )
+  {
+    GNUNET_break_op (0);
+    return TALER_MHD_reply_with_error (rc->connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       TALER_EC_GENERIC_PARAMETER_MALFORMED,
+                                       "h_payto");
+  }
+
+  if (NULL != args[1])
+  {
+    GNUNET_break_op (0);
+    return TALER_MHD_reply_with_error (rc->connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       TALER_EC_GENERIC_ENDPOINT_UNKNOWN,
+                                       args[1]);
+  }
+  {
+    const char *sig_hdr;
+
+    sig_hdr = MHD_lookup_connection_value (rc->connection,
+                                           MHD_HEADER_KIND,
+                                           TALER_AML_OFFICER_SIGNATURE_HEADER);
+    if ( (NULL == sig_hdr) ||
+         (GNUNET_OK !=
+          GNUNET_STRINGS_string_to_data (sig_hdr,
+                                         strlen (sig_hdr),
+                                         &officer_sig,
+                                         sizeof (officer_sig))) ||
+         (GNUNET_OK !=
+          TALER_officer_aml_query_verify (officer_pub,
+                                          &officer_sig)) )
+    {
+      GNUNET_break_op (0);
+      return TALER_MHD_reply_with_error (rc->connection,
+                                         MHD_HTTP_BAD_REQUEST,
+                                         
TALER_EC_EXCHANGE_GENERIC_AML_OFFICER_GET_SIGNATURE_INVALID,
+                                         sig_hdr);
+    }
+    TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
+  }
+
+  {
+    json_t *aml_history;
+    json_t *kyc_attributes;
+    enum GNUNET_DB_QueryStatus qs;
+    bool none;
+
+    aml_history = json_array ();
+    GNUNET_assert (NULL != aml_history);
+    qs = TEH_plugin->select_aml_history (TEH_plugin->cls,
+                                         &h_payto,
+                                         &aml_history_cb,
+                                         aml_history);
+    switch (qs)
+    {
+    case GNUNET_DB_STATUS_HARD_ERROR:
+    case GNUNET_DB_STATUS_SOFT_ERROR:
+      json_decref (aml_history);
+      GNUNET_break (0);
+      return TALER_MHD_reply_with_error (rc->connection,
+                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                         TALER_EC_GENERIC_DB_FETCH_FAILED,
+                                         NULL);
+    case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+      none = true;
+      break;
+    case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+      none = false;
+      break;
+    }
+
+    kyc_attributes = json_array ();
+    GNUNET_assert (NULL != kyc_attributes);
+    qs = TEH_plugin->select_kyc_attributes (TEH_plugin->cls,
+                                            &h_payto,
+                                            &kyc_attribute_cb,
+                                            kyc_attributes);
+    switch (qs)
+    {
+    case GNUNET_DB_STATUS_HARD_ERROR:
+    case GNUNET_DB_STATUS_SOFT_ERROR:
+      json_decref (aml_history);
+      json_decref (kyc_attributes);
+      GNUNET_break (0);
+      return TALER_MHD_reply_with_error (rc->connection,
+                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                         TALER_EC_GENERIC_DB_FETCH_FAILED,
+                                         NULL);
+    case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+      if (none)
+      {
+        json_decref (aml_history);
+        json_decref (kyc_attributes);
+        return TALER_MHD_reply_static (
+          rc->connection,
+          MHD_HTTP_NO_CONTENT,
+          NULL,
+          NULL,
+          0);
+      }
+      break;
+    case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+      break;
+    }
+    return TALER_MHD_REPLY_JSON_PACK (
+      rc->connection,
+      MHD_HTTP_OK,
+      GNUNET_JSON_pack_array_steal ("aml_history",
+                                    aml_history),
+      GNUNET_JSON_pack_array_steal ("kyc_attributes",
+                                    kyc_attributes));
+  }
+}
+
+
+/* end of taler-exchange-httpd_aml-decision_get.c */
diff --git a/src/exchange/taler-exchange-httpd_aml-decision.h 
b/src/exchange/taler-exchange-httpd_aml-decision.h
index e31cfdfa..033db4a8 100644
--- a/src/exchange/taler-exchange-httpd_aml-decision.h
+++ b/src/exchange/taler-exchange-httpd_aml-decision.h
@@ -58,4 +58,22 @@ TEH_handler_aml_decisions_get (
   const struct TALER_AmlOfficerPublicKeyP *officer_pub,
   const char *const args[]);
 
+
+/**
+ * Handle a GET "/aml/$OFFICER_PUB/decision/$H_PAYTO" request.  Parses the 
request
+ * details, checks the signatures and if appropriately authorized returns
+ * the AML history and KYC attributes for the account.
+ *
+ * @param rc request context
+ * @param officer_pub public key of the AML officer who made the request
+ * @param args GET arguments (should be one)
+ * @return MHD result code
+ */
+MHD_RESULT
+TEH_handler_aml_decision_get (
+  struct TEH_RequestContext *rc,
+  const struct TALER_AmlOfficerPublicKeyP *officer_pub,
+  const char *const args[]);
+
+
 #endif
diff --git a/src/exchange/taler-exchange-httpd_aml-decisions-get.c 
b/src/exchange/taler-exchange-httpd_aml-decisions-get.c
index 091e7a67..9f2fae3b 100644
--- a/src/exchange/taler-exchange-httpd_aml-decisions-get.c
+++ b/src/exchange/taler-exchange-httpd_aml-decisions-get.c
@@ -79,8 +79,6 @@ TEH_handler_aml_decisions_get (
   const struct TALER_AmlOfficerPublicKeyP *officer_pub,
   const char *const args[])
 {
-  enum GNUNET_GenericReturnValue res;
-  const char *sig_hdr;
   struct TALER_AmlOfficerSignatureP officer_sig;
   bool frozen = false;
   bool pending = false;
@@ -96,26 +94,30 @@ TEH_handler_aml_decisions_get (
                                        TALER_EC_GENERIC_ENDPOINT_UNKNOWN,
                                        args[0]);
   }
-  sig_hdr = MHD_lookup_connection_value (rc->connection,
-                                         MHD_HEADER_KIND,
-                                         TALER_AML_OFFICER_SIGNATURE_HEADER);
-  if ( (NULL == sig_hdr) ||
-       (GNUNET_OK !=
-        GNUNET_STRINGS_string_to_data (sig_hdr,
-                                       strlen (sig_hdr),
-                                       &officer_sig,
-                                       sizeof (officer_sig))) ||
-       (GNUNET_OK !=
-        TALER_officer_aml_query_verify (officer_pub,
-                                        &officer_sig)) )
   {
-    GNUNET_break_op (0);
-    return TALER_MHD_reply_with_error (rc->connection,
-                                       MHD_HTTP_BAD_REQUEST,
-                                       
TALER_EC_EXCHANGE_GENERIC_AML_OFFICER_GET_SIGNATURE_INVALID,
-                                       sig_hdr);
+    const char *sig_hdr;
+
+    sig_hdr = MHD_lookup_connection_value (rc->connection,
+                                           MHD_HEADER_KIND,
+                                           TALER_AML_OFFICER_SIGNATURE_HEADER);
+    if ( (NULL == sig_hdr) ||
+         (GNUNET_OK !=
+          GNUNET_STRINGS_string_to_data (sig_hdr,
+                                         strlen (sig_hdr),
+                                         &officer_sig,
+                                         sizeof (officer_sig))) ||
+         (GNUNET_OK !=
+          TALER_officer_aml_query_verify (officer_pub,
+                                          &officer_sig)) )
+    {
+      GNUNET_break_op (0);
+      return TALER_MHD_reply_with_error (rc->connection,
+                                         MHD_HTTP_BAD_REQUEST,
+                                         
TALER_EC_EXCHANGE_GENERIC_AML_OFFICER_GET_SIGNATURE_INVALID,
+                                         sig_hdr);
+    }
+    TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
   }
-  TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
 
   {
     const char *p;
@@ -225,4 +227,4 @@ TEH_handler_aml_decisions_get (
 }
 
 
-/* end of taler-exchange-httpd_deposits_get.c */
+/* end of taler-exchange-httpd_aml-decisions_get.c */
diff --git a/src/exchangedb/pg_select_aml_history.c 
b/src/exchangedb/pg_select_aml_history.c
index 9638df5c..ac7fe584 100644
--- a/src/exchangedb/pg_select_aml_history.c
+++ b/src/exchangedb/pg_select_aml_history.c
@@ -74,7 +74,7 @@ handle_aml_result (void *cls,
   {
     struct TALER_Amount new_threshold;
     uint32_t ns;
-    struct GNUNET_TIME_Absolute decision_time;
+    struct GNUNET_TIME_Timestamp decision_time;
     char *justification;
     struct TALER_AmlOfficerPublicKeyP decider_pub;
     struct TALER_AmlOfficerSignatureP decider_sig;
@@ -83,8 +83,8 @@ handle_aml_result (void *cls,
                                    &new_threshold),
       GNUNET_PQ_result_spec_uint32 ("new_status",
                                     &ns),
-      GNUNET_PQ_result_spec_absolute_time ("decision_time",
-                                           &decision_time),
+      GNUNET_PQ_result_spec_timestamp ("decision_time",
+                                       &decision_time),
       GNUNET_PQ_result_spec_string ("justification",
                                     &justification),
       GNUNET_PQ_result_spec_auto_from_type ("decider_pub",
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 3a8b88ae..4eb0a841 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -3159,7 +3159,7 @@ typedef void
   void *cls,
   const struct TALER_Amount *new_threshold,
   enum TALER_AmlDecisionState new_status,
-  struct GNUNET_TIME_Absolute decision_time,
+  struct GNUNET_TIME_Timestamp decision_time,
   const char *justification,
   const struct TALER_AmlOfficerPublicKeyP *decider_pub,
   const struct TALER_AmlOfficerSignatureP *decider_sig);

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