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

          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 "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_json_lib.h"
      30             : #include "taler_exchange_service.h"
      31             : #include "exchange_api_handle.h"
      32             : #include "exchange_api_common.h"
      33             : #include "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 1.16