gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] 01/02: new AML APIs (libtalerexchange)


From: gnunet
Subject: [taler-exchange] 01/02: new AML APIs (libtalerexchange)
Date: Wed, 18 Jan 2023 14:38:33 +0100

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

grothoff pushed a commit to branch master
in repository exchange.

commit 999209518d3eb5ddc7c83011253ec1d2bb32b170
Author: Christian Grothoff <grothoff@gnunet.org>
AuthorDate: Wed Jan 18 14:25:58 2023 +0100

    new AML APIs (libtalerexchange)
---
 src/include/taler_exchange_service.h               | 181 +++++++++++++++-
 src/lib/exchange_api_add_aml_decision.c            | 240 +++++++++++++++++++++
 src/lib/exchange_api_management_add_partner.c      | 232 ++++++++++++++++++++
 .../exchange_api_management_update_aml_officer.c   | 228 ++++++++++++++++++++
 4 files changed, 880 insertions(+), 1 deletion(-)

diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index b2d0bf71..ff1698cc 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -1,6 +1,6 @@
 /*
    This file is part of TALER
-   Copyright (C) 2014-2022 Taler Systems SA
+   Copyright (C) 2014-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
@@ -4240,6 +4240,185 @@ TALER_EXCHANGE_management_revoke_signing_key_cancel (
   struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *rh);
 
 
+/**
+ * Function called with information about the change to
+ * an AML officer status.
+ *
+ * @param cls closure
+ * @param hr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementUpdateAmlOfficerCallback) (
+  void *cls,
+  const struct TALER_EXCHANGE_HttpResponse *hr);
+
+
+/**
+ * @brief Handle for a POST /management/aml-officers/$OFFICER_PUB request.
+ */
+struct TALER_EXCHANGE_ManagementUpdateAmlOfficer;
+
+
+/**
+ * Inform the exchange that the status of an AML officer has changed.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param officer_pub the public signing key of the officer
+ * @param officer_name name of the officer
+ * @param change_date when to affect the status change
+ * @param is_active true to enable the officer
+ * @param read_only true to only allow read-only access
+ * @param master_sig signature affirming the change
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *
+TALER_EXCHANGE_management_update_aml_officer (
+  struct GNUNET_CURL_Context *ctx,
+  const char *url,
+  const struct TALER_AmlOfficerPublicKeyP *officer_pub,
+  const char *officer_name,
+  struct GNUNET_TIME_Timestamp change_date,
+  bool is_active,
+  bool read_only,
+  const struct TALER_MasterSignatureP *master_sig,
+  TALER_EXCHANGE_ManagementUpdateAmlOfficerCallback cb,
+  void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_management_update_aml_officer() operation.
+ *
+ * @param rh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_management_update_aml_officer_cancel (
+  struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *rh);
+
+
+/**
+ * Function called with information about storing an
+ * an AML decision.
+ *
+ * @param cls closure
+ * @param hr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_AddAmlDecisionCallback) (
+  void *cls,
+  const struct TALER_EXCHANGE_HttpResponse *hr);
+
+
+/**
+ * @brief Handle for a POST /aml-decision/$OFFICER_PUB request.
+ */
+struct TALER_EXCHANGE_AddAmlDecision;
+
+
+/**
+ * Inform the exchange that an AML decision has been taken.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param justification human-readable justification
+ * @param decision_time when was the decision made
+ * @param new_threshold at what monthly amount threshold
+ *                      should a revision be triggered
+ * @param h_payto payto URI hash of the account the
+ *                      decision is about
+ * @param new_state updated AML state
+ * @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
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_AddAmlDecision *
+TALER_EXCHANGE_add_aml_decision (
+  struct GNUNET_CURL_Context *ctx,
+  const char *url,
+  const char *justification,
+  struct GNUNET_TIME_Timestamp decision_time,
+  const struct TALER_Amount *new_threshold,
+  const struct TALER_PaytoHashP *h_payto,
+  enum TALER_AmlDecisionState new_state,
+  const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
+  TALER_EXCHANGE_AddAmlDecisionCallback cb,
+  void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_add_aml_decision() operation.
+ *
+ * @param rh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_add_aml_decision_cancel (
+  struct TALER_EXCHANGE_AddAmlDecision *rh);
+
+
+/**
+ * Function called with information about the change to
+ * an AML officer status.
+ *
+ * @param cls closure
+ * @param hr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementAddPartnerCallback) (
+  void *cls,
+  const struct TALER_EXCHANGE_HttpResponse *hr);
+
+
+/**
+ * @brief Handle for a POST /management/partners/$PARTNER_PUB request.
+ */
+struct TALER_EXCHANGE_ManagementAddPartner;
+
+
+/**
+ * Inform the exchange that the status of a partnering
+ * exchange was defined.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param partner_pub the offline signing key of the partner
+ * @param start_date validity period start
+ * @param end_date validity period end
+ * @param wad_frequency how often will we do wad transfers to this partner
+ * @param wad_fee what is the wad fee to this partner
+ * @param partner_base_url what is the base URL of the @a partner_pub exchange
+ * @param master_sig the signature the signature
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementAddPartner *
+TALER_EXCHANGE_management_add_partner (
+  struct GNUNET_CURL_Context *ctx,
+  const char *url,
+  const struct TALER_MasterPublicKeyP *partner_pub,
+  struct GNUNET_TIME_Timestamp start_date,
+  struct GNUNET_TIME_Timestamp end_date,
+  struct GNUNET_TIME_Relative wad_frequency,
+  const struct TALER_Amount *wad_fee,
+  const char *partner_base_url,
+  const struct TALER_MasterSignatureP *master_sig,
+  TALER_EXCHANGE_ManagementAddPartnerCallback cb,
+  void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_management_update_aml_officer() operation.
+ *
+ * @param rh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_management_add_partner_cancel (
+  struct TALER_EXCHANGE_ManagementAddPartner *rh);
+
+
 /**
  * Function called with information about the auditor setup operation result.
  *
diff --git a/src/lib/exchange_api_add_aml_decision.c 
b/src/lib/exchange_api_add_aml_decision.c
new file mode 100644
index 00000000..7230c5ed
--- /dev/null
+++ b/src/lib/exchange_api_add_aml_decision.c
@@ -0,0 +1,240 @@
+/*
+  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 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/>
+*/
+/**
+ * @file lib/exchange_api_add_aml_decision.c
+ * @brief functions to add an AML decision by an AML officer
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_json_lib.h"
+#include <gnunet/gnunet_curl_lib.h>
+#include "taler_exchange_service.h"
+#include "exchange_api_curl_defaults.h"
+#include "taler_signatures.h"
+#include "taler_curl_lib.h"
+#include "taler_json_lib.h"
+
+
+struct TALER_EXCHANGE_AddAmlDecision
+{
+
+  /**
+   * The url for this request.
+   */
+  char *url;
+
+  /**
+   * Minor context that holds body and headers.
+   */
+  struct TALER_CURL_PostContext post_ctx;
+
+  /**
+   * Handle for the request.
+   */
+  struct GNUNET_CURL_Job *job;
+
+  /**
+   * Function to call with the result.
+   */
+  TALER_EXCHANGE_AddAmlDecisionCallback cb;
+
+  /**
+   * Closure for @a cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Reference to the execution context.
+   */
+  struct GNUNET_CURL_Context *ctx;
+};
+
+
+/**
+ * Function called when we're done processing the
+ * HTTP POST /aml-decision/$OFFICER_PUB request.
+ *
+ * @param cls the `struct TALER_EXCHANGE_AddAmlDecision *`
+ * @param response_code HTTP response code, 0 on error
+ * @param response response body, NULL if not in JSON
+ */
+static void
+handle_add_aml_decision_finished (void *cls,
+                                  long response_code,
+                                  const void *response)
+{
+  struct TALER_EXCHANGE_AddAmlDecision *wh = cls;
+  const json_t *json = response;
+  struct TALER_EXCHANGE_HttpResponse hr = {
+    .http_status = (unsigned int) response_code,
+    .reply = json
+  };
+
+  wh->job = NULL;
+  switch (response_code)
+  {
+  case 0:
+    /* no reply */
+    hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+    hr.hint = "server offline?";
+    break;
+  case MHD_HTTP_NO_CONTENT:
+    break;
+  case MHD_HTTP_FORBIDDEN:
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    break;
+  case MHD_HTTP_CONFLICT:
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    break;
+  default:
+    /* unexpected response code */
+    GNUNET_break_op (0);
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unexpected response code %u/%d for exchange AML decision\n",
+                (unsigned int) response_code,
+                (int) hr.ec);
+    break;
+  }
+  if (NULL != wh->cb)
+  {
+    wh->cb (wh->cb_cls,
+            &hr);
+    wh->cb = NULL;
+  }
+  TALER_EXCHANGE_add_aml_decision_cancel (wh);
+}
+
+
+struct TALER_EXCHANGE_AddAmlDecision *
+TALER_EXCHANGE_add_aml_decision (
+  struct GNUNET_CURL_Context *ctx,
+  const char *url,
+  const char *justification,
+  struct GNUNET_TIME_Timestamp decision_time,
+  const struct TALER_Amount *new_threshold,
+  const struct TALER_PaytoHashP *h_payto,
+  enum TALER_AmlDecisionState new_state,
+  const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
+  TALER_EXCHANGE_AddAmlDecisionCallback cb,
+  void *cb_cls)
+{
+  struct TALER_AmlOfficerPrivateKeyP officer_pub;
+  struct TALER_AmlOfficerSignatureP officer_sig;
+  struct TALER_EXCHANGE_AddAmlDecision *wh;
+  CURL *eh;
+  json_t *body;
+
+  GNUNET_CRYPTO_eddsa_key_get_public (&officer_priv->eddsa_priv,
+                                      &officer_pub.eddsa_pub);
+  TALER_officer_aml_decision_sign (justification,
+                                   decision_time,
+                                   h_payto,
+                                   new_state,
+                                   officer_priv,
+                                   &officer_sig);
+  wh = GNUNET_new (struct TALER_EXCHANGE_AddAmlDecision);
+  wh->cb = cb;
+  wh->cb_cls = cb_cls;
+  wh->ctx = ctx;
+  {
+    char *path;
+    char opus[sizeof (officer_pub) * 2];
+    char *end;
+
+    end = GNUNET_STRINGS_data_to_string (
+      &officer_pub,
+      sizeof (officer_pub),
+      opus,
+      sizeof (opus));
+    *end = '\0';
+    GNUNET_asprintf (&path,
+                     "aml-decision/%s",
+                     opus);
+    wh->url = TALER_url_join (url,
+                              path,
+                              NULL);
+    GNUNET_free (path);
+  }
+  if (NULL == wh->url)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Could not construct request URL.\n");
+    GNUNET_free (wh);
+    return NULL;
+  }
+  body = GNUNET_JSON_PACK (
+    GNUNET_JSON_pack_string ("justification",
+                             justification),
+    GNUNET_JSON_pack_data_auto ("officer_sig",
+                                &officer_sig),
+    GNUNET_JSON_pack_data_auto ("h_payto",
+                                h_payto),
+    GNUNET_JSON_pack_data_uint64 ("state",
+                                  (uint32_t) new_state),
+    TALER_JSON_pack_amount ("new_threshold",
+                            new_threshold),
+    GNUNET_JSON_pack_timestamp ("decision_time",
+                                decision_time));
+  eh = TALER_EXCHANGE_curl_easy_get_ (wh->url);
+  if ( (NULL == eh) ||
+       (GNUNET_OK !=
+        TALER_curl_easy_post (&wh->post_ctx,
+                              eh,
+                              body)) )
+  {
+    GNUNET_break (0);
+    if (NULL != eh)
+      curl_easy_cleanup (eh);
+    json_decref (body);
+    GNUNET_free (wh->url);
+    return NULL;
+  }
+  json_decref (body);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Requesting URL '%s'\n",
+              wh->url);
+  wh->job = GNUNET_CURL_job_add2 (ctx,
+                                  eh,
+                                  wh->post_ctx.headers,
+                                  &handle_add_aml_decision_finished,
+                                  wh);
+  if (NULL == wh->job)
+  {
+    TALER_EXCHANGE_add_aml_decision_cancel (wh);
+    return NULL;
+  }
+  return wh;
+}
+
+
+void
+TALER_EXCHANGE_add_aml_decision_cancel (
+  struct TALER_EXCHANGE_AddAmlDecision *wh)
+{
+  if (NULL != wh->job)
+  {
+    GNUNET_CURL_job_cancel (wh->job);
+    wh->job = NULL;
+  }
+  TALER_curl_easy_post_finished (&wh->post_ctx);
+  GNUNET_free (wh->url);
+  GNUNET_free (wh);
+}
diff --git a/src/lib/exchange_api_management_add_partner.c 
b/src/lib/exchange_api_management_add_partner.c
new file mode 100644
index 00000000..264fd664
--- /dev/null
+++ b/src/lib/exchange_api_management_add_partner.c
@@ -0,0 +1,232 @@
+/*
+  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 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/>
+*/
+/**
+ * @file lib/exchange_api_management_add_partner.c
+ * @brief functions to add an partner by an AML officer
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_json_lib.h"
+#include <gnunet/gnunet_curl_lib.h>
+#include "taler_exchange_service.h"
+#include "exchange_api_curl_defaults.h"
+#include "taler_signatures.h"
+#include "taler_curl_lib.h"
+#include "taler_json_lib.h"
+
+
+struct TALER_EXCHANGE_ManagementAddPartner
+{
+
+  /**
+   * The url for this request.
+   */
+  char *url;
+
+  /**
+   * Minor context that holds body and headers.
+   */
+  struct TALER_CURL_PostContext post_ctx;
+
+  /**
+   * Handle for the request.
+   */
+  struct GNUNET_CURL_Job *job;
+
+  /**
+   * Function to call with the result.
+   */
+  TALER_EXCHANGE_ManagementAddPartnerCallback cb;
+
+  /**
+   * Closure for @a cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Reference to the execution context.
+   */
+  struct GNUNET_CURL_Context *ctx;
+};
+
+
+/**
+ * Function called when we're done processing the
+ * HTTP POST /aml-decision/$OFFICER_PUB request.
+ *
+ * @param cls the `struct TALER_EXCHANGE_ManagementAddPartner *`
+ * @param response_code HTTP response code, 0 on error
+ * @param response response body, NULL if not in JSON
+ */
+static void
+handle_add_partner_finished (void *cls,
+                             long response_code,
+                             const void *response)
+{
+  struct TALER_EXCHANGE_ManagementAddPartner *wh = cls;
+  const json_t *json = response;
+  struct TALER_EXCHANGE_HttpResponse hr = {
+    .http_status = (unsigned int) response_code,
+    .reply = json
+  };
+
+  wh->job = NULL;
+  switch (response_code)
+  {
+  case 0:
+    /* no reply */
+    hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+    hr.hint = "server offline?";
+    break;
+  case MHD_HTTP_NO_CONTENT:
+    break;
+  case MHD_HTTP_FORBIDDEN:
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    break;
+  case MHD_HTTP_CONFLICT:
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    break;
+  default:
+    /* unexpected response code */
+    GNUNET_break_op (0);
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unexpected response code %u/%d for adding exchange partner\n",
+                (unsigned int) response_code,
+                (int) hr.ec);
+    break;
+  }
+  if (NULL != wh->cb)
+  {
+    wh->cb (wh->cb_cls,
+            &hr);
+    wh->cb = NULL;
+  }
+  TALER_EXCHANGE_management_add_partner_cancel (wh);
+}
+
+
+struct TALER_EXCHANGE_ManagementAddPartner *
+TALER_EXCHANGE_management_add_partner (
+  struct GNUNET_CURL_Context *ctx,
+  const char *url,
+  const struct TALER_MasterPublicKeyP *partner_pub,
+  struct GNUNET_TIME_Timestamp start_date,
+  struct GNUNET_TIME_Timestamp end_date,
+  struct GNUNET_TIME_Relative wad_frequency,
+  const struct TALER_Amount *wad_fee,
+  const char *partner_base_url,
+  const struct TALER_MasterSignatureP *master_sig,
+  TALER_EXCHANGE_ManagementAddPartnerCallback cb,
+  void *cb_cls)
+{
+  struct TALER_EXCHANGE_ManagementAddPartner *wh;
+  CURL *eh;
+  json_t *body;
+
+  wh = GNUNET_new (struct TALER_EXCHANGE_ManagementAddPartner);
+  wh->cb = cb;
+  wh->cb_cls = cb_cls;
+  wh->ctx = ctx;
+  {
+    char *path;
+    char opus[sizeof (*partner_pub) * 2];
+    char *end;
+
+    end = GNUNET_STRINGS_data_to_string (
+      partner_pub,
+      sizeof (*partner_pub),
+      opus,
+      sizeof (opus));
+    *end = '\0';
+    GNUNET_asprintf (&path,
+                     "management/partners/%s",
+                     opus);
+    wh->url = TALER_url_join (url,
+                              path,
+                              NULL);
+    GNUNET_free (path);
+  }
+  if (NULL == wh->url)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Could not construct request URL.\n");
+    GNUNET_free (wh);
+    return NULL;
+  }
+  body = GNUNET_JSON_PACK (
+    GNUNET_JSON_pack_string ("partner_base_url",
+                             partner_base_url),
+    GNUNET_JSON_pack_timestamp ("start_date",
+                                start_date),
+    GNUNET_JSON_pack_timestamp ("end_date",
+                                end_date),
+    GNUNET_JSON_pack_time_rel ("wad_frequency",
+                               wad_frequency),
+    GNUNET_JSON_pack_data_auto ("master_sig",
+                                &master_sig),
+    TALER_JSON_pack_amount ("wad_fee",
+                            wad_fee)
+    );
+  eh = TALER_EXCHANGE_curl_easy_get_ (wh->url);
+  if ( (NULL == eh) ||
+       (GNUNET_OK !=
+        TALER_curl_easy_post (&wh->post_ctx,
+                              eh,
+                              body)) )
+  {
+    GNUNET_break (0);
+    if (NULL != eh)
+      curl_easy_cleanup (eh);
+    json_decref (body);
+    GNUNET_free (wh->url);
+    return NULL;
+  }
+  json_decref (body);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Requesting URL '%s'\n",
+              wh->url);
+  wh->job = GNUNET_CURL_job_add2 (ctx,
+                                  eh,
+                                  wh->post_ctx.headers,
+                                  &handle_add_partner_finished,
+                                  wh);
+  if (NULL == wh->job)
+  {
+    TALER_EXCHANGE_management_add_partner_cancel (wh);
+    return NULL;
+  }
+  return wh;
+}
+
+
+void
+TALER_EXCHANGE_management_add_partner_cancel (
+  struct TALER_EXCHANGE_ManagementAddPartner *wh)
+{
+  if (NULL != wh->job)
+  {
+    GNUNET_CURL_job_cancel (wh->job);
+    wh->job = NULL;
+  }
+  TALER_curl_easy_post_finished (&wh->post_ctx);
+  GNUNET_free (wh->url);
+  GNUNET_free (wh);
+}
diff --git a/src/lib/exchange_api_management_update_aml_officer.c 
b/src/lib/exchange_api_management_update_aml_officer.c
new file mode 100644
index 00000000..bdc0dbe4
--- /dev/null
+++ b/src/lib/exchange_api_management_update_aml_officer.c
@@ -0,0 +1,228 @@
+/*
+  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 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/>
+*/
+/**
+ * @file lib/exchange_api_management_update_aml_officer.c
+ * @brief functions to update AML officer status
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_json_lib.h"
+#include <gnunet/gnunet_curl_lib.h>
+#include "taler_exchange_service.h"
+#include "exchange_api_curl_defaults.h"
+#include "taler_signatures.h"
+#include "taler_curl_lib.h"
+#include "taler_json_lib.h"
+
+
+struct TALER_EXCHANGE_ManagementUpdateAmlOfficer
+{
+
+  /**
+   * The url for this request.
+   */
+  char *url;
+
+  /**
+   * Minor context that holds body and headers.
+   */
+  struct TALER_CURL_PostContext post_ctx;
+
+  /**
+   * Handle for the request.
+   */
+  struct GNUNET_CURL_Job *job;
+
+  /**
+   * Function to call with the result.
+   */
+  TALER_EXCHANGE_ManagementUpdateAmlOfficerCallback cb;
+
+  /**
+   * Closure for @a cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Reference to the execution context.
+   */
+  struct GNUNET_CURL_Context *ctx;
+};
+
+
+/**
+ * Function called when we're done processing the
+ * HTTP /management/wire request.
+ *
+ * @param cls the `struct TALER_EXCHANGE_ManagementAuditorEnableHandle *`
+ * @param response_code HTTP response code, 0 on error
+ * @param response response body, NULL if not in JSON
+ */
+static void
+handle_update_aml_officer_finished (void *cls,
+                                    long response_code,
+                                    const void *response)
+{
+  struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *wh = cls;
+  const json_t *json = response;
+  struct TALER_EXCHANGE_HttpResponse hr = {
+    .http_status = (unsigned int) response_code,
+    .reply = json
+  };
+
+  wh->job = NULL;
+  switch (response_code)
+  {
+  case 0:
+    /* no reply */
+    hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+    hr.hint = "server offline?";
+    break;
+  case MHD_HTTP_NO_CONTENT:
+    break;
+  case MHD_HTTP_FORBIDDEN:
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    break;
+  case MHD_HTTP_CONFLICT:
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    break;
+  default:
+    /* unexpected response code */
+    GNUNET_break_op (0);
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unexpected response code %u/%d for exchange management update 
AML officer\n",
+                (unsigned int) response_code,
+                (int) hr.ec);
+    break;
+  }
+  if (NULL != wh->cb)
+  {
+    wh->cb (wh->cb_cls,
+            &hr);
+    wh->cb = NULL;
+  }
+  TALER_EXCHANGE_management_update_aml_officer_cancel (wh);
+}
+
+
+struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *
+TALER_EXCHANGE_management_update_aml_officer (
+  struct GNUNET_CURL_Context *ctx,
+  const char *url,
+  const struct TALER_AmlOfficerPublicKeyP *officer_pub,
+  const char *officer_name,
+  struct GNUNET_TIME_Timestamp change_date,
+  bool is_active,
+  bool read_only,
+  const struct TALER_MasterSignatureP *master_sig,
+  TALER_EXCHANGE_ManagementUpdateAmlOfficerCallback cb,
+  void *cb_cls)
+{
+  struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *wh;
+  CURL *eh;
+  json_t *body;
+
+  wh = GNUNET_new (struct TALER_EXCHANGE_ManagementUpdateAmlOfficer);
+  wh->cb = cb;
+  wh->cb_cls = cb_cls;
+  wh->ctx = ctx;
+  {
+    char *path;
+    char opus[sizeof (*officer_pub) * 2];
+    char *end;
+
+    end = GNUNET_STRINGS_data_to_string (
+      officer_pub,
+      sizeof (*officer_pub),
+      opus,
+      sizeof (opus));
+    *end = '\0';
+    GNUNET_asprintf (&path,
+                     "management/aml-officers/%s",
+                     opus);
+    wh->url = TALER_url_join (url,
+                              path,
+                              NULL);
+    GNUNET_free (path);
+  }
+  if (NULL == wh->url)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Could not construct request URL.\n");
+    GNUNET_free (wh);
+    return NULL;
+  }
+  body = GNUNET_JSON_PACK (
+    GNUNET_JSON_pack_string ("officer_name",
+                             officer_name),
+    GNUNET_JSON_pack_data_auto ("master_sig",
+                                master_sig),
+    GNUNET_JSON_pack_data_bool ("is_active",
+                                is_active),
+    GNUNET_JSON_pack_data_bool ("read_only",
+                                read_only),
+    GNUNET_JSON_pack_timestamp ("change_date",
+                                change_date));
+  eh = TALER_EXCHANGE_curl_easy_get_ (wh->url);
+  if ( (NULL == eh) ||
+       (GNUNET_OK !=
+        TALER_curl_easy_post (&wh->post_ctx,
+                              eh,
+                              body)) )
+  {
+    GNUNET_break (0);
+    if (NULL != eh)
+      curl_easy_cleanup (eh);
+    json_decref (body);
+    GNUNET_free (wh->url);
+    return NULL;
+  }
+  json_decref (body);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Requesting URL '%s'\n",
+              wh->url);
+  wh->job = GNUNET_CURL_job_add2 (ctx,
+                                  eh,
+                                  wh->post_ctx.headers,
+                                  &handle_update_aml_officer_finished,
+                                  wh);
+  if (NULL == wh->job)
+  {
+    TALER_EXCHANGE_management_update_aml_officer_cancel (wh);
+    return NULL;
+  }
+  return wh;
+}
+
+
+void
+TALER_EXCHANGE_management_update_aml_officer_cancel (
+  struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *wh)
+{
+  if (NULL != wh->job)
+  {
+    GNUNET_CURL_job_cancel (wh->job);
+    wh->job = NULL;
+  }
+  TALER_curl_easy_post_finished (&wh->post_ctx);
+  GNUNET_free (wh->url);
+  GNUNET_free (wh);
+}

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