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 */