testing_api_cmd_post_kyc_form.c (7594B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2024 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as 7 published by the Free Software Foundation; either version 3, or 8 (at your option) any later version. 9 10 TALER is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public 16 License along with TALER; see the file COPYING. If not, see 17 <http://www.gnu.org/licenses/> 18 */ 19 20 /** 21 * @file testing/testing_api_cmd_post_kyc_form.c 22 * @brief Implement the testing CMDs for a POST /kyc-form operation. 23 * @author Christian Grothoff 24 */ 25 #include "taler/taler_json_lib.h" 26 #include <gnunet/gnunet_curl_lib.h> 27 #include "taler/taler_testing_lib.h" 28 29 /** 30 * State for a POST /kyc-upload/$ID CMD. 31 */ 32 struct PostKycFormState 33 { 34 35 /** 36 * Command that did a GET on /kyc-info 37 */ 38 const char *kyc_info_reference; 39 40 /** 41 * Index of the requirement to form. 42 */ 43 unsigned int requirement_index; 44 45 /** 46 * Expected HTTP response code. 47 */ 48 unsigned int expected_response_code; 49 50 /** 51 * HTTP header to use. 52 */ 53 struct curl_slist *form_header; 54 55 /** 56 * Form data to POST. 57 */ 58 const char *form_data; 59 60 /** 61 * Curl handle performing the POST. 62 */ 63 struct GNUNET_CURL_Job *job; 64 65 /** 66 * Interpreter state. 67 */ 68 struct TALER_TESTING_Interpreter *is; 69 }; 70 71 72 /** 73 * Handle response to the command. 74 * 75 * @param cls closure. 76 * @param response_code HTTP response code from server, 0 on hard error 77 * @param response in JSON, NULL if response was not in JSON format 78 */ 79 static void 80 post_kyc_form_cb ( 81 void *cls, 82 long response_code, 83 const void *response) 84 { 85 struct PostKycFormState *kcg = cls; 86 struct TALER_TESTING_Interpreter *is = kcg->is; 87 88 (void) response; 89 kcg->job = NULL; 90 if (kcg->expected_response_code != response_code) 91 { 92 TALER_TESTING_unexpected_status (is, 93 (unsigned int) response_code, 94 kcg->expected_response_code); 95 return; 96 } 97 TALER_TESTING_interpreter_next (kcg->is); 98 } 99 100 101 /** 102 * Get a curl handle with the right defaults. 103 * 104 * @param url URL to query 105 */ 106 static CURL * 107 curl_easy_setup (const char *url) 108 { 109 CURL *eh; 110 111 eh = curl_easy_init (); 112 if (NULL == eh) 113 { 114 GNUNET_break (0); 115 return NULL; 116 } 117 GNUNET_assert (CURLE_OK == 118 curl_easy_setopt (eh, 119 CURLOPT_URL, 120 url)); 121 /* Enable compression (using whatever curl likes), see 122 https://curl.se/libcurl/c/CURLOPT_ACCEPT_ENCODING.html */ 123 GNUNET_break (CURLE_OK == 124 curl_easy_setopt (eh, 125 CURLOPT_ACCEPT_ENCODING, 126 "")); 127 GNUNET_assert (CURLE_OK == 128 curl_easy_setopt (eh, 129 CURLOPT_TCP_FASTOPEN, 130 1L)); 131 return eh; 132 } 133 134 135 /** 136 * Run the command. 137 * 138 * @param cls closure. 139 * @param cmd the command to execute. 140 * @param is the interpreter state. 141 */ 142 static void 143 post_kyc_form_run (void *cls, 144 const struct TALER_TESTING_Command *cmd, 145 struct TALER_TESTING_Interpreter *is) 146 { 147 struct PostKycFormState *kcg = cls; 148 const struct TALER_TESTING_Command *res_cmd; 149 const char *id; 150 CURL *eh; 151 152 (void) cmd; 153 kcg->is = is; 154 res_cmd = TALER_TESTING_interpreter_lookup_command ( 155 kcg->is, 156 kcg->kyc_info_reference); 157 if (NULL == res_cmd) 158 { 159 GNUNET_break (0); 160 TALER_TESTING_interpreter_fail (kcg->is); 161 return; 162 } 163 if (GNUNET_OK != 164 TALER_TESTING_get_trait_kyc_id ( 165 res_cmd, 166 kcg->requirement_index, 167 &id)) 168 { 169 GNUNET_break (0); 170 TALER_TESTING_interpreter_fail (kcg->is); 171 return; 172 } 173 if (NULL == id) 174 { 175 GNUNET_break (0); 176 TALER_TESTING_interpreter_fail (kcg->is); 177 return; 178 } 179 { 180 char *url; 181 182 GNUNET_asprintf (&url, 183 "%skyc-upload/%s", 184 TALER_TESTING_get_exchange_url (is), 185 id); 186 eh = curl_easy_setup (url); 187 if (NULL == eh) 188 { 189 GNUNET_break (0); 190 GNUNET_free (url); 191 TALER_TESTING_interpreter_fail (kcg->is); 192 return; 193 } 194 GNUNET_free (url); 195 } 196 GNUNET_assert ( 197 CURLE_OK == 198 curl_easy_setopt (eh, 199 CURLOPT_POST, 200 1L)); 201 GNUNET_assert ( 202 CURLE_OK == 203 curl_easy_setopt (eh, 204 CURLOPT_POSTFIELDS, 205 kcg->form_data)); 206 GNUNET_assert ( 207 CURLE_OK == 208 curl_easy_setopt (eh, 209 CURLOPT_POSTFIELDSIZE_LARGE, 210 (curl_off_t) strlen (kcg->form_data))); 211 kcg->job = GNUNET_CURL_job_add2 ( 212 TALER_TESTING_interpreter_get_context (is), 213 eh, 214 kcg->form_header, 215 &post_kyc_form_cb, 216 kcg); 217 GNUNET_assert (NULL != kcg->job); 218 } 219 220 221 /** 222 * Cleanup the state from a "track transaction" CMD, and possibly 223 * cancel a operation thereof. 224 * 225 * @param cls closure. 226 * @param cmd the command which is being cleaned up. 227 */ 228 static void 229 post_kyc_form_cleanup (void *cls, 230 const struct TALER_TESTING_Command *cmd) 231 { 232 struct PostKycFormState *kcg = cls; 233 234 if (NULL != kcg->job) 235 { 236 TALER_TESTING_command_incomplete (kcg->is, 237 cmd->label); 238 GNUNET_CURL_job_cancel (kcg->job); 239 kcg->job = NULL; 240 } 241 curl_slist_free_all (kcg->form_header); 242 GNUNET_free (kcg); 243 } 244 245 246 /** 247 * Offer internal data from a "check KYC" CMD. 248 * 249 * @param cls closure. 250 * @param[out] ret result (could be anything). 251 * @param trait name of the trait. 252 * @param index index number of the object to offer. 253 * @return #GNUNET_OK on success. 254 */ 255 static enum GNUNET_GenericReturnValue 256 post_kyc_form_traits (void *cls, 257 const void **ret, 258 const char *trait, 259 unsigned int index) 260 { 261 struct PostKycFormState *kcg = cls; 262 struct TALER_TESTING_Trait traits[] = { 263 TALER_TESTING_trait_end () 264 }; 265 266 (void) kcg; 267 return TALER_TESTING_get_trait (traits, 268 ret, 269 trait, 270 index); 271 } 272 273 274 struct TALER_TESTING_Command 275 TALER_TESTING_cmd_post_kyc_form ( 276 const char *label, 277 const char *kyc_info_reference, 278 unsigned int requirement_index, 279 const char *form_data_content_type, 280 const char *form_data, 281 unsigned int expected_response_code) 282 { 283 struct PostKycFormState *kcg; 284 285 kcg = GNUNET_new (struct PostKycFormState); 286 kcg->kyc_info_reference = kyc_info_reference; 287 kcg->requirement_index = requirement_index; 288 if (NULL != form_data_content_type) 289 { 290 char *hdr; 291 292 GNUNET_asprintf (&hdr, 293 "%s: %s", 294 MHD_HTTP_HEADER_CONTENT_ENCODING, 295 form_data_content_type); 296 kcg->form_header 297 = curl_slist_append (NULL, 298 hdr); 299 GNUNET_free (hdr); 300 } 301 kcg->form_data = form_data; 302 kcg->expected_response_code = expected_response_code; 303 { 304 struct TALER_TESTING_Command cmd = { 305 .cls = kcg, 306 .label = label, 307 .run = &post_kyc_form_run, 308 .cleanup = &post_kyc_form_cleanup, 309 .traits = &post_kyc_form_traits 310 }; 311 312 return cmd; 313 } 314 } 315 316 317 /* end of testing_api_cmd_post_kyc_form.c */