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