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


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