exchange

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

exchange_api_management_post_extensions.c (5978B)


      1 /*
      2    This file is part of TALER
      3    Copyright (C) 2015-2023 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_management_post_extensions.c
     19  * @brief functions to handle the settings for extensions (p2p and age restriction)
     20  * @author Özgür Kesim
     21  */
     22 #include "taler/platform.h"
     23 #include "taler/taler_json_lib.h"
     24 #include <gnunet/gnunet_curl_lib.h>
     25 #include "taler/taler_extensions.h"
     26 #include "exchange_api_curl_defaults.h"
     27 #include "taler/taler_exchange_service.h"
     28 #include "taler/taler_signatures.h"
     29 #include "taler/taler_curl_lib.h"
     30 #include "taler/taler_json_lib.h"
     31 
     32 
     33 /**
     34  * @brief Handle for a POST /management/extensions request.
     35  */
     36 struct TALER_EXCHANGE_ManagementPostExtensionsHandle
     37 {
     38 
     39   /**
     40    * The url for this request.
     41    */
     42   char *url;
     43 
     44   /**
     45    * Minor context that holds body and headers.
     46    */
     47   struct TALER_CURL_PostContext post_ctx;
     48 
     49   /**
     50    * Handle for the request.
     51    */
     52   struct GNUNET_CURL_Job *job;
     53 
     54   /**
     55    * Function to call with the result.
     56    */
     57   TALER_EXCHANGE_ManagementPostExtensionsCallback cb;
     58 
     59   /**
     60    * Closure for @a cb.
     61    */
     62   void *cb_cls;
     63 
     64   /**
     65    * Reference to the execution context.
     66    */
     67   struct GNUNET_CURL_Context *ctx;
     68 };
     69 
     70 
     71 /**
     72  * Function called when we're done processing the
     73  * HTTP POST /management/extensions request.
     74  *
     75  * @param cls the `struct TALER_EXCHANGE_ManagementPostExtensionsHandle *`
     76  * @param response_code HTTP response code, 0 on error
     77  * @param response response body, NULL if not in JSON
     78  */
     79 static void
     80 handle_post_extensions_finished (void *cls,
     81                                  long response_code,
     82                                  const void *response)
     83 {
     84   struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph = cls;
     85   const json_t *json = response;
     86   struct TALER_EXCHANGE_ManagementPostExtensionsResponse per = {
     87     .hr.http_status = (unsigned int) response_code,
     88     .hr.reply = json
     89   };
     90 
     91   ph->job = NULL;
     92   switch (response_code)
     93   {
     94   case MHD_HTTP_NO_CONTENT:
     95     break;
     96   case MHD_HTTP_FORBIDDEN:
     97     per.hr.ec = TALER_JSON_get_error_code (json);
     98     per.hr.hint = TALER_JSON_get_error_hint (json);
     99     break;
    100   case MHD_HTTP_NOT_FOUND:
    101     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    102                 "Server did not find handler at `%s'. Did you configure the correct exchange base URL?\n",
    103                 ph->url);
    104     if (NULL != json)
    105     {
    106       per.hr.ec = TALER_JSON_get_error_code (json);
    107       per.hr.hint = TALER_JSON_get_error_hint (json);
    108     }
    109     else
    110     {
    111       per.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
    112       per.hr.hint = TALER_ErrorCode_get_hint (per.hr.ec);
    113     }
    114     break;
    115   default:
    116     /* unexpected response code */
    117     GNUNET_break_op (0);
    118     per.hr.ec = TALER_JSON_get_error_code (json);
    119     per.hr.hint = TALER_JSON_get_error_hint (json);
    120     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    121                 "Unexpected response code %u/%d for exchange management post extensions\n",
    122                 (unsigned int) response_code,
    123                 (int) per.hr.ec);
    124     break;
    125   }
    126   if (NULL != ph->cb)
    127   {
    128     ph->cb (ph->cb_cls,
    129             &per);
    130     ph->cb = NULL;
    131   }
    132   TALER_EXCHANGE_management_post_extensions_cancel (ph);
    133 }
    134 
    135 
    136 struct TALER_EXCHANGE_ManagementPostExtensionsHandle *
    137 TALER_EXCHANGE_management_post_extensions (
    138   struct GNUNET_CURL_Context *ctx,
    139   const char *url,
    140   const struct TALER_EXCHANGE_ManagementPostExtensionsData *ped,
    141   TALER_EXCHANGE_ManagementPostExtensionsCallback cb,
    142   void *cb_cls)
    143 {
    144   struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph;
    145   CURL *eh = NULL;
    146   json_t *body = NULL;
    147 
    148   ph = GNUNET_new (struct TALER_EXCHANGE_ManagementPostExtensionsHandle);
    149   ph->cb = cb;
    150   ph->cb_cls = cb_cls;
    151   ph->ctx = ctx;
    152   ph->url = TALER_url_join (url,
    153                             "management/extensions",
    154                             NULL);
    155   if (NULL == ph->url)
    156   {
    157     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    158                 "Could not construct request URL.\n");
    159     GNUNET_free (ph);
    160     return NULL;
    161   }
    162 
    163   body = GNUNET_JSON_PACK (
    164     GNUNET_JSON_pack_object_steal ("extensions",
    165                                    (json_t *) ped->extensions),
    166     GNUNET_JSON_pack_data_auto ("extensions_sig",
    167                                 &ped->extensions_sig));
    168 
    169   eh = TALER_EXCHANGE_curl_easy_get_ (ph->url);
    170   if ( (NULL == eh) ||
    171        (GNUNET_OK !=
    172         TALER_curl_easy_post (&ph->post_ctx,
    173                               eh,
    174                               body)) )
    175   {
    176     GNUNET_break (0);
    177     if (NULL != eh)
    178       curl_easy_cleanup (eh);
    179     json_decref (body);
    180     GNUNET_free (ph->url);
    181     return NULL;
    182   }
    183   json_decref (body);
    184   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    185               "Requesting URL '%s'\n",
    186               ph->url);
    187   ph->job = GNUNET_CURL_job_add2 (ctx,
    188                                   eh,
    189                                   ph->post_ctx.headers,
    190                                   &handle_post_extensions_finished,
    191                                   ph);
    192   if (NULL == ph->job)
    193   {
    194     TALER_EXCHANGE_management_post_extensions_cancel (ph);
    195     return NULL;
    196   }
    197   return ph;
    198 }
    199 
    200 
    201 void
    202 TALER_EXCHANGE_management_post_extensions_cancel (
    203   struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph)
    204 {
    205   if (NULL != ph->job)
    206   {
    207     GNUNET_CURL_job_cancel (ph->job);
    208     ph->job = NULL;
    209   }
    210   TALER_curl_easy_post_finished (&ph->post_ctx);
    211   GNUNET_free (ph->url);
    212   GNUNET_free (ph);
    213 }