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-management-wire-disable.c (7659B)


      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-management-wire-disable.c
     19  * @brief functions to disable an exchange wire method / bank account
     20  * @author Christian Grothoff
     21  */
     22 #include "taler/platform.h"
     23 #include "taler/taler_json_lib.h"
     24 #include <gnunet/gnunet_curl_lib.h>
     25 #include <microhttpd.h>
     26 #include "taler/taler_exchange_service.h"
     27 #include "taler/taler-exchange/post-management-wire-disable.h"
     28 #include "exchange_api_curl_defaults.h"
     29 #include "taler/taler_signatures.h"
     30 #include "taler/taler_curl_lib.h"
     31 
     32 
     33 struct TALER_EXCHANGE_PostManagementWireDisableHandle
     34 {
     35 
     36   /**
     37    * The base URL for this request.
     38    */
     39   char *base_url;
     40 
     41   /**
     42    * The full URL for this request, set during _start.
     43    */
     44   char *url;
     45 
     46   /**
     47    * Minor context that holds body and headers.
     48    */
     49   struct TALER_CURL_PostContext post_ctx;
     50 
     51   /**
     52    * Handle for the request.
     53    */
     54   struct GNUNET_CURL_Job *job;
     55 
     56   /**
     57    * Function to call with the result.
     58    */
     59   TALER_EXCHANGE_PostManagementWireDisableCallback cb;
     60 
     61   /**
     62    * Closure for @a cb.
     63    */
     64   TALER_EXCHANGE_POST_MANAGEMENT_WIRE_DISABLE_RESULT_CLOSURE *cb_cls;
     65 
     66   /**
     67    * Reference to the execution context.
     68    */
     69   struct GNUNET_CURL_Context *ctx;
     70 
     71   /**
     72    * Payto URI of the account to disable.
     73    */
     74   char *payto_uri_str;
     75 
     76   /**
     77    * When was this decided?
     78    */
     79   struct GNUNET_TIME_Timestamp validity_end;
     80 
     81   /**
     82    * Signature affirming the wire disablement.
     83    */
     84   struct TALER_MasterSignatureP master_sig;
     85 
     86 };
     87 
     88 
     89 /**
     90  * Function called when we're done processing the
     91  * HTTP POST /management/wire/disable request.
     92  *
     93  * @param cls the `struct TALER_EXCHANGE_PostManagementWireDisableHandle`
     94  * @param response_code HTTP response code, 0 on error
     95  * @param response response body, NULL if not in JSON
     96  */
     97 static void
     98 handle_wire_disable_finished (void *cls,
     99                                long response_code,
    100                                const void *response)
    101 {
    102   struct TALER_EXCHANGE_PostManagementWireDisableHandle *pmwdh = cls;
    103   const json_t *json = response;
    104   struct TALER_EXCHANGE_PostManagementWireDisableResponse res = {
    105     .hr.http_status = (unsigned int) response_code,
    106     .hr.reply = json
    107   };
    108 
    109   pmwdh->job = NULL;
    110   switch (response_code)
    111   {
    112   case 0:
    113     /* no reply */
    114     res.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
    115     res.hr.hint = "server offline?";
    116     break;
    117   case MHD_HTTP_NO_CONTENT:
    118     break;
    119   case MHD_HTTP_FORBIDDEN:
    120     res.hr.ec = TALER_JSON_get_error_code (json);
    121     res.hr.hint = TALER_JSON_get_error_hint (json);
    122     break;
    123   case MHD_HTTP_NOT_FOUND:
    124     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    125                 "Server did not find handler at `%s'. Did you configure the correct exchange base URL?\n",
    126                 pmwdh->url);
    127     if (NULL != json)
    128     {
    129       res.hr.ec = TALER_JSON_get_error_code (json);
    130       res.hr.hint = TALER_JSON_get_error_hint (json);
    131     }
    132     else
    133     {
    134       res.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
    135       res.hr.hint = TALER_ErrorCode_get_hint (res.hr.ec);
    136     }
    137     break;
    138   case MHD_HTTP_CONFLICT:
    139     res.hr.ec = TALER_JSON_get_error_code (json);
    140     res.hr.hint = TALER_JSON_get_error_hint (json);
    141     break;
    142   default:
    143     /* unexpected response code */
    144     GNUNET_break_op (0);
    145     res.hr.ec = TALER_JSON_get_error_code (json);
    146     res.hr.hint = TALER_JSON_get_error_hint (json);
    147     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    148                 "Unexpected response code %u/%d for exchange management disable wire\n",
    149                 (unsigned int) response_code,
    150                 (int) res.hr.ec);
    151     break;
    152   }
    153   if (NULL != pmwdh->cb)
    154   {
    155     pmwdh->cb (pmwdh->cb_cls,
    156                &res);
    157     pmwdh->cb = NULL;
    158   }
    159   TALER_EXCHANGE_post_management_wire_disable_cancel (pmwdh);
    160 }
    161 
    162 
    163 struct TALER_EXCHANGE_PostManagementWireDisableHandle *
    164 TALER_EXCHANGE_post_management_wire_disable_create (
    165   struct GNUNET_CURL_Context *ctx,
    166   const char *exchange_url,
    167   const struct TALER_FullPayto payto_uri,
    168   struct GNUNET_TIME_Timestamp validity_end,
    169   const struct TALER_MasterSignatureP *master_sig)
    170 {
    171   struct TALER_EXCHANGE_PostManagementWireDisableHandle *pmwdh;
    172 
    173   pmwdh = GNUNET_new (struct TALER_EXCHANGE_PostManagementWireDisableHandle);
    174   pmwdh->ctx = ctx;
    175   pmwdh->base_url = GNUNET_strdup (exchange_url);
    176   pmwdh->payto_uri_str = GNUNET_strdup (payto_uri.full_payto);
    177   pmwdh->validity_end = validity_end;
    178   pmwdh->master_sig = *master_sig;
    179   return pmwdh;
    180 }
    181 
    182 
    183 enum TALER_ErrorCode
    184 TALER_EXCHANGE_post_management_wire_disable_start (
    185   struct TALER_EXCHANGE_PostManagementWireDisableHandle *pmwdh,
    186   TALER_EXCHANGE_PostManagementWireDisableCallback cb,
    187   TALER_EXCHANGE_POST_MANAGEMENT_WIRE_DISABLE_RESULT_CLOSURE *cb_cls)
    188 {
    189   CURL *eh;
    190   json_t *body;
    191   struct TALER_FullPayto payto_uri = {
    192     .full_payto = pmwdh->payto_uri_str
    193   };
    194 
    195   pmwdh->cb = cb;
    196   pmwdh->cb_cls = cb_cls;
    197   pmwdh->url = TALER_url_join (pmwdh->base_url,
    198                                "management/wire/disable",
    199                                NULL);
    200   if (NULL == pmwdh->url)
    201   {
    202     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    203                 "Could not construct request URL.\n");
    204     return TALER_EC_GENERIC_CONFIGURATION_INVALID;
    205   }
    206   body = GNUNET_JSON_PACK (
    207     TALER_JSON_pack_full_payto ("payto_uri",
    208                                 payto_uri),
    209     GNUNET_JSON_pack_data_auto ("master_sig_del",
    210                                 &pmwdh->master_sig),
    211     GNUNET_JSON_pack_timestamp ("validity_end",
    212                                 pmwdh->validity_end));
    213   eh = TALER_EXCHANGE_curl_easy_get_ (pmwdh->url);
    214   if ( (NULL == eh) ||
    215        (GNUNET_OK !=
    216         TALER_curl_easy_post (&pmwdh->post_ctx,
    217                               eh,
    218                               body)) )
    219   {
    220     GNUNET_break (0);
    221     if (NULL != eh)
    222       curl_easy_cleanup (eh);
    223     json_decref (body);
    224     GNUNET_free (pmwdh->url);
    225     pmwdh->url = NULL;
    226     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
    227   }
    228   json_decref (body);
    229   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    230               "Requesting URL '%s'\n",
    231               pmwdh->url);
    232   pmwdh->job = GNUNET_CURL_job_add2 (pmwdh->ctx,
    233                                      eh,
    234                                      pmwdh->post_ctx.headers,
    235                                      &handle_wire_disable_finished,
    236                                      pmwdh);
    237   if (NULL == pmwdh->job)
    238   {
    239     TALER_curl_easy_post_finished (&pmwdh->post_ctx);
    240     GNUNET_free (pmwdh->url);
    241     pmwdh->url = NULL;
    242     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
    243   }
    244   return TALER_EC_NONE;
    245 }
    246 
    247 
    248 void
    249 TALER_EXCHANGE_post_management_wire_disable_cancel (
    250   struct TALER_EXCHANGE_PostManagementWireDisableHandle *pmwdh)
    251 {
    252   if (NULL != pmwdh->job)
    253   {
    254     GNUNET_CURL_job_cancel (pmwdh->job);
    255     pmwdh->job = NULL;
    256   }
    257   TALER_curl_easy_post_finished (&pmwdh->post_ctx);
    258   GNUNET_free (pmwdh->payto_uri_str);
    259   GNUNET_free (pmwdh->url);
    260   GNUNET_free (pmwdh->base_url);
    261   GNUNET_free (pmwdh);
    262 }
    263 
    264 
    265 /* end of exchange_api_post-management-wire-disable.c */