gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: add new subcommands for AML staf


From: gnunet
Subject: [taler-exchange] branch master updated: add new subcommands for AML staff management and partner exchanges
Date: Sun, 22 Jan 2023 19:40:49 +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 c2eee251 add new subcommands for AML staff management and partner 
exchanges
c2eee251 is described below

commit c2eee251c2eda2ce544a808d77a9a5615a2e7c34
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Jan 22 19:40:47 2023 +0100

    add new subcommands for AML staff management and partner exchanges
---
 src/exchange-tools/taler-exchange-offline.c | 617 +++++++++++++++++++++++++++-
 src/include/taler_exchange_service.h        |   2 +-
 2 files changed, 617 insertions(+), 2 deletions(-)

diff --git a/src/exchange-tools/taler-exchange-offline.c 
b/src/exchange-tools/taler-exchange-offline.c
index eb64a6c9..660864b7 100644
--- a/src/exchange-tools/taler-exchange-offline.c
+++ b/src/exchange-tools/taler-exchange-offline.c
@@ -1,6 +1,6 @@
 /*
    This file is part of TALER
-   Copyright (C) 2020, 2021, 2022 Taler Systems SA
+   Copyright (C) 2020-2023 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
@@ -112,6 +112,16 @@
  */
 #define OP_DRAIN_PROFITS "exchange-drain-profits-0"
 
+/**
+ * Setup AML staff.
+ */
+#define OP_UPDATE_AML_STAFF "exchange-add-aml-staff-0"
+
+/**
+ * Setup partner exchange for wad transfers.
+ */
+#define OP_ADD_PARTNER "exchange-add-partner-0"
+
 /**
  * Our private key, initialized in #load_offline_key().
  */
@@ -498,6 +508,62 @@ struct UploadExtensionsRequest
 };
 
 
+/**
+ * Data structure for AML staff requests.
+ */
+struct AmlStaffRequest
+{
+
+  /**
+   * Kept in a DLL.
+   */
+  struct AmlStaffRequest *next;
+
+  /**
+   * Kept in a DLL.
+   */
+  struct AmlStaffRequest *prev;
+
+  /**
+   * Operation handle.
+   */
+  struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *h;
+
+  /**
+   * Array index of the associated command.
+   */
+  size_t idx;
+};
+
+
+/**
+ * Data structure for partner add requests.
+ */
+struct PartnerAddRequest
+{
+
+  /**
+   * Kept in a DLL.
+   */
+  struct PartnerAddRequest *next;
+
+  /**
+   * Kept in a DLL.
+   */
+  struct PartnerAddRequest *prev;
+
+  /**
+   * Operation handle.
+   */
+  struct TALER_EXCHANGE_ManagementAddPartner *h;
+
+  /**
+   * Array index of the associated command.
+   */
+  size_t idx;
+};
+
+
 /**
  * Next work item to perform.
  */
@@ -508,6 +574,27 @@ static struct GNUNET_SCHEDULER_Task *nxt;
  */
 static struct TALER_EXCHANGE_ManagementGetKeysHandle *mgkh;
 
+
+/**
+ * Active AML staff change requests.
+ */
+static struct AmlStaffRequest *asr_head;
+
+/**
+ * Active AML staff change requests.
+ */
+static struct AmlStaffRequest *asr_tail;
+
+/**
+ * Active partner add requests.
+ */
+static struct PartnerAddRequest *par_head;
+
+/**
+ * Active partner add requests.
+ */
+static struct PartnerAddRequest *par_tail;
+
 /**
  * Active denomiantion revocation requests.
  */
@@ -629,6 +716,36 @@ do_shutdown (void *cls)
 {
   (void) cls;
 
+  {
+    struct AmlStaffRequest *asr;
+
+    while (NULL != (asr = asr_head))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Aborting incomplete AML staff update #%u\n",
+                  (unsigned int) asr->idx);
+      TALER_EXCHANGE_management_update_aml_officer_cancel (asr->h);
+      GNUNET_CONTAINER_DLL_remove (asr_head,
+                                   asr_tail,
+                                   asr);
+      GNUNET_free (asr);
+    }
+  }
+  {
+    struct PartnerAddRequest *par;
+
+    while (NULL != (par = par_head))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Aborting incomplete partner add request #%u\n",
+                  (unsigned int) par->idx);
+      TALER_EXCHANGE_management_add_partner_cancel (par->h);
+      GNUNET_CONTAINER_DLL_remove (par_head,
+                                   par_tail,
+                                   par);
+      GNUNET_free (par);
+    }
+  }
   {
     struct DenomRevocationRequest *drr;
 
@@ -842,6 +959,8 @@ static void
 test_shutdown (void)
 {
   if ( (NULL == drr_head) &&
+       (NULL == par_head) &&
+       (NULL == asr_head) &&
        (NULL == srr_head) &&
        (NULL == aar_head) &&
        (NULL == adr_head) &&
@@ -2214,6 +2333,221 @@ upload_extensions (const char *exchange_url,
 }
 
 
+/**
+ * Function called with information about the add partner operation.
+ *
+ * @param cls closure with a `struct PartnerAddRequest`
+ * @param hr HTTP response data
+ */
+static void
+add_partner_cb (
+  void *cls,
+  const struct TALER_EXCHANGE_HttpResponse *hr)
+{
+  struct PartnerAddRequest *par = cls;
+
+  if (MHD_HTTP_NO_CONTENT != hr->http_status)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Upload failed for command %u with status %u: %s (%s)\n",
+                (unsigned int) par->idx,
+                hr->http_status,
+                TALER_ErrorCode_get_hint (hr->ec),
+                hr->hint);
+    global_ret = EXIT_FAILURE;
+  }
+  GNUNET_CONTAINER_DLL_remove (par_head,
+                               par_tail,
+                               par);
+  GNUNET_free (par);
+  test_shutdown ();
+}
+
+
+/**
+ * Add partner action.
+ *
+ * @param exchange_url base URL of the exchange
+ * @param idx index of the operation we are performing (for logging)
+ * @param value arguments for add partner
+ */
+static void
+add_partner (const char *exchange_url,
+             size_t idx,
+             const json_t *value)
+{
+  struct TALER_MasterPublicKeyP partner_pub;
+  struct GNUNET_TIME_Timestamp start_date;
+  struct GNUNET_TIME_Timestamp end_date;
+  struct GNUNET_TIME_Relative wad_frequency;
+  struct TALER_Amount wad_fee;
+  const char *partner_base_url;
+  struct TALER_MasterSignatureP master_sig;
+  struct PartnerAddRequest *par;
+  struct GNUNET_JSON_Specification spec[] = {
+    GNUNET_JSON_spec_fixed_auto ("partner_pub",
+                                 &partner_pub),
+    TALER_JSON_spec_amount ("wad_fee",
+                            currency,
+                            &wad_fee),
+    GNUNET_JSON_spec_relative_time ("wad_frequency",
+                                    &wad_frequency),
+    GNUNET_JSON_spec_timestamp ("start_date",
+                                &start_date),
+    GNUNET_JSON_spec_timestamp ("end_date",
+                                &end_date),
+    GNUNET_JSON_spec_string ("partner_base_url",
+                             &partner_base_url),
+    GNUNET_JSON_spec_fixed_auto ("master_sig",
+                                 &master_sig),
+    GNUNET_JSON_spec_end ()
+  };
+  const char *err_name;
+  unsigned int err_line;
+
+  if (GNUNET_OK !=
+      GNUNET_JSON_parse (value,
+                         spec,
+                         &err_name,
+                         &err_line))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Invalid input to add partner: %s#%u at %u (skipping)\n",
+                err_name,
+                err_line,
+                (unsigned int) idx);
+    json_dumpf (value,
+                stderr,
+                JSON_INDENT (2));
+    global_ret = EXIT_FAILURE;
+    test_shutdown ();
+    return;
+  }
+  par = GNUNET_new (struct PartnerAddRequest);
+  par->idx = idx;
+  par->h =
+    TALER_EXCHANGE_management_add_partner (ctx,
+                                           exchange_url,
+                                           &partner_pub,
+                                           start_date,
+                                           end_date,
+                                           wad_frequency,
+                                           &wad_fee,
+                                           partner_base_url,
+                                           &master_sig,
+                                           &add_partner_cb,
+                                           par);
+  GNUNET_CONTAINER_DLL_insert (par_head,
+                               par_tail,
+                               par);
+}
+
+
+/**
+ * Function called with information about the AML officer update operation.
+ *
+ * @param cls closure with a `struct AmlStaffRequest`
+ * @param hr HTTP response data
+ */
+static void
+update_aml_officer_cb (
+  void *cls,
+  const struct TALER_EXCHANGE_HttpResponse *hr)
+{
+  struct AmlStaffRequest *asr = cls;
+
+  if (MHD_HTTP_NO_CONTENT != hr->http_status)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Upload failed for command %u with status %u: %s (%s)\n",
+                (unsigned int) asr->idx,
+                hr->http_status,
+                TALER_ErrorCode_get_hint (hr->ec),
+                hr->hint);
+    global_ret = EXIT_FAILURE;
+  }
+  GNUNET_CONTAINER_DLL_remove (asr_head,
+                               asr_tail,
+                               asr);
+  GNUNET_free (asr);
+  test_shutdown ();
+}
+
+
+/**
+ * Upload AML staff action.
+ *
+ * @param exchange_url base URL of the exchange
+ * @param idx index of the operation we are performing (for logging)
+ * @param value arguments for AML staff change
+ */
+static void
+update_aml_staff (const char *exchange_url,
+                  size_t idx,
+                  const json_t *value)
+{
+  struct TALER_AmlOfficerPublicKeyP officer_pub;
+  const char *officer_name;
+  struct GNUNET_TIME_Timestamp change_date;
+  bool is_active;
+  bool read_only;
+  struct TALER_MasterSignatureP master_sig;
+  struct AmlStaffRequest *asr;
+  struct GNUNET_JSON_Specification spec[] = {
+    GNUNET_JSON_spec_fixed_auto ("officer_pub",
+                                 &officer_pub),
+    GNUNET_JSON_spec_timestamp ("change_date",
+                                &change_date),
+    GNUNET_JSON_spec_bool ("is_active",
+                           &is_active),
+    GNUNET_JSON_spec_bool ("read_only",
+                           &read_only),
+    GNUNET_JSON_spec_string ("officer_name",
+                             &officer_name),
+    GNUNET_JSON_spec_fixed_auto ("master_sig",
+                                 &master_sig),
+    GNUNET_JSON_spec_end ()
+  };
+  const char *err_name;
+  unsigned int err_line;
+
+  if (GNUNET_OK !=
+      GNUNET_JSON_parse (value,
+                         spec,
+                         &err_name,
+                         &err_line))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Invalid input to AML staff update: %s#%u at %u (skipping)\n",
+                err_name,
+                err_line,
+                (unsigned int) idx);
+    json_dumpf (value,
+                stderr,
+                JSON_INDENT (2));
+    global_ret = EXIT_FAILURE;
+    test_shutdown ();
+    return;
+  }
+  asr = GNUNET_new (struct AmlStaffRequest);
+  asr->idx = idx;
+  asr->h =
+    TALER_EXCHANGE_management_update_aml_officer (ctx,
+                                                  exchange_url,
+                                                  &officer_pub,
+                                                  officer_name,
+                                                  change_date,
+                                                  is_active,
+                                                  read_only,
+                                                  &master_sig,
+                                                  &update_aml_officer_cb,
+                                                  asr);
+  GNUNET_CONTAINER_DLL_insert (asr_head,
+                               asr_tail,
+                               asr);
+}
+
+
 /**
  * Perform uploads based on the JSON in #out.
  *
@@ -2267,6 +2601,14 @@ trigger_upload (const char *exchange_url)
       .key = OP_EXTENSIONS,
       .cb = &upload_extensions
     },
+    {
+      .key = OP_UPDATE_AML_STAFF,
+      .cb = &update_aml_staff
+    },
+    {
+      .key = OP_ADD_PARTNER,
+      .cb = &add_partner
+    },
     /* array termination */
     {
       .key = NULL
@@ -3040,6 +3382,261 @@ do_drain (char *const *args)
 }
 
 
+/**
+ * Add partner.
+ *
+ * @param args the array of command-line arguments to process next;
+ *        args[0] must be the partner's master public key, args[1] the 
partner's
+ *        API base URL, args[2] the wad fee, args[3] the wad frequency, and
+ *        args[4] the year (including possibly 'now')
+ */
+static void
+do_add_partner (char *const *args)
+{
+  struct TALER_MasterPublicKeyP partner_pub;
+  struct GNUNET_TIME_Timestamp start_date;
+  struct GNUNET_TIME_Timestamp end_date;
+  struct GNUNET_TIME_Relative wad_frequency;
+  struct TALER_Amount wad_fee;
+  const char *partner_base_url;
+  struct TALER_MasterSignatureP master_sig;
+  char dummy;
+  unsigned int year;
+
+  if (NULL != in)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Downloaded data was not consumed, not adding partner\n");
+    test_shutdown ();
+    global_ret = EXIT_FAILURE;
+    return;
+  }
+  if ( (NULL == args[0]) ||
+       (GNUNET_OK !=
+        GNUNET_STRINGS_string_to_data (args[0],
+                                       strlen (args[0]),
+                                       &partner_pub,
+                                       sizeof (partner_pub))) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "You must specify the partner master public key as first 
argument for this subcommand\n");
+    test_shutdown ();
+    global_ret = EXIT_INVALIDARGUMENT;
+    return;
+  }
+  if ( (NULL == args[1]) ||
+       (0 != strncmp ("http",
+                      args[1],
+                      strlen ("http"))) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "You must specify the partner's base URL as the 2nd argument 
to this subcommand\n");
+    test_shutdown ();
+    global_ret = EXIT_INVALIDARGUMENT;
+    return;
+  }
+  partner_base_url = args[1];
+  if ( (NULL == args[2]) ||
+       (GNUNET_OK !=
+        TALER_string_to_amount (args[2],
+                                &wad_fee)) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Invalid amount `%s' specified for wad fee of partner\n",
+                args[2]);
+    test_shutdown ();
+    global_ret = EXIT_INVALIDARGUMENT;
+    return;
+  }
+  if ( (NULL == args[3]) ||
+       (GNUNET_OK !=
+        GNUNET_STRINGS_fancy_time_to_relative (args[3],
+                                               &wad_frequency)) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Invalid wad frequency `%s' specified for add partner\n",
+                args[3]);
+    test_shutdown ();
+    global_ret = EXIT_INVALIDARGUMENT;
+    return;
+  }
+  if ( (NULL == args[4]) ||
+       ( (1 != sscanf (args[4],
+                       "%u%c",
+                       &year,
+                       &dummy)) &&
+         (0 != strcasecmp ("now",
+                           args[4])) ) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Invalid year `%s' specified for add partner\n",
+                args[4]);
+    test_shutdown ();
+    global_ret = EXIT_INVALIDARGUMENT;
+    return;
+  }
+  if (0 == strcasecmp ("now",
+                       args[4]))
+    year = GNUNET_TIME_get_current_year ();
+  start_date = GNUNET_TIME_absolute_to_timestamp (
+    GNUNET_TIME_year_to_time (year));
+  end_date = GNUNET_TIME_absolute_to_timestamp (
+    GNUNET_TIME_year_to_time (year + 1));
+
+  if (GNUNET_OK !=
+      load_offline_key (GNUNET_NO))
+    return;
+  TALER_exchange_offline_partner_details_sign (&partner_pub,
+                                               start_date,
+                                               end_date,
+                                               wad_frequency,
+                                               &wad_fee,
+                                               partner_base_url,
+                                               &master_priv,
+                                               &master_sig);
+  output_operation (OP_ADD_PARTNER,
+                    GNUNET_JSON_PACK (
+                      GNUNET_JSON_pack_string ("partner_base_url",
+                                               partner_base_url),
+                      GNUNET_JSON_pack_time_rel ("wad_frequency",
+                                                 wad_frequency),
+                      GNUNET_JSON_pack_timestamp ("start_date",
+                                                  start_date),
+                      GNUNET_JSON_pack_timestamp ("end_date",
+                                                  end_date),
+                      GNUNET_JSON_pack_data_auto ("partner_pub",
+                                                  &partner_pub),
+                      GNUNET_JSON_pack_data_auto ("master_sig",
+                                                  &master_sig)));
+  next (args + 5);
+}
+
+
+/**
+ * Enable or disable AML staff.
+ *
+ * @param is_active true to enable, false to disable
+ * @param args the array of command-line arguments to process next; args[0] 
must be the AML staff's public key, args[1] the AML staff's legal name, and if 
@a is_active then args[2] rw (read write) or ro (read only)
+ */
+static void
+do_set_aml_staff (bool is_active,
+                  char *const *args)
+{
+  struct TALER_AmlOfficerPublicKeyP officer_pub;
+  const char *officer_name;
+  bool read_only;
+  struct TALER_MasterSignatureP master_sig;
+  struct GNUNET_TIME_Timestamp now
+    = GNUNET_TIME_timestamp_get ();
+
+  if (NULL != in)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Downloaded data was not consumed, not updating AML staff 
status\n");
+    test_shutdown ();
+    global_ret = EXIT_FAILURE;
+    return;
+  }
+  if ( (NULL == args[0]) ||
+       (GNUNET_OK !=
+        GNUNET_STRINGS_string_to_data (args[0],
+                                       strlen (args[0]),
+                                       &officer_pub,
+                                       sizeof (officer_pub))) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "You must specify the AML officer's public key as first 
argument for this subcommand\n");
+    test_shutdown ();
+    global_ret = EXIT_INVALIDARGUMENT;
+    return;
+  }
+  if (NULL == args[1])
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "You must specify the officer's legal name as the 2nd argument 
to this subcommand\n");
+    test_shutdown ();
+    global_ret = EXIT_INVALIDARGUMENT;
+    return;
+  }
+  officer_name = args[1];
+  if (is_active)
+  {
+    if ( (NULL == args[2]) ||
+         ( (0 != strcmp (args[2],
+                         "ro")) &&
+           (0 != strcmp (args[2],
+                         "rw")) ) )
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "You must specify 'ro' or 'rw' (and not `%s') for the access 
level\n",
+                  args[2]);
+      test_shutdown ();
+      global_ret = EXIT_INVALIDARGUMENT;
+      return;
+    }
+    read_only = (0 == strcmp (args[2],
+                              "ro"));
+  }
+  else
+  {
+    read_only = true;
+  }
+  if (GNUNET_OK !=
+      load_offline_key (GNUNET_NO))
+    return;
+  TALER_exchange_offline_aml_officer_status_sign (&officer_pub,
+                                                  officer_name,
+                                                  now,
+                                                  is_active,
+                                                  read_only,
+                                                  &master_priv,
+                                                  &master_sig);
+  output_operation (OP_UPDATE_AML_STAFF,
+                    GNUNET_JSON_PACK (
+                      GNUNET_JSON_pack_string ("officer_name",
+                                               officer_name),
+                      GNUNET_JSON_pack_timestamp ("change_date",
+                                                  now),
+                      GNUNET_JSON_pack_bool ("is_active",
+                                             is_active),
+                      GNUNET_JSON_pack_bool ("read_only",
+                                             read_only),
+                      GNUNET_JSON_pack_data_auto ("officer_pub",
+                                                  &officer_pub),
+                      GNUNET_JSON_pack_data_auto ("master_sig",
+                                                  &master_sig)));
+  next (args + (is_active ? 3 : 2));
+}
+
+
+/**
+ * Disable AML staff.
+ *
+ * @param args the array of command-line arguments to process next;
+ *        args[0] must be the AML staff's public key, args[1] the AML staff's 
legal name, args[2] rw (read write) or ro (read only)
+ */
+static void
+disable_aml_staff (char *const *args)
+{
+  do_set_aml_staff (false,
+                    args);
+}
+
+
+/**
+ * Enable AML staff.
+ *
+ * @param args the array of command-line arguments to process next;
+ *        args[0] must be the AML staff's public key, args[1] the AML staff's 
legal name, args[2] rw (read write) or ro (read only)
+ */
+static void
+enable_aml_staff (char *const *args)
+{
+  do_set_aml_staff (true,
+                    args);
+}
+
+
 /**
  * Function called with information about future keys.  Dumps the JSON output
  * (on success), either into an internal buffer or to stdout (depending on
@@ -4475,6 +5072,24 @@ work (void *cls)
         "drain profits from exchange escrow account to regular exchange 
operator account (amount, debit account configuration section and credit 
account payto://-URI must be given as arguments)",
       .cb = &do_drain
     },
+    {
+      .name = "add-partner",
+      .help =
+        "add partner exchange for P2P wad transfers (partner master public 
key, partner base URL, wad fee, wad frequency and validity year must be given 
as arguments)",
+      .cb = &do_add_partner
+    },
+    {
+      .name = "aml-enable",
+      .help =
+        "enable AML staff member (staff member public key, legal name and rw 
(read write) or ro (read only) must be given as arguments)",
+      .cb = &enable_aml_staff
+    },
+    {
+      .name = "aml-disable",
+      .help =
+        "disable AML staff member (staff member public key and legal name must 
be given as arguments)",
+      .cb = &disable_aml_staff
+    },
     {
       .name = "upload",
       .help =
diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index ff1698cc..bc98e532 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -4410,7 +4410,7 @@ TALER_EXCHANGE_management_add_partner (
 
 
 /**
- * Cancel #TALER_EXCHANGE_management_update_aml_officer() operation.
+ * Cancel #TALER_EXCHANGE_management_add_partner() operation.
  *
  * @param rh handle of the operation to cancel
  */

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