donau

Donation authority for GNU Taler (experimental)
Log | Files | Refs | Submodules | README | LICENSE

donau_api_charity_delete.c (6435B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2024 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it
      6   under the terms of the GNU General Public License as published
      7   by the Free Software Foundation; either version 3, or (at your
      8   option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful, but
     11   WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13   GNU General Public License for more details.
     14 
     15   You should have received a copy of the GNU General Public
     16   License along with TALER; see the file COPYING.  If not, see
     17   <http://www.gnu.org/licenses/>
     18 */
     19 
     20 /**
     21  * @file lib/donau_api_charity_delete.c
     22  * @brief Implementation of the "handle" component of the donau's HTTP API
     23  * @author Lukas Matyja
     24  */
     25 #include <gnunet/gnunet_curl_lib.h>
     26 #include <taler/taler_json_lib.h>
     27 #include "donau_service.h"
     28 #include "donau_api_curl_defaults.h"
     29 #include "donau_json_lib.h"
     30 
     31 
     32 /**
     33  * Handle for a GET /charities/$CHARITY_ID request.
     34  */
     35 struct DONAU_CharityDeleteHandle
     36 {
     37   /**
     38    * The url for the /charities/$CHARITY_ID request.
     39    */
     40   char *url;
     41 
     42   /**
     43    * Entry for this request with the `struct GNUNET_CURL_Context`.
     44    */
     45   struct GNUNET_CURL_Job *job;
     46 
     47   /**
     48    * Function to call with the result.
     49    */
     50   DONAU_DeleteCharityResponseCallback cb;
     51 
     52   /**
     53    * Charity id we are querying.
     54    */
     55   unsigned long long charity_id;
     56 
     57   /**
     58    * Closure to pass to @e cb.
     59    */
     60   void *cb_cls;
     61 
     62 };
     63 
     64 
     65 /**
     66  * Callback used when downloading the reply to a /charity request
     67  * is complete.
     68  *
     69  * @param cls the `struct KeysRequest`
     70  * @param response_code HTTP response code, 0 on error
     71  * @param resp_obj parsed JSON result, NULL on error
     72  */
     73 static void
     74 handle_charity_delete_finished (void *cls,
     75                                 long response_code,
     76                                 const void *resp_obj)
     77 {
     78   struct DONAU_CharityDeleteHandle *cdh = cls;
     79   const json_t *j = resp_obj;
     80   struct DONAU_DeleteCharityResponse dcresp = {
     81     .hr.reply = j,
     82     .hr.http_status = (unsigned int) response_code
     83   };
     84 
     85   cdh->job = NULL;
     86   switch (response_code)
     87   {
     88   case 0:
     89     dcresp.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     90     break;
     91   case MHD_HTTP_NO_CONTENT:
     92     break;
     93   case MHD_HTTP_BAD_REQUEST:
     94     /* This should never happen, either us or the exchange is buggy
     95        (or API version conflict); just pass JSON reply to the application */
     96     dcresp.hr.ec = TALER_JSON_get_error_code (j);
     97     dcresp.hr.hint = TALER_JSON_get_error_hint (j);
     98     break;
     99   case MHD_HTTP_FORBIDDEN:
    100     dcresp.hr.ec = TALER_JSON_get_error_code (j);
    101     dcresp.hr.hint = TALER_JSON_get_error_hint (j);
    102     /* Nothing really to verify, exchange says one of the signatures is
    103        invalid; as we checked them, this should never happen, we
    104        should pass the JSON reply to the application */
    105     break;
    106   case MHD_HTTP_NOT_FOUND:
    107     dcresp.hr.ec = TALER_JSON_get_error_code (j);
    108     dcresp.hr.hint = TALER_JSON_get_error_hint (j);
    109     /* Nothing really to verify, this should never
    110        happen, we should pass the JSON reply to the application */
    111     break;
    112   case MHD_HTTP_CONFLICT:
    113     dcresp.hr.ec = TALER_JSON_get_error_code (j);
    114     dcresp.hr.hint = TALER_JSON_get_error_hint (j);
    115     break;
    116   case MHD_HTTP_INTERNAL_SERVER_ERROR:
    117     dcresp.hr.ec = TALER_JSON_get_error_code (j);
    118     dcresp.hr.hint = TALER_JSON_get_error_hint (j);
    119     /* Server had an internal issue; we should retry, but this API
    120        leaves this to the application */
    121     break;
    122   default:
    123     /* unexpected response code */
    124     GNUNET_break_op (0);
    125     dcresp.hr.ec = TALER_JSON_get_error_code (j);
    126     dcresp.hr.hint = TALER_JSON_get_error_hint (j);
    127     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    128                 "Unexpected response code %u/%d for DELETE %s\n",
    129                 (unsigned int) response_code,
    130                 (int) dcresp.hr.ec,
    131                 cdh->url);
    132     break;
    133   }
    134   if (NULL != cdh->cb)
    135   {
    136     cdh->cb (cdh->cb_cls,
    137              &dcresp);
    138     cdh->cb = NULL;
    139   }
    140   DONAU_charity_delete_cancel (cdh);
    141 }
    142 
    143 
    144 struct DONAU_CharityDeleteHandle *
    145 DONAU_charity_delete (
    146   struct GNUNET_CURL_Context *ctx,
    147   const char *url,
    148   const uint64_t id,
    149   const struct DONAU_BearerToken *bearer,
    150   DONAU_DeleteCharityResponseCallback cb,
    151   void *cb_cls)
    152 {
    153   struct DONAU_CharityDeleteHandle *cdh;
    154   CURL *eh;
    155   char arg_str[sizeof (id) * 2 + 32];
    156 
    157   TALER_LOG_DEBUG ("Connecting to the donau (%s)\n",
    158                    url);
    159   cdh = GNUNET_new (struct DONAU_CharityDeleteHandle);
    160   cdh->url = GNUNET_strdup (url);
    161   cdh->cb = cb;
    162   cdh->charity_id = id;
    163   cdh->cb_cls = cb_cls;
    164   GNUNET_snprintf (arg_str,
    165                    sizeof (arg_str),
    166                    "charities/%llu",
    167                    (unsigned long long)
    168                    id);
    169   cdh->url = TALER_url_join (url,
    170                              arg_str,
    171                              NULL);
    172   if (NULL == cdh->url)
    173   {
    174     GNUNET_free (cdh);
    175     return NULL;
    176   }
    177   eh = DONAU_curl_easy_get_ (cdh->url);
    178   if (NULL == eh)
    179   {
    180     GNUNET_break (0);
    181     GNUNET_free (cdh->url);
    182     GNUNET_free (cdh);
    183     return NULL;
    184   }
    185   GNUNET_assert (CURLE_OK ==
    186                  curl_easy_setopt (eh,
    187                                    CURLOPT_CUSTOMREQUEST,
    188                                    MHD_HTTP_METHOD_DELETE));
    189   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    190               "Requesting charity deletion with URL `%s'.\n",
    191               cdh->url);
    192   cdh->job = GNUNET_CURL_job_add_with_ct_json (ctx,
    193                                                eh,
    194                                                &handle_charity_delete_finished,
    195                                                cdh);
    196   GNUNET_assert (NULL != cdh->job);
    197   if (NULL != bearer)
    198   {
    199     struct curl_slist *auth;
    200     char *hdr;
    201 
    202     GNUNET_asprintf (&hdr,
    203                      "%s: Bearer %s",
    204                      MHD_HTTP_HEADER_AUTHORIZATION,
    205                      bearer->token);
    206     auth = curl_slist_append (NULL,
    207                               hdr);
    208     GNUNET_free (hdr);
    209     GNUNET_CURL_extend_headers (cdh->job,
    210                                 auth);
    211     curl_slist_free_all (auth);
    212   }
    213   return cdh;
    214 }
    215 
    216 
    217 void
    218 DONAU_charity_delete_cancel (
    219   struct DONAU_CharityDeleteHandle *cdh)
    220 {
    221   if (NULL != cdh->job)
    222   {
    223     GNUNET_CURL_job_cancel (cdh->job);
    224     cdh->job = NULL;
    225   }
    226   GNUNET_free (cdh->url);
    227   GNUNET_free (cdh);
    228 }