testing_api_cmd_deposits_get.c (10843B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2014-2021, 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_deposits_get.c 22 * @brief Implement the testing CMDs for the /deposits/ GET operations. 23 * @author Marcello Stanisci 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 "track transaction" CMD. 31 */ 32 struct TrackTransactionState 33 { 34 35 /** 36 * If non NULL, will provide a WTID to be compared against 37 * the one returned by the "track transaction" operation. 38 */ 39 const char *bank_transfer_reference; 40 41 /** 42 * Our command. 43 */ 44 const struct TALER_TESTING_Command *cmd; 45 46 /** 47 * The WTID associated by the transaction being tracked. 48 */ 49 struct TALER_WireTransferIdentifierRawP wtid; 50 51 /** 52 * Expected HTTP response code. 53 */ 54 unsigned int expected_response_code; 55 56 /** 57 * Set to the KYC requirement payto hash *if* the exchange replied with a 58 * request for KYC (#MHD_HTTP_ACCEPTED). 59 * Note: set based on our @e merchant_payto_uri, as 60 * the exchange does not respond with the payto hash. 61 */ 62 struct TALER_NormalizedPaytoHashP h_payto; 63 64 /** 65 * Set to the KYC requirement row *if* the exchange replied with 66 * a request for KYC (#MHD_HTTP_ACCEPTED). 67 */ 68 uint64_t requirement_row; 69 70 /** 71 * Reference to any operation that can provide a transaction. 72 * Will be the transaction to track. 73 */ 74 const char *transaction_reference; 75 76 /** 77 * Payto URI of the merchant receiving the deposit. 78 */ 79 struct TALER_FullPayto merchant_payto_uri; 80 81 /** 82 * Index of the coin involved in the transaction. Recall: 83 * at the exchange, the tracking is done _per coin_. 84 */ 85 unsigned int coin_index; 86 87 /** 88 * Handle to the "track transaction" pending operation. 89 */ 90 struct TALER_EXCHANGE_GetDepositsHandle *tth; 91 92 /** 93 * Interpreter state. 94 */ 95 struct TALER_TESTING_Interpreter *is; 96 }; 97 98 99 /** 100 * Checks what is returned by the "track transaction" operation. 101 * Checks that the HTTP response code is acceptable, and - if the 102 * right reference is non NULL - that the wire transfer subject 103 * line matches our expectations. 104 * 105 * @param cls closure. 106 * @param dr GET deposit response details 107 */ 108 static void 109 deposit_wtid_cb ( 110 void *cls, 111 const struct TALER_EXCHANGE_GetDepositsResponse *dr) 112 { 113 struct TrackTransactionState *tts = cls; 114 struct TALER_TESTING_Interpreter *is = tts->is; 115 116 tts->tth = NULL; 117 if (tts->expected_response_code != dr->hr.http_status) 118 { 119 TALER_TESTING_unexpected_status (is, 120 dr->hr.http_status, 121 tts->expected_response_code); 122 return; 123 } 124 switch (dr->hr.http_status) 125 { 126 case MHD_HTTP_OK: 127 tts->wtid = dr->details.ok.wtid; 128 if (NULL != tts->bank_transfer_reference) 129 { 130 const struct TALER_TESTING_Command *bank_transfer_cmd; 131 const struct TALER_WireTransferIdentifierRawP *wtid_want; 132 133 /* _this_ wire transfer subject line. */ 134 bank_transfer_cmd 135 = TALER_TESTING_interpreter_lookup_command (is, 136 tts->bank_transfer_reference 137 ); 138 if (NULL == bank_transfer_cmd) 139 { 140 GNUNET_break (0); 141 TALER_TESTING_interpreter_fail (is); 142 return; 143 } 144 145 if (GNUNET_OK != 146 TALER_TESTING_get_trait_wtid (bank_transfer_cmd, 147 &wtid_want)) 148 { 149 GNUNET_break (0); 150 TALER_TESTING_interpreter_fail (is); 151 return; 152 } 153 154 /* Compare that expected and gotten subjects match. */ 155 if (0 != GNUNET_memcmp (&dr->details.ok.wtid, 156 wtid_want)) 157 { 158 GNUNET_break (0); 159 TALER_TESTING_interpreter_fail (tts->is); 160 return; 161 } 162 } 163 break; 164 case MHD_HTTP_ACCEPTED: 165 /* allowed, nothing to check here */ 166 TALER_full_payto_normalize_and_hash (tts->merchant_payto_uri, 167 &tts->h_payto); 168 tts->requirement_row 169 = dr->details.accepted.requirement_row; 170 break; 171 case MHD_HTTP_NOT_FOUND: 172 /* allowed, nothing to check here */ 173 break; 174 default: 175 GNUNET_break (0); 176 break; 177 } 178 TALER_TESTING_interpreter_next (tts->is); 179 } 180 181 182 /** 183 * Run the command. 184 * 185 * @param cls closure. 186 * @param cmd the command to execute. 187 * @param is the interpreter state. 188 */ 189 static void 190 deposits_get_run ( 191 void *cls, 192 const struct TALER_TESTING_Command *cmd, 193 struct TALER_TESTING_Interpreter *is) 194 { 195 struct TrackTransactionState *tts = cls; 196 const struct TALER_TESTING_Command *transaction_cmd; 197 const struct TALER_CoinSpendPrivateKeyP *coin_priv; 198 struct TALER_CoinSpendPublicKeyP coin_pub; 199 const json_t *contract_terms; 200 const json_t *wire_details; 201 struct TALER_MerchantWireHashP h_wire_details; 202 struct TALER_PrivateContractHashP h_contract_terms; 203 const struct TALER_MerchantPrivateKeyP *merchant_priv; 204 205 tts->cmd = cmd; 206 tts->is = is; 207 transaction_cmd 208 = TALER_TESTING_interpreter_lookup_command (tts->is, 209 tts->transaction_reference); 210 if (NULL == transaction_cmd) 211 { 212 GNUNET_break (0); 213 TALER_TESTING_interpreter_fail (tts->is); 214 return; 215 } 216 217 if (GNUNET_OK != 218 TALER_TESTING_get_trait_coin_priv (transaction_cmd, 219 tts->coin_index, 220 &coin_priv)) 221 { 222 GNUNET_break (0); 223 TALER_TESTING_interpreter_fail (tts->is); 224 return; 225 } 226 227 GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, 228 &coin_pub.eddsa_pub); 229 230 /* Get the strings.. */ 231 if (GNUNET_OK != 232 TALER_TESTING_get_trait_wire_details (transaction_cmd, 233 &wire_details)) 234 { 235 GNUNET_break (0); 236 TALER_TESTING_interpreter_fail (tts->is); 237 return; 238 } 239 tts->merchant_payto_uri.full_payto 240 = GNUNET_strdup (json_string_value (json_object_get (wire_details, 241 "payto_uri"))); 242 if (GNUNET_OK != 243 TALER_TESTING_get_trait_contract_terms (transaction_cmd, 244 &contract_terms)) 245 { 246 GNUNET_break (0); 247 TALER_TESTING_interpreter_fail (tts->is); 248 return; 249 } 250 251 if ( (NULL == wire_details) || 252 (NULL == contract_terms) ) 253 { 254 GNUNET_break (0); 255 TALER_TESTING_interpreter_fail (tts->is); 256 return; 257 } 258 259 /* Should not fail here, json has been parsed already */ 260 GNUNET_assert 261 ( (GNUNET_OK == 262 TALER_JSON_merchant_wire_signature_hash (wire_details, 263 &h_wire_details)) && 264 (GNUNET_OK == 265 TALER_JSON_contract_hash (contract_terms, 266 &h_contract_terms)) ); 267 268 if (GNUNET_OK != 269 TALER_TESTING_get_trait_merchant_priv (transaction_cmd, 270 &merchant_priv)) 271 { 272 GNUNET_break (0); 273 TALER_TESTING_interpreter_fail (tts->is); 274 return; 275 } 276 277 tts->tth = TALER_EXCHANGE_get_deposits_create ( 278 TALER_TESTING_interpreter_get_context (is), 279 TALER_TESTING_get_exchange_url (is), 280 TALER_TESTING_get_keys (is), 281 merchant_priv, 282 &h_wire_details, 283 &h_contract_terms, 284 &coin_pub); 285 if (NULL == tts->tth) 286 { 287 GNUNET_break (0); 288 TALER_TESTING_interpreter_fail (is); 289 return; 290 } 291 if (TALER_EC_NONE != 292 TALER_EXCHANGE_get_deposits_start (tts->tth, 293 &deposit_wtid_cb, 294 tts)) 295 { 296 GNUNET_break (0); 297 TALER_EXCHANGE_get_deposits_cancel (tts->tth); 298 tts->tth = NULL; 299 TALER_TESTING_interpreter_fail (is); 300 return; 301 } 302 } 303 304 305 /** 306 * Cleanup the state from a "track transaction" CMD, and possibly 307 * cancel a operation thereof. 308 * 309 * @param cls closure. 310 * @param cmd the command which is being cleaned up. 311 */ 312 static void 313 deposits_get_cleanup ( 314 void *cls, 315 const struct TALER_TESTING_Command *cmd) 316 { 317 struct TrackTransactionState *tts = cls; 318 319 if (NULL != tts->tth) 320 { 321 TALER_TESTING_command_incomplete (tts->is, 322 cmd->label); 323 TALER_EXCHANGE_get_deposits_cancel (tts->tth); 324 tts->tth = NULL; 325 } 326 GNUNET_free (tts->merchant_payto_uri.full_payto); 327 GNUNET_free (tts); 328 } 329 330 331 /** 332 * Offer internal data from a "track transaction" CMD. 333 * 334 * @param cls closure. 335 * @param[out] ret result (could be anything). 336 * @param trait name of the trait. 337 * @param index index number of the object to offer. 338 * @return #GNUNET_OK on success. 339 */ 340 static enum GNUNET_GenericReturnValue 341 deposits_get_traits (void *cls, 342 const void **ret, 343 const char *trait, 344 unsigned int index) 345 { 346 struct TrackTransactionState *tts = cls; 347 struct TALER_TESTING_Trait traits[] = { 348 TALER_TESTING_make_trait_wtid (&tts->wtid), 349 TALER_TESTING_make_trait_legi_requirement_row ( 350 &tts->requirement_row), 351 TALER_TESTING_make_trait_h_normalized_payto (&tts->h_payto), 352 TALER_TESTING_make_trait_full_payto_uri (&tts->merchant_payto_uri), 353 TALER_TESTING_trait_end () 354 }; 355 356 return TALER_TESTING_get_trait (traits, 357 ret, 358 trait, 359 index); 360 } 361 362 363 struct TALER_TESTING_Command 364 TALER_TESTING_cmd_deposits_get ( 365 const char *label, 366 const char *transaction_reference, 367 unsigned int coin_index, 368 unsigned int expected_response_code, 369 const char *bank_transfer_reference) 370 { 371 struct TrackTransactionState *tts; 372 373 tts = GNUNET_new (struct TrackTransactionState); 374 tts->transaction_reference = transaction_reference; 375 tts->expected_response_code = expected_response_code; 376 tts->bank_transfer_reference = bank_transfer_reference; 377 tts->coin_index = coin_index; 378 { 379 struct TALER_TESTING_Command cmd = { 380 .cls = tts, 381 .label = label, 382 .run = &deposits_get_run, 383 .cleanup = &deposits_get_cleanup, 384 .traits = &deposits_get_traits 385 }; 386 387 return cmd; 388 } 389 } 390 391 392 /* end of testing_api_cmd_deposits_get.c */