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 (7545B)


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