exchange

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

exchange_api_get-kyc-proof-PROVIDER_NAME.c (7756B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2021, 2022, 2026 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_get-kyc-proof-PROVIDER_NAME.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 #include "taler/taler-exchange/get-kyc-proof-PROVIDER_NAME.h"
     32 
     33 
     34 /**
     35  * @brief A handle for GET /kyc-proof/$PROVIDER_NAME
     36  */
     37 struct TALER_EXCHANGE_GetKycProofHandle
     38 {
     39 
     40   /**
     41    * The base URL of the exchange.
     42    */
     43   char *base_url;
     44 
     45   /**
     46    * The full URL for this request.
     47    */
     48   char *url;
     49 
     50   /**
     51    * Handle to our CURL request.
     52    */
     53   CURL *eh;
     54 
     55   /**
     56    * Handle for the request.
     57    */
     58   struct GNUNET_CURL_Job *job;
     59 
     60   /**
     61    * Function to call with the result.
     62    */
     63   TALER_EXCHANGE_GetKycProofCallback cb;
     64 
     65   /**
     66    * Closure for @e cb.
     67    */
     68   TALER_EXCHANGE_GET_KYC_PROOF_RESULT_CLOSURE *cb_cls;
     69 
     70   /**
     71    * CURL context to use.
     72    */
     73   struct GNUNET_CURL_Context *ctx;
     74 
     75   /**
     76    * Hash of the payto URI identifying the target account.
     77    */
     78   struct TALER_NormalizedPaytoHashP h_payto;
     79 
     80   /**
     81    * Name of the KYC logic / provider. Heap-allocated copy.
     82    */
     83   char *logic;
     84 
     85   /**
     86    * Additional query string arguments to append to the URL.
     87    * Borrowed pointer (not owned), must start with '&'.
     88    * NULL if not set.
     89    */
     90   const char *args;
     91 
     92 };
     93 
     94 
     95 /**
     96  * Function called when we're done processing the
     97  * HTTP GET /kyc-proof request.
     98  *
     99  * @param cls the `struct TALER_EXCHANGE_GetKycProofHandle`
    100  * @param response_code HTTP response code, 0 on error
    101  * @param body response body
    102  * @param body_size number of bytes in @a body
    103  */
    104 static void
    105 handle_get_kyc_proof_finished (void *cls,
    106                                long response_code,
    107                                const void *body,
    108                                size_t body_size)
    109 {
    110   struct TALER_EXCHANGE_GetKycProofHandle *gkph = cls;
    111   struct TALER_EXCHANGE_GetKycProofResponse gkpr = {
    112     .hr.http_status = (unsigned int) response_code
    113   };
    114 
    115   (void) body;
    116   (void) body_size;
    117   gkph->job = NULL;
    118   switch (response_code)
    119   {
    120   case 0:
    121     break;
    122   case MHD_HTTP_SEE_OTHER:
    123     {
    124       char *redirect_url;
    125 
    126       GNUNET_assert (CURLE_OK ==
    127                      curl_easy_getinfo (gkph->eh,
    128                                         CURLINFO_REDIRECT_URL,
    129                                         &redirect_url));
    130       gkpr.details.found.redirect_url = redirect_url;
    131       break;
    132     }
    133   case MHD_HTTP_BAD_REQUEST:
    134     /* This should never happen, either us or the exchange is buggy
    135        (or API version conflict); just pass JSON reply to the application */
    136     break;
    137   case MHD_HTTP_UNAUTHORIZED:
    138     break;
    139   case MHD_HTTP_FORBIDDEN:
    140     break;
    141   case MHD_HTTP_NOT_FOUND:
    142     break;
    143   case MHD_HTTP_BAD_GATEWAY:
    144     /* Server had an internal issue; we should retry, but this API
    145        leaves this to the application */
    146     break;
    147   case MHD_HTTP_GATEWAY_TIMEOUT:
    148     /* Server had an internal issue; we should retry, but this API
    149        leaves this to the application */
    150     break;
    151   default:
    152     /* unexpected response code */
    153     GNUNET_break_op (0);
    154     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    155                 "Unexpected response code %u for exchange get_kyc_proof\n",
    156                 (unsigned int) response_code);
    157     break;
    158   }
    159   gkph->cb (gkph->cb_cls,
    160             &gkpr);
    161   TALER_EXCHANGE_get_kyc_proof_cancel (gkph);
    162 }
    163 
    164 
    165 struct TALER_EXCHANGE_GetKycProofHandle *
    166 TALER_EXCHANGE_get_kyc_proof_create (
    167   struct GNUNET_CURL_Context *ctx,
    168   const char *url,
    169   const struct TALER_NormalizedPaytoHashP *h_payto,
    170   const char *logic)
    171 {
    172   struct TALER_EXCHANGE_GetKycProofHandle *gkph;
    173 
    174   gkph = GNUNET_new (struct TALER_EXCHANGE_GetKycProofHandle);
    175   gkph->ctx = ctx;
    176   gkph->base_url = GNUNET_strdup (url);
    177   gkph->h_payto = *h_payto;
    178   gkph->logic = GNUNET_strdup (logic);
    179   return gkph;
    180 }
    181 
    182 
    183 enum GNUNET_GenericReturnValue
    184 TALER_EXCHANGE_get_kyc_proof_set_options_ (
    185   struct TALER_EXCHANGE_GetKycProofHandle *gkph,
    186   unsigned int num_options,
    187   const struct TALER_EXCHANGE_GetKycProofOptionValue *options)
    188 {
    189   for (unsigned int i = 0; i < num_options; i++)
    190   {
    191     const struct TALER_EXCHANGE_GetKycProofOptionValue *opt = &options[i];
    192 
    193     switch (opt->option)
    194     {
    195     case TALER_EXCHANGE_GET_KYC_PROOF_OPTION_END:
    196       return GNUNET_OK;
    197     case TALER_EXCHANGE_GET_KYC_PROOF_OPTION_ARGS:
    198       GNUNET_assert (opt->details.args[0] == '&');
    199       gkph->args = opt->details.args;
    200       break;
    201     }
    202   }
    203   return GNUNET_OK;
    204 }
    205 
    206 
    207 enum TALER_ErrorCode
    208 TALER_EXCHANGE_get_kyc_proof_start (
    209   struct TALER_EXCHANGE_GetKycProofHandle *gkph,
    210   TALER_EXCHANGE_GetKycProofCallback cb,
    211   TALER_EXCHANGE_GET_KYC_PROOF_RESULT_CLOSURE *cb_cls)
    212 {
    213   char *arg_str;
    214 
    215   if (NULL != gkph->job)
    216   {
    217     GNUNET_break (0);
    218     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
    219   }
    220   gkph->cb = cb;
    221   gkph->cb_cls = cb_cls;
    222   {
    223     char hstr[sizeof (gkph->h_payto) * 2];
    224     char *end;
    225 
    226     end = GNUNET_STRINGS_data_to_string (&gkph->h_payto,
    227                                          sizeof (gkph->h_payto),
    228                                          hstr,
    229                                          sizeof (hstr));
    230     *end = '\0';
    231     GNUNET_asprintf (&arg_str,
    232                      "kyc-proof/%s?state=%s%s",
    233                      gkph->logic,
    234                      hstr,
    235                      (NULL != gkph->args) ? gkph->args : "");
    236   }
    237   gkph->url = TALER_url_join (gkph->base_url,
    238                               arg_str,
    239                               NULL);
    240   GNUNET_free (arg_str);
    241   if (NULL == gkph->url)
    242     return TALER_EC_GENERIC_CONFIGURATION_INVALID;
    243   gkph->eh = TALER_EXCHANGE_curl_easy_get_ (gkph->url);
    244   if (NULL == gkph->eh)
    245   {
    246     GNUNET_break (0);
    247     GNUNET_free (gkph->url);
    248     gkph->url = NULL;
    249     return TALER_EC_GENERIC_CONFIGURATION_INVALID;
    250   }
    251   /* disable location following, we want to learn the
    252      result of a 303 redirect! */
    253   curl_easy_setopt (gkph->eh,
    254                     CURLOPT_FOLLOWLOCATION,
    255                     0L);
    256   gkph->job = GNUNET_CURL_job_add_raw (gkph->ctx,
    257                                        gkph->eh,
    258                                        NULL,
    259                                        &handle_get_kyc_proof_finished,
    260                                        gkph);
    261   if (NULL == gkph->job)
    262   {
    263     curl_easy_cleanup (gkph->eh);
    264     gkph->eh = NULL;
    265     GNUNET_free (gkph->url);
    266     gkph->url = NULL;
    267     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
    268   }
    269   return TALER_EC_NONE;
    270 }
    271 
    272 
    273 void
    274 TALER_EXCHANGE_get_kyc_proof_cancel (
    275   struct TALER_EXCHANGE_GetKycProofHandle *gkph)
    276 {
    277   if (NULL != gkph->job)
    278   {
    279     GNUNET_CURL_job_cancel (gkph->job);
    280     gkph->job = NULL;
    281   }
    282   GNUNET_free (gkph->url);
    283   GNUNET_free (gkph->logic);
    284   GNUNET_free (gkph->base_url);
    285   GNUNET_free (gkph);
    286 }
    287 
    288 
    289 /* end of exchange_api_get-kyc-proof-PROVIDER_NAME.c */