exchange_api_post-kyc-start-ID.c (6359B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2024-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_post-kyc-start-ID.c 19 * @brief functions to start a KYC process 20 * @author Christian Grothoff 21 */ 22 #include "taler/platform.h" 23 #include "taler/taler_json_lib.h" 24 #include <microhttpd.h> 25 #include <gnunet/gnunet_curl_lib.h> 26 #include "taler/taler_exchange_service.h" 27 #include "taler/taler-exchange/post-kyc-start-ID.h" 28 #include "exchange_api_curl_defaults.h" 29 #include "taler/taler_signatures.h" 30 #include "taler/taler_curl_lib.h" 31 32 33 struct TALER_EXCHANGE_PostKycStartHandle 34 { 35 36 /** 37 * The base URL for this request. 38 */ 39 char *base_url; 40 41 /** 42 * The full URL for this request. 43 */ 44 char *url; 45 46 /** 47 * Minor context that holds body and headers. 48 */ 49 struct TALER_CURL_PostContext post_ctx; 50 51 /** 52 * Handle for the request. 53 */ 54 struct GNUNET_CURL_Job *job; 55 56 /** 57 * Function to call with the result. 58 */ 59 TALER_EXCHANGE_PostKycStartCallback cb; 60 61 /** 62 * Closure for @e cb. 63 */ 64 TALER_EXCHANGE_POST_KYC_START_RESULT_CLOSURE *cb_cls; 65 66 /** 67 * Reference to the execution context. 68 */ 69 struct GNUNET_CURL_Context *ctx; 70 71 /** 72 * Identifier for the KYC process to start. 73 */ 74 char *id; 75 76 }; 77 78 79 /** 80 * Function called when we're done processing the 81 * HTTP POST /kyc-start/$ID request. 82 * 83 * @param cls the `struct TALER_EXCHANGE_PostKycStartHandle *` 84 * @param response_code HTTP response code, 0 on error 85 * @param response response body, NULL if not in JSON 86 */ 87 static void 88 handle_kyc_start_finished (void *cls, 89 long response_code, 90 const void *response) 91 { 92 struct TALER_EXCHANGE_PostKycStartHandle *pksh = cls; 93 const json_t *json = response; 94 struct TALER_EXCHANGE_PostKycStartResponse adr = { 95 .hr.http_status = (unsigned int) response_code, 96 .hr.reply = json 97 }; 98 99 pksh->job = NULL; 100 switch (response_code) 101 { 102 case 0: 103 /* no reply */ 104 adr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; 105 adr.hr.hint = "server offline?"; 106 break; 107 case MHD_HTTP_OK: 108 { 109 struct GNUNET_JSON_Specification spec[] = { 110 GNUNET_JSON_spec_string ( 111 "redirect_url", 112 &adr.details.ok.redirect_url), 113 GNUNET_JSON_spec_end () 114 }; 115 116 if (GNUNET_OK != 117 GNUNET_JSON_parse (json, 118 spec, 119 NULL, NULL)) 120 { 121 GNUNET_break_op (0); 122 adr.hr.http_status = 0; 123 adr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; 124 break; 125 } 126 } 127 break; 128 case MHD_HTTP_NOT_FOUND: 129 break; 130 default: 131 /* unexpected response code */ 132 GNUNET_break_op (0); 133 adr.hr.ec = TALER_JSON_get_error_code (json); 134 adr.hr.hint = TALER_JSON_get_error_hint (json); 135 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 136 "Unexpected response code %u/%d for exchange POST kyc-start\n", 137 (unsigned int) response_code, 138 (int) adr.hr.ec); 139 break; 140 } 141 if (NULL != pksh->cb) 142 { 143 pksh->cb (pksh->cb_cls, 144 &adr); 145 pksh->cb = NULL; 146 } 147 TALER_EXCHANGE_post_kyc_start_cancel (pksh); 148 } 149 150 151 struct TALER_EXCHANGE_PostKycStartHandle * 152 TALER_EXCHANGE_post_kyc_start_create ( 153 struct GNUNET_CURL_Context *ctx, 154 const char *url, 155 const char *id) 156 { 157 struct TALER_EXCHANGE_PostKycStartHandle *pksh; 158 159 pksh = GNUNET_new (struct TALER_EXCHANGE_PostKycStartHandle); 160 pksh->ctx = ctx; 161 pksh->base_url = GNUNET_strdup (url); 162 pksh->id = GNUNET_strdup (id); 163 return pksh; 164 } 165 166 167 enum TALER_ErrorCode 168 TALER_EXCHANGE_post_kyc_start_start ( 169 struct TALER_EXCHANGE_PostKycStartHandle *pksh, 170 TALER_EXCHANGE_PostKycStartCallback cb, 171 TALER_EXCHANGE_POST_KYC_START_RESULT_CLOSURE *cb_cls) 172 { 173 CURL *eh; 174 json_t *body; 175 char *path; 176 177 pksh->cb = cb; 178 pksh->cb_cls = cb_cls; 179 GNUNET_asprintf (&path, 180 "kyc-start/%s", 181 pksh->id); 182 pksh->url = TALER_url_join (pksh->base_url, 183 path, 184 NULL); 185 GNUNET_free (path); 186 if (NULL == pksh->url) 187 { 188 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 189 "Could not construct request URL.\n"); 190 return TALER_EC_GENERIC_CONFIGURATION_INVALID; 191 } 192 body = json_object (); /* as per spec: empty! */ 193 GNUNET_assert (NULL != body); 194 eh = TALER_EXCHANGE_curl_easy_get_ (pksh->url); 195 if ( (NULL == eh) || 196 (GNUNET_OK != 197 TALER_curl_easy_post (&pksh->post_ctx, 198 eh, 199 body)) ) 200 { 201 GNUNET_break (0); 202 if (NULL != eh) 203 curl_easy_cleanup (eh); 204 json_decref (body); 205 GNUNET_free (pksh->url); 206 pksh->url = NULL; 207 return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; 208 } 209 json_decref (body); 210 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 211 "Requesting URL '%s'\n", 212 pksh->url); 213 pksh->job = GNUNET_CURL_job_add2 (pksh->ctx, 214 eh, 215 pksh->post_ctx.headers, 216 &handle_kyc_start_finished, 217 pksh); 218 if (NULL == pksh->job) 219 { 220 TALER_curl_easy_post_finished (&pksh->post_ctx); 221 GNUNET_free (pksh->url); 222 pksh->url = NULL; 223 return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; 224 } 225 return TALER_EC_NONE; 226 } 227 228 229 void 230 TALER_EXCHANGE_post_kyc_start_cancel ( 231 struct TALER_EXCHANGE_PostKycStartHandle *pksh) 232 { 233 if (NULL != pksh->job) 234 { 235 GNUNET_CURL_job_cancel (pksh->job); 236 pksh->job = NULL; 237 } 238 TALER_curl_easy_post_finished (&pksh->post_ctx); 239 GNUNET_free (pksh->url); 240 GNUNET_free (pksh->base_url); 241 GNUNET_free (pksh->id); 242 GNUNET_free (pksh); 243 } 244 245 246 /* end of exchange_api_post-kyc-start-ID.c */