testing_api_cmd_truth_challenge.c (9495B)
1 /* 2 This file is part of Anastasis 3 Copyright (C) 2020, 2022 Anastasis SARL 4 5 Anastasis 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 Anastasis 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 Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file testing/testing_api_cmd_truth_challenge.c 18 * @brief Testing of Implementation of the /truth GET 19 * @author Christian Grothoff 20 * @author Dennis Neufeld 21 * @author Dominik Meister 22 */ 23 24 #include "platform.h" 25 #include "anastasis_testing_lib.h" 26 #include <taler/taler_util.h> 27 #include <taler/taler_testing_lib.h> 28 #include <taler/taler_merchant_service.h> 29 30 31 /** 32 * State for a "keyshare lookup" CMD. 33 */ 34 struct TruthChallengeState 35 { 36 /** 37 * The interpreter state. 38 */ 39 struct TALER_TESTING_Interpreter *is; 40 41 /** 42 * URL of the anastasis backend. 43 */ 44 const char *anastasis_url; 45 46 /** 47 * Expected HTTP status code. 48 */ 49 unsigned int expected_http_status; 50 51 /** 52 * The /truth GET operation handle. 53 */ 54 struct ANASTASIS_TruthChallengeOperation *tco; 55 56 /** 57 * Reference to upload command we expect to lookup. 58 */ 59 const char *upload_reference; 60 61 /** 62 * Reference to upload command we expect to lookup. 63 */ 64 const char *payment_reference; 65 66 /** 67 * Payment secret requested by the service, if any. 68 */ 69 struct ANASTASIS_PaymentSecretP payment_secret_response; 70 71 /** 72 * Taler-URI with payment request, if any. 73 */ 74 char *pay_uri; 75 76 /** 77 * Order ID for payment request, if any. 78 */ 79 char *order_id; 80 81 /** 82 * "code" returned by service, if any. 83 */ 84 char *code; 85 86 /** 87 * "instructions" for how to solve the challenge as returned by service, if any. 88 */ 89 char *instructions; 90 91 }; 92 93 94 static void 95 truth_challenge_cb (void *cls, 96 const struct ANASTASIS_TruthChallengeDetails *tcd) 97 { 98 struct TruthChallengeState *ksls = cls; 99 100 ksls->tco = NULL; 101 if (tcd->http_status != ksls->expected_http_status) 102 { 103 TALER_TESTING_unexpected_status (ksls->is, 104 tcd->http_status, 105 ksls->expected_http_status); 106 return; 107 } 108 switch (tcd->http_status) 109 { 110 case MHD_HTTP_OK: 111 switch (tcd->details.success.cs) 112 { 113 case ANASTASIS_CS_FILE_WRITTEN: 114 { 115 FILE *file; 116 char code[22]; 117 118 file = fopen (tcd->details.success.details.challenge_filename, 119 "r"); 120 if (NULL == file) 121 { 122 GNUNET_log_strerror_file ( 123 GNUNET_ERROR_TYPE_ERROR, 124 "open", 125 tcd->details.success.details.challenge_filename); 126 TALER_TESTING_interpreter_fail (ksls->is); 127 return; 128 } 129 if (0 == fscanf (file, 130 "%21s", 131 code)) 132 { 133 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, 134 "fscanf", 135 tcd->details.success.details. 136 challenge_filename); 137 GNUNET_break (0 == fclose (file)); 138 TALER_TESTING_interpreter_fail (ksls->is); 139 return; 140 } 141 GNUNET_break (0 == fclose (file)); 142 ksls->code = GNUNET_strdup (code); 143 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 144 "Read code `%s'\n", 145 code); 146 } 147 break; 148 case ANASTASIS_CS_TAN_SENT: 149 ksls->instructions = GNUNET_strdup ( 150 tcd->details.success.details.tan_address_hint); 151 break; 152 case ANASTASIS_CS_TAN_ALREADY_SENT: 153 break; 154 case ANASTASIS_CS_WIRE_FUNDS: 155 /* FIXME: not implemented */ 156 GNUNET_break (0); 157 return; 158 } 159 break; 160 case MHD_HTTP_PAYMENT_REQUIRED: 161 ksls->pay_uri = GNUNET_strdup ( 162 tcd->details.payment_required.payment_request); 163 ksls->payment_secret_response = tcd->details.payment_required.ps; 164 { 165 struct TALER_MERCHANT_PayUriData pd; 166 167 if (GNUNET_OK != 168 TALER_MERCHANT_parse_pay_uri (ksls->pay_uri, 169 &pd)) 170 { 171 GNUNET_break (0); 172 TALER_TESTING_interpreter_fail (ksls->is); 173 return; 174 } 175 ksls->order_id = GNUNET_strdup (pd.order_id); 176 TALER_MERCHANT_parse_pay_uri_free (&pd); 177 } 178 179 break; 180 default: 181 break; 182 } 183 TALER_TESTING_interpreter_next (ksls->is); 184 } 185 186 187 static void 188 truth_challenge_run (void *cls, 189 const struct TALER_TESTING_Command *cmd, 190 struct TALER_TESTING_Interpreter *is) 191 { 192 struct TruthChallengeState *ksls = cls; 193 const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key; 194 const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid; 195 const struct ANASTASIS_PaymentSecretP *payment_secret; 196 197 ksls->is = is; 198 if (NULL == ksls->upload_reference) 199 { 200 GNUNET_break (0); 201 TALER_TESTING_interpreter_fail (ksls->is); 202 return; 203 } 204 { 205 const struct TALER_TESTING_Command *upload_cmd; 206 207 upload_cmd = TALER_TESTING_interpreter_lookup_command ( 208 is, 209 ksls->upload_reference); 210 if (NULL == upload_cmd) 211 { 212 GNUNET_break (0); 213 TALER_TESTING_interpreter_fail (ksls->is); 214 return; 215 } 216 if (GNUNET_OK != 217 ANASTASIS_TESTING_get_trait_truth_uuid (upload_cmd, 218 &truth_uuid)) 219 { 220 GNUNET_break (0); 221 TALER_TESTING_interpreter_fail (ksls->is); 222 return; 223 } 224 if (NULL == truth_uuid) 225 { 226 GNUNET_break (0); 227 TALER_TESTING_interpreter_fail (ksls->is); 228 return; 229 } 230 if (GNUNET_OK != 231 ANASTASIS_TESTING_get_trait_truth_key (upload_cmd, 232 &truth_key)) 233 { 234 GNUNET_break (0); 235 TALER_TESTING_interpreter_fail (ksls->is); 236 return; 237 } 238 if (NULL == truth_key) 239 { 240 GNUNET_break (0); 241 TALER_TESTING_interpreter_fail (ksls->is); 242 return; 243 } 244 } 245 246 if (NULL != ksls->payment_reference) 247 { 248 const struct TALER_TESTING_Command *payment_cmd; 249 250 payment_cmd = TALER_TESTING_interpreter_lookup_command ( 251 is, 252 ksls->payment_reference); 253 if (GNUNET_OK != 254 ANASTASIS_TESTING_get_trait_payment_secret (payment_cmd, 255 &payment_secret)) 256 { 257 GNUNET_break (0); 258 TALER_TESTING_interpreter_fail (ksls->is); 259 return; 260 } 261 } 262 else 263 { 264 payment_secret = NULL; 265 } 266 267 ksls->tco = ANASTASIS_truth_challenge ( 268 TALER_TESTING_interpreter_get_context (is), 269 ksls->anastasis_url, 270 truth_uuid, 271 truth_key, 272 payment_secret, 273 &truth_challenge_cb, 274 ksls); 275 if (NULL == ksls->tco) 276 { 277 GNUNET_break (0); 278 TALER_TESTING_interpreter_fail (ksls->is); 279 return; 280 } 281 } 282 283 284 static void 285 truth_challenge_cleanup (void *cls, 286 const struct TALER_TESTING_Command *cmd) 287 { 288 struct TruthChallengeState *ksls = cls; 289 290 if (NULL != ksls->tco) 291 { 292 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 293 "Command '%s' did not complete (keyshare lookup)\n", 294 cmd->label); 295 ANASTASIS_truth_challenge_cancel (ksls->tco); 296 ksls->tco = NULL; 297 } 298 GNUNET_free (ksls->pay_uri); 299 GNUNET_free (ksls->order_id); 300 GNUNET_free (ksls->code); 301 GNUNET_free (ksls->instructions); 302 GNUNET_free (ksls); 303 } 304 305 306 /** 307 * Offer internal data to other commands. 308 * 309 * @param cls closure 310 * @param[out] ret result (could be anything) 311 * @param[out] trait name of the trait 312 * @param index index number of the object to extract. 313 * @return #GNUNET_OK on success 314 */ 315 static enum GNUNET_GenericReturnValue 316 truth_challenge_traits (void *cls, 317 const void **ret, 318 const char *trait, 319 unsigned int index) 320 { 321 struct TruthChallengeState *ksls = cls; 322 struct TALER_TESTING_Trait traits[] = { 323 ANASTASIS_TESTING_make_trait_payment_secret ( 324 &ksls->payment_secret_response), 325 TALER_TESTING_make_trait_taler_uri (ksls->pay_uri), 326 TALER_TESTING_make_trait_order_id (ksls->order_id), 327 ANASTASIS_TESTING_make_trait_code (ksls->code), 328 TALER_TESTING_trait_end () 329 }; 330 331 return TALER_TESTING_get_trait (traits, 332 ret, 333 trait, 334 index); 335 } 336 337 338 struct TALER_TESTING_Command 339 ANASTASIS_TESTING_cmd_truth_challenge ( 340 const char *label, 341 const char *anastasis_url, 342 const char *payment_ref, 343 const char *upload_ref, 344 unsigned int http_status) 345 { 346 struct TruthChallengeState *ksls; 347 348 GNUNET_assert (NULL != upload_ref); 349 ksls = GNUNET_new (struct TruthChallengeState); 350 ksls->expected_http_status = http_status; 351 ksls->anastasis_url = anastasis_url; 352 ksls->upload_reference = upload_ref; 353 ksls->payment_reference = payment_ref; 354 { 355 struct TALER_TESTING_Command cmd = { 356 .cls = ksls, 357 .label = label, 358 .run = &truth_challenge_run, 359 .cleanup = &truth_challenge_cleanup, 360 .traits = &truth_challenge_traits 361 }; 362 363 return cmd; 364 } 365 } 366 367 368 /* end of testing_api_cmd_truth_challenge.c */