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