donau

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

donau_api_csr_post.c (6392B)


      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_csr_post.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 <taler/taler_curl_lib.h>
     28 #include "donau_service.h"
     29 #include "donau_api_curl_defaults.h"
     30 #include "donau_json_lib.h"
     31 
     32 
     33 /**
     34  * Handle for a POST /csr-issue request.
     35  */
     36 struct DONAU_CsRBatchIssueHandle
     37 {
     38   /**
     39    * The url for the /csr-issue request.
     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    * Entry for this request with the `struct GNUNET_CURL_Context`.
     50    */
     51   struct GNUNET_CURL_Job *job;
     52 
     53   /**
     54    * Function to call with the result.
     55    */
     56   DONAU_CsRBatchIssueCallback cb;
     57 
     58   /**
     59    * Closure to pass to @e cb.
     60    */
     61   void *cb_cls;
     62 
     63   /**
     64    * Reference to the execution context.
     65    */
     66   struct GNUNET_CURL_Context *ctx;
     67 
     68 };
     69 
     70 /**
     71  * Function called when we're done processing the
     72  * HTTP POST /csr-issue request.
     73  *
     74  * @param cls the `struct KeysRequest`
     75  * @param response_code HTTP response code, 0 on error
     76  * @param resp_obj parsed JSON result, NULL on error
     77  */
     78 static void
     79 handle_csr_issue_post_finished (void *cls,
     80                                 long response_code,
     81                                 const void *resp_obj)
     82 {
     83   struct DONAU_CsRBatchIssueHandle *csrh = cls;
     84   const json_t *j = resp_obj;
     85 
     86   struct DONAU_CsRBatchIssueResponse csrresp = {
     87     .hr.reply = j,
     88     .hr.http_status = (unsigned int) response_code
     89   };
     90 
     91   csrh->job = NULL;
     92   switch (response_code)
     93   {
     94   case MHD_HTTP_CREATED:
     95     {
     96       struct GNUNET_JSON_Specification spec[] = {
     97         TALER_JSON_spec_exchange_blinding_values (
     98           "ewv",
     99           (struct TALER_ExchangeBlindingValues *) &csrresp.details.ok.alg_values
    100           ),
    101         GNUNET_JSON_spec_end ()
    102       };
    103 
    104       if (GNUNET_OK !=
    105           GNUNET_JSON_parse (j,
    106                              spec,
    107                              NULL,
    108                              NULL))
    109       {
    110         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    111                     "Could not parse response from csr POST\n");
    112         GNUNET_break_op (0);
    113       }
    114       csrh->cb (csrh->cb_cls,
    115                 &csrresp);
    116       csrh->cb = NULL;
    117       break;
    118     }
    119   // Donation unit was revoked.
    120   case MHD_HTTP_GONE:
    121     csrresp.hr.ec = TALER_JSON_get_error_code (j);
    122     csrresp.hr.hint = TALER_JSON_get_error_hint (j);
    123     break;
    124   // Donation unit or endpoint not found.
    125   case MHD_HTTP_NOT_FOUND:
    126     csrresp.hr.ec = TALER_JSON_get_error_code (j);
    127     csrresp.hr.hint = TALER_JSON_get_error_hint (j);
    128     break;
    129   case MHD_HTTP_BAD_REQUEST:
    130     csrresp.hr.ec = TALER_JSON_get_error_code (j);
    131     csrresp.hr.hint = TALER_JSON_get_error_hint (j);
    132     break;
    133   default:
    134     /* unexpected response code */
    135     GNUNET_break_op (0);
    136     csrresp.hr.ec = TALER_JSON_get_error_code (j);
    137     csrresp.hr.hint = TALER_JSON_get_error_hint (j);
    138     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    139                 "Unexpected response code %u/%d for POST %s\n",
    140                 (unsigned int) response_code,
    141                 (int) csrresp.hr.ec,
    142                 csrh->url);
    143     break;
    144   }
    145   if (NULL != csrh->cb)
    146   {
    147     csrh->cb (csrh->cb_cls,
    148               &csrresp);
    149     csrh->cb = NULL;
    150   }
    151   DONAU_csr_cancel (csrh);
    152 }
    153 
    154 
    155 struct DONAU_CsRBatchIssueHandle *
    156 DONAU_csr_issue (
    157   struct GNUNET_CURL_Context *ctx,
    158   const char *url,
    159   const struct DONAU_DonationUnitPublicKey *pk,
    160   const struct GNUNET_CRYPTO_CsSessionNonce *nonce,
    161   DONAU_CsRBatchIssueCallback cb,
    162   void *cb_cls)
    163 {
    164   struct DONAU_CsRBatchIssueHandle *csrh;
    165   CURL *eh;
    166   json_t *body;
    167 
    168   struct DONAU_DonationUnitHashP h_donation_unit_pub;
    169   DONAU_donation_unit_pub_hash (pk,
    170                                 &h_donation_unit_pub);
    171 
    172   TALER_LOG_DEBUG ("Connecting to the donau (%s)\n",
    173                    url);
    174   csrh = GNUNET_new (struct DONAU_CsRBatchIssueHandle);
    175   csrh->url = GNUNET_strdup (url);
    176   csrh->cb = cb;
    177   csrh->cb_cls = cb_cls;
    178   csrh->ctx = ctx;
    179   csrh->url = TALER_url_join (url,
    180                               "csr-issue",
    181                               NULL);
    182   if (NULL == csrh->url)
    183   {
    184     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    185                 "Could not construct requested URL.\n");
    186     GNUNET_free (csrh);
    187     return NULL;
    188   }
    189   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    190               "Request CS R with URL `%s'.\n",
    191               csrh->url);
    192   body = GNUNET_JSON_PACK (
    193     GNUNET_JSON_pack_data_varsize ("nonce",
    194                                    nonce,
    195                                    sizeof(*nonce)),
    196     GNUNET_JSON_pack_data_varsize ("du_pub_hash",
    197                                    &h_donation_unit_pub,
    198                                    sizeof(h_donation_unit_pub)));
    199   eh = DONAU_curl_easy_get_ (csrh->url);
    200   if ( (NULL == eh) ||
    201        (GNUNET_OK !=
    202         TALER_curl_easy_post (&csrh->post_ctx,
    203                               eh,
    204                               body)) )
    205   {
    206     GNUNET_break (0);
    207     if (NULL != eh)
    208       curl_easy_cleanup (eh);
    209     json_decref (body);
    210     GNUNET_free (csrh->url);
    211     return NULL;
    212   }
    213   json_decref (body);
    214   csrh->job = GNUNET_CURL_job_add2 (ctx,
    215                                     eh,
    216                                     csrh->post_ctx.headers,
    217                                     &handle_csr_issue_post_finished,
    218                                     csrh);
    219   return csrh;
    220 }
    221 
    222 
    223 void
    224 DONAU_csr_cancel (
    225   struct DONAU_CsRBatchIssueHandle *csrh)
    226 {
    227   if (NULL != csrh->job)
    228   {
    229     GNUNET_CURL_job_cancel (csrh->job);
    230     csrh->job = NULL;
    231   }
    232   TALER_curl_easy_post_finished (&csrh->post_ctx);
    233   GNUNET_free (csrh->url);
    234   GNUNET_free (csrh);
    235 }