exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

exchange_api_kyc_proof.c (5710B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2021, 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_kyc_proof.c
     19  * @brief Implementation of the /kyc-proof request
     20  * @author Christian Grothoff
     21  */
     22 #include "taler/platform.h"
     23 #include <microhttpd.h> /* just for HTTP proof codes */
     24 #include <gnunet/gnunet_util_lib.h>
     25 #include <gnunet/gnunet_curl_lib.h>
     26 #include "taler/taler_exchange_service.h"
     27 #include "taler/taler_json_lib.h"
     28 #include "exchange_api_handle.h"
     29 #include "taler/taler_signatures.h"
     30 #include "exchange_api_curl_defaults.h"
     31 
     32 
     33 /**
     34  * @brief A ``/kyc-proof`` handle
     35  */
     36 struct TALER_EXCHANGE_KycProofHandle
     37 {
     38 
     39   /**
     40    * The url for this request.
     41    */
     42   char *url;
     43 
     44   /**
     45    * Handle to our CURL request.
     46    */
     47   CURL *eh;
     48 
     49   /**
     50    * Handle for the request.
     51    */
     52   struct GNUNET_CURL_Job *job;
     53 
     54   /**
     55    * Function to call with the result.
     56    */
     57   TALER_EXCHANGE_KycProofCallback cb;
     58 
     59   /**
     60    * Closure for @e cb.
     61    */
     62   void *cb_cls;
     63 
     64 };
     65 
     66 
     67 /**
     68  * Function called when we're done processing the
     69  * HTTP /kyc-proof request.
     70  *
     71  * @param cls the `struct TALER_EXCHANGE_KycProofHandle`
     72  * @param response_code HTTP response code, 0 on error
     73  * @param body response body
     74  * @param body_size number of bytes in @a body
     75  */
     76 static void
     77 handle_kyc_proof_finished (void *cls,
     78                            long response_code,
     79                            const void *body,
     80                            size_t body_size)
     81 {
     82   struct TALER_EXCHANGE_KycProofHandle *kph = cls;
     83   struct TALER_EXCHANGE_KycProofResponse kpr = {
     84     .hr.http_status = (unsigned int) response_code
     85   };
     86 
     87   (void) body;
     88   (void) body_size;
     89   kph->job = NULL;
     90   switch (response_code)
     91   {
     92   case 0:
     93     break;
     94   case MHD_HTTP_SEE_OTHER:
     95     {
     96       char *redirect_url;
     97 
     98       GNUNET_assert (CURLE_OK ==
     99                      curl_easy_getinfo (kph->eh,
    100                                         CURLINFO_REDIRECT_URL,
    101                                         &redirect_url));
    102       kpr.details.found.redirect_url = redirect_url;
    103       break;
    104     }
    105   case MHD_HTTP_BAD_REQUEST:
    106     /* This should never happen, either us or the exchange is buggy
    107        (or API version conflict); just pass JSON reply to the application */
    108     break;
    109   case MHD_HTTP_UNAUTHORIZED:
    110     break;
    111   case MHD_HTTP_FORBIDDEN:
    112     break;
    113   case MHD_HTTP_NOT_FOUND:
    114     break;
    115   case MHD_HTTP_BAD_GATEWAY:
    116     /* Server had an internal issue; we should retry, but this API
    117        leaves this to the application */
    118     break;
    119   case MHD_HTTP_GATEWAY_TIMEOUT:
    120     /* Server had an internal issue; we should retry, but this API
    121        leaves this to the application */
    122     break;
    123   default:
    124     /* unexpected response code */
    125     GNUNET_break_op (0);
    126     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    127                 "Unexpected response code %u for exchange kyc_proof\n",
    128                 (unsigned int) response_code);
    129     break;
    130   }
    131   kph->cb (kph->cb_cls,
    132            &kpr);
    133   TALER_EXCHANGE_kyc_proof_cancel (kph);
    134 }
    135 
    136 
    137 struct TALER_EXCHANGE_KycProofHandle *
    138 TALER_EXCHANGE_kyc_proof (
    139   struct GNUNET_CURL_Context *ctx,
    140   const char *url,
    141   const struct TALER_NormalizedPaytoHashP *h_payto,
    142   const char *logic,
    143   const char *args,
    144   TALER_EXCHANGE_KycProofCallback cb,
    145   void *cb_cls)
    146 {
    147   struct TALER_EXCHANGE_KycProofHandle *kph;
    148   char *arg_str;
    149 
    150   if (NULL == args)
    151     args = "";
    152   else
    153     GNUNET_assert (args[0] == '&');
    154   {
    155     char hstr[sizeof (*h_payto) * 2];
    156     char *end;
    157 
    158     end = GNUNET_STRINGS_data_to_string (h_payto,
    159                                          sizeof (*h_payto),
    160                                          hstr,
    161                                          sizeof (hstr));
    162     *end = '\0';
    163     GNUNET_asprintf (&arg_str,
    164                      "kyc-proof/%s?state=%s%s",
    165                      logic,
    166                      hstr,
    167                      args);
    168   }
    169   kph = GNUNET_new (struct TALER_EXCHANGE_KycProofHandle);
    170   kph->cb = cb;
    171   kph->cb_cls = cb_cls;
    172   kph->url = TALER_url_join (url,
    173                              arg_str,
    174                              NULL);
    175   GNUNET_free (arg_str);
    176   if (NULL == kph->url)
    177   {
    178     GNUNET_free (kph);
    179     return NULL;
    180   }
    181   kph->eh = TALER_EXCHANGE_curl_easy_get_ (kph->url);
    182   if (NULL == kph->eh)
    183   {
    184     GNUNET_break (0);
    185     GNUNET_free (kph->url);
    186     GNUNET_free (kph);
    187     return NULL;
    188   }
    189   /* disable location following, we want to learn the
    190      result of a 303 redirect! */
    191   GNUNET_assert (CURLE_OK ==
    192                  curl_easy_setopt (kph->eh,
    193                                    CURLOPT_FOLLOWLOCATION,
    194                                    0L));
    195   kph->job = GNUNET_CURL_job_add_raw (ctx,
    196                                       kph->eh,
    197                                       NULL,
    198                                       &handle_kyc_proof_finished,
    199                                       kph);
    200   return kph;
    201 }
    202 
    203 
    204 void
    205 TALER_EXCHANGE_kyc_proof_cancel (struct TALER_EXCHANGE_KycProofHandle *kph)
    206 {
    207   if (NULL != kph->job)
    208   {
    209     GNUNET_CURL_job_cancel (kph->job);
    210     kph->job = NULL;
    211   }
    212   GNUNET_free (kph->url);
    213   GNUNET_free (kph);
    214 }
    215 
    216 
    217 /* end of exchange_api_kyc_proof.c */