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 (7847B)


      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_OK:
    123     /* KYC process already completed; nothing more to do */
    124     break;
    125   case MHD_HTTP_SEE_OTHER:
    126     {
    127       char *redirect_url;
    128 
    129       GNUNET_assert (CURLE_OK ==
    130                      curl_easy_getinfo (gkph->eh,
    131                                         CURLINFO_REDIRECT_URL,
    132                                         &redirect_url));
    133       gkpr.details.found.redirect_url = redirect_url;
    134       break;
    135     }
    136   case MHD_HTTP_BAD_REQUEST:
    137     /* This should never happen, either us or the exchange is buggy
    138        (or API version conflict); just pass JSON reply to the application */
    139     break;
    140   case MHD_HTTP_UNAUTHORIZED:
    141     break;
    142   case MHD_HTTP_FORBIDDEN:
    143     break;
    144   case MHD_HTTP_NOT_FOUND:
    145     break;
    146   case MHD_HTTP_BAD_GATEWAY:
    147     /* Server had an internal issue; we should retry, but this API
    148        leaves this to the application */
    149     break;
    150   case MHD_HTTP_GATEWAY_TIMEOUT:
    151     /* Server had an internal issue; we should retry, but this API
    152        leaves this to the application */
    153     break;
    154   default:
    155     /* unexpected response code */
    156     GNUNET_break_op (0);
    157     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    158                 "Unexpected response code %u for exchange get_kyc_proof\n",
    159                 (unsigned int) response_code);
    160     break;
    161   }
    162   gkph->cb (gkph->cb_cls,
    163             &gkpr);
    164   TALER_EXCHANGE_get_kyc_proof_cancel (gkph);
    165 }
    166 
    167 
    168 struct TALER_EXCHANGE_GetKycProofHandle *
    169 TALER_EXCHANGE_get_kyc_proof_create (
    170   struct GNUNET_CURL_Context *ctx,
    171   const char *url,
    172   const struct TALER_NormalizedPaytoHashP *h_payto,
    173   const char *logic)
    174 {
    175   struct TALER_EXCHANGE_GetKycProofHandle *gkph;
    176 
    177   gkph = GNUNET_new (struct TALER_EXCHANGE_GetKycProofHandle);
    178   gkph->ctx = ctx;
    179   gkph->base_url = GNUNET_strdup (url);
    180   gkph->h_payto = *h_payto;
    181   gkph->logic = GNUNET_strdup (logic);
    182   return gkph;
    183 }
    184 
    185 
    186 enum GNUNET_GenericReturnValue
    187 TALER_EXCHANGE_get_kyc_proof_set_options_ (
    188   struct TALER_EXCHANGE_GetKycProofHandle *gkph,
    189   unsigned int num_options,
    190   const struct TALER_EXCHANGE_GetKycProofOptionValue *options)
    191 {
    192   for (unsigned int i = 0; i < num_options; i++)
    193   {
    194     const struct TALER_EXCHANGE_GetKycProofOptionValue *opt = &options[i];
    195 
    196     switch (opt->option)
    197     {
    198     case TALER_EXCHANGE_GET_KYC_PROOF_OPTION_END:
    199       return GNUNET_OK;
    200     case TALER_EXCHANGE_GET_KYC_PROOF_OPTION_ARGS:
    201       GNUNET_assert (opt->details.args[0] == '&');
    202       gkph->args = opt->details.args;
    203       break;
    204     }
    205   }
    206   return GNUNET_OK;
    207 }
    208 
    209 
    210 enum TALER_ErrorCode
    211 TALER_EXCHANGE_get_kyc_proof_start (
    212   struct TALER_EXCHANGE_GetKycProofHandle *gkph,
    213   TALER_EXCHANGE_GetKycProofCallback cb,
    214   TALER_EXCHANGE_GET_KYC_PROOF_RESULT_CLOSURE *cb_cls)
    215 {
    216   char *arg_str;
    217 
    218   if (NULL != gkph->job)
    219   {
    220     GNUNET_break (0);
    221     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
    222   }
    223   gkph->cb = cb;
    224   gkph->cb_cls = cb_cls;
    225   {
    226     char hstr[sizeof (gkph->h_payto) * 2];
    227     char *end;
    228 
    229     end = GNUNET_STRINGS_data_to_string (&gkph->h_payto,
    230                                          sizeof (gkph->h_payto),
    231                                          hstr,
    232                                          sizeof (hstr));
    233     *end = '\0';
    234     GNUNET_asprintf (&arg_str,
    235                      "kyc-proof/%s?state=%s%s",
    236                      gkph->logic,
    237                      hstr,
    238                      (NULL != gkph->args) ? gkph->args : "");
    239   }
    240   gkph->url = TALER_url_join (gkph->base_url,
    241                               arg_str,
    242                               NULL);
    243   GNUNET_free (arg_str);
    244   if (NULL == gkph->url)
    245     return TALER_EC_GENERIC_CONFIGURATION_INVALID;
    246   gkph->eh = TALER_EXCHANGE_curl_easy_get_ (gkph->url);
    247   if (NULL == gkph->eh)
    248   {
    249     GNUNET_break (0);
    250     GNUNET_free (gkph->url);
    251     gkph->url = NULL;
    252     return TALER_EC_GENERIC_CONFIGURATION_INVALID;
    253   }
    254   /* disable location following, we want to learn the
    255      result of a 303 redirect! */
    256   curl_easy_setopt (gkph->eh,
    257                     CURLOPT_FOLLOWLOCATION,
    258                     0L);
    259   gkph->job = GNUNET_CURL_job_add_raw (gkph->ctx,
    260                                        gkph->eh,
    261                                        NULL,
    262                                        &handle_get_kyc_proof_finished,
    263                                        gkph);
    264   if (NULL == gkph->job)
    265   {
    266     curl_easy_cleanup (gkph->eh);
    267     gkph->eh = NULL;
    268     GNUNET_free (gkph->url);
    269     gkph->url = NULL;
    270     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
    271   }
    272   return TALER_EC_NONE;
    273 }
    274 
    275 
    276 void
    277 TALER_EXCHANGE_get_kyc_proof_cancel (
    278   struct TALER_EXCHANGE_GetKycProofHandle *gkph)
    279 {
    280   if (NULL != gkph->job)
    281   {
    282     GNUNET_CURL_job_cancel (gkph->job);
    283     gkph->job = NULL;
    284   }
    285   GNUNET_free (gkph->url);
    286   GNUNET_free (gkph->logic);
    287   GNUNET_free (gkph->base_url);
    288   GNUNET_free (gkph);
    289 }
    290 
    291 
    292 /* end of exchange_api_get-kyc-proof-PROVIDER_NAME.c */