exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

exchange_api_get-aml-OFFICER_PUB.c (6294B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2026 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 */
      9 /**
     10  * @file lib/exchange_api_get-aml-OFFICER_PUB.c
     11  * @brief Implementation of GET /aml/$OFFICER_PUB
     12  */
     13 #include <microhttpd.h>
     14 #include <gnunet/gnunet_util_lib.h>
     15 #include <gnunet/gnunet_curl_lib.h>
     16 #include "taler/taler_json_lib.h"
     17 #include "taler/exchange/get-aml-OFFICER_PUB.h"
     18 #include "exchange_api_handle.h"
     19 #include "taler/taler_signatures.h"
     20 #include "exchange_api_curl_defaults.h"
     21 
     22 
     23 /**
     24  * Handle for GET /aml/$OFFICER_PUB.
     25  */
     26 struct TALER_EXCHANGE_GetAmlOfficerHandle
     27 {
     28   char *base_url;
     29   char *url;
     30   struct GNUNET_CURL_Job *job;
     31   TALER_EXCHANGE_GetAmlOfficerCallback cb;
     32   TALER_EXCHANGE_GET_AML_OFFICER_RESULT_CLOSURE *cb_cls;
     33   struct GNUNET_CURL_Context *ctx;
     34   struct TALER_AmlOfficerPublicKeyP officer_pub;
     35   struct TALER_AmlOfficerPrivateKeyP officer_priv;
     36 };
     37 
     38 
     39 /**
     40  * Process a completed request.
     41  *
     42  * @param cls operation handle
     43  * @param response_code HTTP status, 0 on transport failure
     44  * @param response parsed JSON response
     45  */
     46 static void
     47 handle_get_aml_officer_finished (void *cls,
     48                                  long response_code,
     49                                  const void *response)
     50 {
     51   struct TALER_EXCHANGE_GetAmlOfficerHandle *gaoh = cls;
     52   const json_t *j = response;
     53   struct TALER_EXCHANGE_GetAmlOfficerResponse result = {
     54     .hr.reply = j,
     55     .hr.http_status = (unsigned int) response_code
     56   };
     57 
     58   gaoh->job = NULL;
     59   switch (response_code)
     60   {
     61   case 0:
     62     result.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     63     break;
     64   case MHD_HTTP_OK:
     65     {
     66       struct GNUNET_JSON_Specification spec[] = {
     67         GNUNET_JSON_spec_string (
     68           "officer_name",
     69           &result.details.ok.officer_name),
     70         GNUNET_JSON_spec_bool (
     71           "read_only",
     72           &result.details.ok.read_only),
     73         GNUNET_JSON_spec_end ()
     74       };
     75 
     76       if (GNUNET_OK !=
     77           GNUNET_JSON_parse (j,
     78                              spec,
     79                              NULL,
     80                              NULL))
     81       {
     82         GNUNET_break_op (0);
     83         result.hr.http_status = 0;
     84         result.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
     85       }
     86       break;
     87     }
     88   case MHD_HTTP_BAD_REQUEST:
     89   case MHD_HTTP_FORBIDDEN:
     90   case MHD_HTTP_INTERNAL_SERVER_ERROR:
     91     result.hr.ec = TALER_JSON_get_error_code (j);
     92     result.hr.hint = TALER_JSON_get_error_hint (j);
     93     break;
     94   default:
     95     GNUNET_break_op (0);
     96     result.hr.ec = TALER_JSON_get_error_code (j);
     97     result.hr.hint = TALER_JSON_get_error_hint (j);
     98     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     99                 "Unexpected response code %u/%d for GET AML officer\n",
    100                 (unsigned int) response_code,
    101                 (int) result.hr.ec);
    102     break;
    103   }
    104   gaoh->cb (gaoh->cb_cls,
    105             &result);
    106   gaoh->cb = NULL;
    107   TALER_EXCHANGE_get_aml_officer_cancel (gaoh);
    108 }
    109 
    110 
    111 struct TALER_EXCHANGE_GetAmlOfficerHandle *
    112 TALER_EXCHANGE_get_aml_officer_create (
    113   struct GNUNET_CURL_Context *ctx,
    114   const char *url,
    115   const struct TALER_AmlOfficerPrivateKeyP *officer_priv)
    116 {
    117   struct TALER_EXCHANGE_GetAmlOfficerHandle *gaoh;
    118 
    119   gaoh = GNUNET_new (struct TALER_EXCHANGE_GetAmlOfficerHandle);
    120   gaoh->ctx = ctx;
    121   gaoh->base_url = GNUNET_strdup (url);
    122   gaoh->officer_priv = *officer_priv;
    123   GNUNET_CRYPTO_eddsa_key_get_public (&officer_priv->eddsa_priv,
    124                                       &gaoh->officer_pub.eddsa_pub);
    125   return gaoh;
    126 }
    127 
    128 
    129 enum TALER_ErrorCode
    130 TALER_EXCHANGE_get_aml_officer_start (
    131   struct TALER_EXCHANGE_GetAmlOfficerHandle *gaoh,
    132   TALER_EXCHANGE_GetAmlOfficerCallback cb,
    133   TALER_EXCHANGE_GET_AML_OFFICER_RESULT_CLOSURE *cb_cls)
    134 {
    135   CURL *eh;
    136   struct TALER_AmlOfficerSignatureP officer_sig;
    137   char arg_str[sizeof (struct TALER_AmlOfficerPublicKeyP) * 2 + 16];
    138   struct curl_slist *job_headers = NULL;
    139   char pub_str[sizeof (gaoh->officer_pub) * 2];
    140   char sig_str[sizeof (officer_sig) * 2];
    141   char *end;
    142   char *hdr;
    143 
    144   gaoh->cb = cb;
    145   gaoh->cb_cls = cb_cls;
    146   TALER_officer_aml_query_sign (&gaoh->officer_priv,
    147                                 &officer_sig);
    148   end = GNUNET_STRINGS_data_to_string (&gaoh->officer_pub,
    149                                        sizeof (gaoh->officer_pub),
    150                                        pub_str,
    151                                        sizeof (pub_str));
    152   *end = '\0';
    153   GNUNET_snprintf (arg_str,
    154                    sizeof (arg_str),
    155                    "aml/%s",
    156                    pub_str);
    157   gaoh->url = TALER_url_join (gaoh->base_url,
    158                               arg_str,
    159                               NULL);
    160   if (NULL == gaoh->url)
    161     return TALER_EC_GENERIC_CONFIGURATION_INVALID;
    162   eh = TALER_EXCHANGE_curl_easy_get_ (gaoh->url);
    163   if (NULL == eh)
    164   {
    165     GNUNET_free (gaoh->url);
    166     gaoh->url = NULL;
    167     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
    168   }
    169   end = GNUNET_STRINGS_data_to_string (&officer_sig,
    170                                        sizeof (officer_sig),
    171                                        sig_str,
    172                                        sizeof (sig_str));
    173   *end = '\0';
    174   GNUNET_asprintf (&hdr,
    175                    "%s: %s",
    176                    TALER_AML_OFFICER_SIGNATURE_HEADER,
    177                    sig_str);
    178   job_headers = curl_slist_append (NULL,
    179                                    hdr);
    180   GNUNET_free (hdr);
    181   gaoh->job = GNUNET_CURL_job_add2 (gaoh->ctx,
    182                                     eh,
    183                                     job_headers,
    184                                     &handle_get_aml_officer_finished,
    185                                     gaoh);
    186   curl_slist_free_all (job_headers);
    187   if (NULL == gaoh->job)
    188   {
    189     GNUNET_free (gaoh->url);
    190     gaoh->url = NULL;
    191     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
    192   }
    193   return TALER_EC_NONE;
    194 }
    195 
    196 
    197 void
    198 TALER_EXCHANGE_get_aml_officer_cancel (
    199   struct TALER_EXCHANGE_GetAmlOfficerHandle *gaoh)
    200 {
    201   if (NULL != gaoh->job)
    202   {
    203     GNUNET_CURL_job_cancel (gaoh->job);
    204     gaoh->job = NULL;
    205   }
    206   GNUNET_free (gaoh->url);
    207   GNUNET_free (gaoh->base_url);
    208   GNUNET_free (gaoh);
    209 }
    210 
    211 
    212 /* end of exchange_api_get-aml-OFFICER_PUB.c */