LCOV - code coverage report
Current view: top level - lib - exchange_api_purse_delete.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 51.2 % 80 41
Test Date: 2025-12-28 14:06:02 Functions: 100.0 % 3 3

            Line data    Source code
       1              : /*
       2              :    This file is part of TALER
       3              :    Copyright (C) 2022 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_purse_delete.c
      19              :  * @brief Implementation of the client to delete a purse
      20              :  *        into an account
      21              :  * @author Christian Grothoff
      22              :  */
      23              : #include "taler/platform.h"
      24              : #include <jansson.h>
      25              : #include <microhttpd.h> /* just for HTTP status codes */
      26              : #include <gnunet/gnunet_util_lib.h>
      27              : #include <gnunet/gnunet_json_lib.h>
      28              : #include <gnunet/gnunet_curl_lib.h>
      29              : #include "taler/taler_json_lib.h"
      30              : #include "taler/taler_exchange_service.h"
      31              : #include "exchange_api_handle.h"
      32              : #include "exchange_api_common.h"
      33              : #include "taler/taler_signatures.h"
      34              : #include "exchange_api_curl_defaults.h"
      35              : 
      36              : 
      37              : /**
      38              :  * @brief A purse delete with deposit handle
      39              :  */
      40              : struct TALER_EXCHANGE_PurseDeleteHandle
      41              : {
      42              : 
      43              :   /**
      44              :    * The url for this request.
      45              :    */
      46              :   char *url;
      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_PurseDeleteCallback cb;
      57              : 
      58              :   /**
      59              :    * Closure for @a cb.
      60              :    */
      61              :   void *cb_cls;
      62              : 
      63              :   /**
      64              :    * Header with the purse_sig.
      65              :    */
      66              :   struct curl_slist *xhdr;
      67              : };
      68              : 
      69              : 
      70              : /**
      71              :  * Function called when we're done processing the
      72              :  * HTTP DELETE /purse/$PID request.
      73              :  *
      74              :  * @param cls the `struct TALER_EXCHANGE_PurseDeleteHandle`
      75              :  * @param response_code HTTP response code, 0 on error
      76              :  * @param response parsed JSON result, NULL on error
      77              :  */
      78              : static void
      79            2 : handle_purse_delete_finished (void *cls,
      80              :                               long response_code,
      81              :                               const void *response)
      82              : {
      83            2 :   struct TALER_EXCHANGE_PurseDeleteHandle *pdh = cls;
      84            2 :   const json_t *j = response;
      85            2 :   struct TALER_EXCHANGE_PurseDeleteResponse dr = {
      86              :     .hr.reply = j,
      87            2 :     .hr.http_status = (unsigned int) response_code
      88              :   };
      89              : 
      90            2 :   pdh->job = NULL;
      91            2 :   switch (response_code)
      92              :   {
      93            0 :   case 0:
      94            0 :     dr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
      95            0 :     break;
      96            2 :   case MHD_HTTP_NO_CONTENT:
      97            2 :     break;
      98            0 :   case MHD_HTTP_BAD_REQUEST:
      99              :     /* This should never happen, either us or the exchange is buggy
     100              :        (or API version conflict); just pass JSON reply to the application */
     101            0 :     dr.hr.ec = TALER_JSON_get_error_code (j);
     102            0 :     dr.hr.hint = TALER_JSON_get_error_hint (j);
     103            0 :     break;
     104            0 :   case MHD_HTTP_FORBIDDEN:
     105            0 :     dr.hr.ec = TALER_JSON_get_error_code (j);
     106            0 :     dr.hr.hint = TALER_JSON_get_error_hint (j);
     107              :     /* Nothing really to verify, exchange says one of the signatures is
     108              :        invalid; as we checked them, this should never happen, we
     109              :        should pass the JSON reply to the application */
     110            0 :     break;
     111            0 :   case MHD_HTTP_NOT_FOUND:
     112            0 :     dr.hr.ec = TALER_JSON_get_error_code (j);
     113            0 :     dr.hr.hint = TALER_JSON_get_error_hint (j);
     114              :     /* Nothing really to verify, this should never
     115              :        happen, we should pass the JSON reply to the application */
     116            0 :     break;
     117            0 :   case MHD_HTTP_CONFLICT:
     118            0 :     dr.hr.ec = TALER_JSON_get_error_code (j);
     119            0 :     dr.hr.hint = TALER_JSON_get_error_hint (j);
     120            0 :     break;
     121            0 :   case MHD_HTTP_INTERNAL_SERVER_ERROR:
     122            0 :     dr.hr.ec = TALER_JSON_get_error_code (j);
     123            0 :     dr.hr.hint = TALER_JSON_get_error_hint (j);
     124              :     /* Server had an internal issue; we should retry, but this API
     125              :        leaves this to the application */
     126            0 :     break;
     127            0 :   default:
     128              :     /* unexpected response code */
     129            0 :     dr.hr.ec = TALER_JSON_get_error_code (j);
     130            0 :     dr.hr.hint = TALER_JSON_get_error_hint (j);
     131            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     132              :                 "Unexpected response code %u/%d for exchange deposit\n",
     133              :                 (unsigned int) response_code,
     134              :                 dr.hr.ec);
     135            0 :     GNUNET_break_op (0);
     136            0 :     break;
     137              :   }
     138            2 :   pdh->cb (pdh->cb_cls,
     139              :            &dr);
     140            2 :   TALER_EXCHANGE_purse_delete_cancel (pdh);
     141            2 : }
     142              : 
     143              : 
     144              : struct TALER_EXCHANGE_PurseDeleteHandle *
     145            2 : TALER_EXCHANGE_purse_delete (
     146              :   struct GNUNET_CURL_Context *ctx,
     147              :   const char *url,
     148              :   const struct TALER_PurseContractPrivateKeyP *purse_priv,
     149              :   TALER_EXCHANGE_PurseDeleteCallback cb,
     150              :   void *cb_cls)
     151              : {
     152              :   struct TALER_EXCHANGE_PurseDeleteHandle *pdh;
     153              :   CURL *eh;
     154              :   struct TALER_PurseContractPublicKeyP purse_pub;
     155              :   struct TALER_PurseContractSignatureP purse_sig;
     156              :   char arg_str[sizeof (purse_pub) * 2 + 32];
     157              : 
     158            2 :   pdh = GNUNET_new (struct TALER_EXCHANGE_PurseDeleteHandle);
     159            2 :   pdh->cb = cb;
     160            2 :   pdh->cb_cls = cb_cls;
     161            2 :   GNUNET_CRYPTO_eddsa_key_get_public (&purse_priv->eddsa_priv,
     162              :                                       &purse_pub.eddsa_pub);
     163              :   {
     164              :     char pub_str[sizeof (purse_pub) * 2];
     165              :     char *end;
     166              : 
     167            2 :     end = GNUNET_STRINGS_data_to_string (&purse_pub,
     168              :                                          sizeof (purse_pub),
     169              :                                          pub_str,
     170              :                                          sizeof (pub_str));
     171            2 :     *end = '\0';
     172            2 :     GNUNET_snprintf (arg_str,
     173              :                      sizeof (arg_str),
     174              :                      "purses/%s",
     175              :                      pub_str);
     176              :   }
     177            2 :   pdh->url = TALER_url_join (url,
     178              :                              arg_str,
     179              :                              NULL);
     180            2 :   if (NULL == pdh->url)
     181              :   {
     182            0 :     GNUNET_break (0);
     183            0 :     GNUNET_free (pdh);
     184            0 :     return NULL;
     185              :   }
     186            2 :   TALER_wallet_purse_delete_sign (purse_priv,
     187              :                                   &purse_sig);
     188              :   {
     189              :     char *delete_str;
     190              :     char *xhdr;
     191              : 
     192              :     delete_str =
     193            2 :       GNUNET_STRINGS_data_to_string_alloc (&purse_sig,
     194              :                                            sizeof (purse_sig));
     195            2 :     GNUNET_asprintf (&xhdr,
     196              :                      "Taler-Purse-Signature: %s",
     197              :                      delete_str);
     198            2 :     GNUNET_free (delete_str);
     199            2 :     pdh->xhdr = curl_slist_append (NULL,
     200              :                                    xhdr);
     201            2 :     GNUNET_free (xhdr);
     202              :   }
     203            2 :   eh = TALER_EXCHANGE_curl_easy_get_ (pdh->url);
     204            2 :   if (NULL == eh)
     205              :   {
     206            0 :     GNUNET_break (0);
     207            0 :     curl_slist_free_all (pdh->xhdr);
     208            0 :     GNUNET_free (pdh->url);
     209            0 :     GNUNET_free (pdh);
     210            0 :     return NULL;
     211              :   }
     212            2 :   GNUNET_assert (CURLE_OK ==
     213              :                  curl_easy_setopt (eh,
     214              :                                    CURLOPT_CUSTOMREQUEST,
     215              :                                    MHD_HTTP_METHOD_DELETE));
     216            2 :   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
     217              :               "URL for purse delete: `%s'\n",
     218              :               pdh->url);
     219            4 :   pdh->job = GNUNET_CURL_job_add2 (ctx,
     220              :                                    eh,
     221            2 :                                    pdh->xhdr,
     222              :                                    &handle_purse_delete_finished,
     223              :                                    pdh);
     224            2 :   return pdh;
     225              : }
     226              : 
     227              : 
     228              : void
     229            2 : TALER_EXCHANGE_purse_delete_cancel (
     230              :   struct TALER_EXCHANGE_PurseDeleteHandle *pdh)
     231              : {
     232            2 :   if (NULL != pdh->job)
     233              :   {
     234            0 :     GNUNET_CURL_job_cancel (pdh->job);
     235            0 :     pdh->job = NULL;
     236              :   }
     237            2 :   curl_slist_free_all (pdh->xhdr);
     238            2 :   GNUNET_free (pdh->url);
     239            2 :   GNUNET_free (pdh);
     240            2 : }
     241              : 
     242              : 
     243              : /* end of exchange_api_purse_delete.c */
        

Generated by: LCOV version 2.0-1