exchange

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

exchange_api_post-auditors-AUDITOR_PUB-H_DENOM_PUB.c (7686B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2015-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   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   TALER; see the file COPYING.  If not, see
     15   <http://www.gnu.org/licenses/>
     16 */
     17 /**
     18  * @file lib/exchange_api_post-auditors-AUDITOR_PUB-H_DENOM_PUB.c
     19  * @brief functions for the auditor to add its signature for denomination at the exchange
     20  * @author Christian Grothoff
     21  */
     22 #include "taler/taler_json_lib.h"
     23 #include <gnunet/gnunet_curl_lib.h>
     24 #include <microhttpd.h>
     25 #include "taler/exchange/post-auditors-AUDITOR_PUB-H_DENOM_PUB.h"
     26 #include "auditor_api_curl_defaults.h"
     27 #include "taler/taler_curl_lib.h"
     28 
     29 
     30 struct TALER_EXCHANGE_PostAuditorsHandle
     31 {
     32 
     33   /**
     34    * The base URL for this request.
     35    */
     36   char *base_url;
     37 
     38   /**
     39    * The full URL for this request, set during _start.
     40    */
     41   char *url;
     42 
     43   /**
     44    * Minor context that holds body and headers.
     45    */
     46   struct TALER_CURL_PostContext post_ctx;
     47 
     48   /**
     49    * Handle for the request.
     50    */
     51   struct GNUNET_CURL_Job *job;
     52 
     53   /**
     54    * Function to call with the result.
     55    */
     56   TALER_EXCHANGE_PostAuditorsCallback cb;
     57 
     58   /**
     59    * Closure for @a cb.
     60    */
     61   TALER_EXCHANGE_POST_AUDITORS_RESULT_CLOSURE *cb_cls;
     62 
     63   /**
     64    * Reference to the execution context.
     65    */
     66   struct GNUNET_CURL_Context *ctx;
     67 
     68   /**
     69    * Hash of the denomination public key.
     70    */
     71   struct TALER_DenominationHashP h_denom_pub;
     72 
     73   /**
     74    * The auditor's public key.
     75    */
     76   struct TALER_AuditorPublicKeyP auditor_pub;
     77 
     78   /**
     79    * The auditor's signature.
     80    */
     81   struct TALER_AuditorSignatureP auditor_sig;
     82 
     83 };
     84 
     85 
     86 /**
     87  * Function called when we're done processing the
     88  * HTTP POST /auditor/$AUDITOR_PUB/$H_DENOM_PUB request.
     89  *
     90  * @param cls the `struct TALER_EXCHANGE_PostAuditorsHandle *`
     91  * @param response_code HTTP response code, 0 on error
     92  * @param response response body, NULL if not in JSON
     93  */
     94 static void
     95 handle_auditor_add_denomination_finished (void *cls,
     96                                           long response_code,
     97                                           const void *response)
     98 {
     99   struct TALER_EXCHANGE_PostAuditorsHandle *ah = cls;
    100   const json_t *json = response;
    101   struct TALER_EXCHANGE_PostAuditorsResponse adr = {
    102     .hr.http_status = (unsigned int) response_code,
    103     .hr.reply = json
    104   };
    105 
    106   ah->job = NULL;
    107   switch (response_code)
    108   {
    109   case MHD_HTTP_NO_CONTENT:
    110     break;
    111   case MHD_HTTP_FORBIDDEN:
    112     adr.hr.ec = TALER_JSON_get_error_code (json);
    113     adr.hr.hint = TALER_JSON_get_error_hint (json);
    114     break;
    115   case MHD_HTTP_NOT_FOUND:
    116     adr.hr.ec = TALER_JSON_get_error_code (json);
    117     adr.hr.hint = TALER_JSON_get_error_hint (json);
    118     break;
    119   case MHD_HTTP_GONE:
    120     adr.hr.ec = TALER_JSON_get_error_code (json);
    121     adr.hr.hint = TALER_JSON_get_error_hint (json);
    122     break;
    123   case MHD_HTTP_PRECONDITION_FAILED:
    124     adr.hr.ec = TALER_JSON_get_error_code (json);
    125     adr.hr.hint = TALER_JSON_get_error_hint (json);
    126     break;
    127   default:
    128     /* unexpected response code */
    129     if (NULL != json)
    130     {
    131       adr.hr.ec = TALER_JSON_get_error_code (json);
    132       adr.hr.hint = TALER_JSON_get_error_hint (json);
    133       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    134                   "Unexpected response code %u/%d for exchange auditor-add-denomination at URL `%s'\n",
    135                   (unsigned int) response_code,
    136                   (int) adr.hr.ec,
    137                   ah->url);
    138     }
    139     else
    140     {
    141       adr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
    142       adr.hr.hint = NULL;
    143       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    144                   "Unexpected HTTP response code %u (no JSON returned) at URL `%s'\n",
    145                   (unsigned int) response_code,
    146                   ah->url);
    147     }
    148     break;
    149   }
    150   if (NULL != ah->cb)
    151   {
    152     ah->cb (ah->cb_cls,
    153             &adr);
    154     ah->cb = NULL;
    155   }
    156   TALER_EXCHANGE_post_auditors_cancel (ah);
    157 }
    158 
    159 
    160 struct TALER_EXCHANGE_PostAuditorsHandle *
    161 TALER_EXCHANGE_post_auditors_create (
    162   struct GNUNET_CURL_Context *ctx,
    163   const char *url,
    164   const struct TALER_DenominationHashP *h_denom_pub,
    165   const struct TALER_AuditorPublicKeyP *auditor_pub,
    166   const struct TALER_AuditorSignatureP *auditor_sig)
    167 {
    168   struct TALER_EXCHANGE_PostAuditorsHandle *ah;
    169 
    170   ah = GNUNET_new (struct TALER_EXCHANGE_PostAuditorsHandle);
    171   ah->ctx = ctx;
    172   ah->base_url = GNUNET_strdup (url);
    173   ah->h_denom_pub = *h_denom_pub;
    174   ah->auditor_pub = *auditor_pub;
    175   ah->auditor_sig = *auditor_sig;
    176   return ah;
    177 }
    178 
    179 
    180 enum TALER_ErrorCode
    181 TALER_EXCHANGE_post_auditors_start (
    182   struct TALER_EXCHANGE_PostAuditorsHandle *ah,
    183   TALER_EXCHANGE_PostAuditorsCallback cb,
    184   TALER_EXCHANGE_POST_AUDITORS_RESULT_CLOSURE *cb_cls)
    185 {
    186   CURL *eh;
    187   json_t *body;
    188 
    189   ah->cb = cb;
    190   ah->cb_cls = cb_cls;
    191   {
    192     char apub_str[sizeof (ah->auditor_pub) * 2];
    193     char denom_str[sizeof (ah->h_denom_pub) * 2];
    194     char arg_str[sizeof (apub_str) + sizeof (denom_str) + 32];
    195     char *end;
    196 
    197     end = GNUNET_STRINGS_data_to_string (&ah->auditor_pub,
    198                                          sizeof (ah->auditor_pub),
    199                                          apub_str,
    200                                          sizeof (apub_str));
    201     *end = '\0';
    202     end = GNUNET_STRINGS_data_to_string (&ah->h_denom_pub,
    203                                          sizeof (ah->h_denom_pub),
    204                                          denom_str,
    205                                          sizeof (denom_str));
    206     *end = '\0';
    207     GNUNET_snprintf (arg_str,
    208                      sizeof (arg_str),
    209                      "auditors/%s/%s",
    210                      apub_str,
    211                      denom_str);
    212     ah->url = TALER_url_join (ah->base_url,
    213                               arg_str,
    214                               NULL);
    215   }
    216   if (NULL == ah->url)
    217   {
    218     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    219                 "Could not construct request URL.\n");
    220     return TALER_EC_GENERIC_CONFIGURATION_INVALID;
    221   }
    222   body = GNUNET_JSON_PACK (
    223     GNUNET_JSON_pack_data_auto ("auditor_sig",
    224                                 &ah->auditor_sig));
    225   eh = TALER_AUDITOR_curl_easy_get_ (ah->url);
    226   if ( (NULL == eh) ||
    227        (GNUNET_OK !=
    228         TALER_curl_easy_post (&ah->post_ctx,
    229                               eh,
    230                               body)) )
    231   {
    232     GNUNET_break (0);
    233     if (NULL != eh)
    234       curl_easy_cleanup (eh);
    235     json_decref (body);
    236     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
    237   }
    238   json_decref (body);
    239   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    240               "Requesting URL '%s'\n",
    241               ah->url);
    242   ah->job = GNUNET_CURL_job_add2 (ah->ctx,
    243                                   eh,
    244                                   ah->post_ctx.headers,
    245                                   &handle_auditor_add_denomination_finished,
    246                                   ah);
    247   if (NULL == ah->job)
    248     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
    249   return TALER_EC_NONE;
    250 }
    251 
    252 
    253 void
    254 TALER_EXCHANGE_post_auditors_cancel (
    255   struct TALER_EXCHANGE_PostAuditorsHandle *ah)
    256 {
    257   if (NULL != ah->job)
    258   {
    259     GNUNET_CURL_job_cancel (ah->job);
    260     ah->job = NULL;
    261   }
    262   TALER_curl_easy_post_finished (&ah->post_ctx);
    263   GNUNET_free (ah->url);
    264   GNUNET_free (ah->base_url);
    265   GNUNET_free (ah);
    266 }
    267 
    268 
    269 /* end of exchange_api_post-auditors-AUDITOR_PUB-H_DENOM_PUB.c */