testing_api_cmd_claim_order.c (7974B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2014-2023 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_api_cmd_claim_order.c 22 * @brief command to claim an order 23 * @author Marcello Stanisci 24 */ 25 #include "platform.h" 26 #include <taler/taler_exchange_service.h> 27 #include <taler/taler_testing_lib.h> 28 #include "taler_merchant_service.h" 29 #include "taler_merchant_testing_lib.h" 30 31 /** 32 * State for a "order claim" CMD. Not used by 33 * the initial claim operation. 34 */ 35 struct OrderClaimState 36 { 37 /** 38 * The interpreter state. 39 */ 40 struct TALER_TESTING_Interpreter *is; 41 42 /** 43 * URL of the merchant backend. 44 */ 45 const char *merchant_url; 46 47 /** 48 * Contract terms we downloaded. Only set if we got #MHD_HTTP_OK. 49 */ 50 json_t *contract_terms; 51 52 /** 53 * Hash over the contract terms. Only set if we got #MHD_HTTP_OK. 54 */ 55 struct TALER_PrivateContractHashP contract_terms_hash; 56 57 /** 58 * Signature of the merchant. Only set if we got #MHD_HTTP_OK. 59 */ 60 struct TALER_MerchantSignatureP merchant_sig; 61 62 /** 63 * Public key of the merchant. Only set if we got #MHD_HTTP_OK. 64 */ 65 struct TALER_MerchantPublicKeyP merchant_pub; 66 67 /** 68 * Expected status code. 69 */ 70 unsigned int http_status; 71 72 /** 73 * /order/claim operation handle. 74 */ 75 struct TALER_MERCHANT_OrderClaimHandle *och; 76 77 /** 78 * Reference to a order operation. Will offer the 79 * nonce for the operation. 80 */ 81 const char *order_reference; 82 83 /** 84 * Order id to claim upon. If null, the @a order_reference 85 * will offer this value. 86 */ 87 const char *order_id; 88 }; 89 90 91 /** 92 * Free the state of a "order claim" CMD, and possibly 93 * cancel it if it did not complete. 94 * 95 * @param cls closure. 96 * @param cmd command being freed. 97 */ 98 static void 99 order_claim_cleanup (void *cls, 100 const struct TALER_TESTING_Command *cmd) 101 { 102 struct OrderClaimState *pls = cls; 103 104 if (NULL != pls->och) 105 { 106 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 107 "Command '%s' did not complete\n", 108 cmd->label); 109 TALER_MERCHANT_order_claim_cancel (pls->och); 110 pls->och = NULL; 111 } 112 if (NULL != pls->contract_terms) 113 { 114 json_decref (pls->contract_terms); 115 pls->contract_terms = NULL; 116 } 117 GNUNET_free (pls); 118 } 119 120 121 /** 122 * Callback for "order claim" operation, to check the 123 * response code is as expected. 124 * 125 * @param cls closure 126 * @param ocr response we got 127 */ 128 static void 129 order_claim_cb (void *cls, 130 const struct TALER_MERCHANT_OrderClaimResponse *ocr) 131 { 132 struct OrderClaimState *pls = cls; 133 134 pls->och = NULL; 135 if (pls->http_status != ocr->hr.http_status) 136 TALER_TESTING_FAIL (pls->is); 137 if (MHD_HTTP_OK == ocr->hr.http_status) 138 { 139 pls->contract_terms 140 = json_incref ((json_t *) ocr->details.ok.contract_terms); 141 pls->contract_terms_hash = ocr->details.ok.h_contract_terms; 142 pls->merchant_sig = ocr->details.ok.sig; 143 { 144 const char *error_name; 145 unsigned int error_line; 146 struct GNUNET_JSON_Specification spec[] = { 147 GNUNET_JSON_spec_fixed_auto ("merchant_pub", 148 &pls->merchant_pub), 149 GNUNET_JSON_spec_end () 150 }; 151 152 if (GNUNET_OK != 153 GNUNET_JSON_parse (pls->contract_terms, 154 spec, 155 &error_name, 156 &error_line)) 157 TALER_TESTING_FAIL (pls->is); 158 } 159 } 160 TALER_TESTING_interpreter_next (pls->is); 161 } 162 163 164 /** 165 * Run the "order claim" CMD. 166 * 167 * @param cls closure. 168 * @param cmd command currently being run. 169 * @param is interpreter state. 170 */ 171 static void 172 order_claim_run (void *cls, 173 const struct TALER_TESTING_Command *cmd, 174 struct TALER_TESTING_Interpreter *is) 175 { 176 struct OrderClaimState *pls = cls; 177 const char *order_id; 178 const struct GNUNET_CRYPTO_EddsaPublicKey *nonce; 179 /* Only used if we do NOT use the nonce/token from traits. */ 180 struct GNUNET_CRYPTO_EddsaPublicKey dummy_nonce; 181 const struct TALER_ClaimTokenP *claim_token; 182 183 pls->is = is; 184 if (NULL != pls->order_id) 185 { 186 order_id = pls->order_id; 187 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, 188 &dummy_nonce, 189 sizeof (dummy_nonce)); 190 nonce = &dummy_nonce; 191 claim_token = NULL; 192 } 193 else 194 { 195 const struct TALER_TESTING_Command *order_cmd; 196 197 order_cmd 198 = TALER_TESTING_interpreter_lookup_command (is, 199 pls->order_reference); 200 if (NULL == order_cmd) 201 TALER_TESTING_FAIL (is); 202 if (GNUNET_OK != 203 TALER_TESTING_get_trait_claim_nonce (order_cmd, 204 &nonce)) 205 { 206 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, 207 &dummy_nonce, 208 sizeof (dummy_nonce)); 209 nonce = &dummy_nonce; 210 } 211 if (GNUNET_OK != 212 TALER_TESTING_get_trait_claim_token (order_cmd, 213 &claim_token)) 214 claim_token = NULL; 215 if (GNUNET_OK != 216 TALER_TESTING_get_trait_order_id (order_cmd, 217 &order_id)) 218 TALER_TESTING_FAIL (is); 219 } 220 pls->och = TALER_MERCHANT_order_claim (TALER_TESTING_interpreter_get_context ( 221 is), 222 pls->merchant_url, 223 order_id, 224 nonce, 225 claim_token, 226 &order_claim_cb, 227 pls); 228 if (NULL == pls->och) 229 TALER_TESTING_FAIL (is); 230 } 231 232 233 /** 234 * Offer internal data to other commands. 235 * 236 * @param cls closure 237 * @param[out] ret result (could be anything) 238 * @param trait name of the trait 239 * @param index index number of the object to extract. 240 * @return #GNUNET_OK on success 241 */ 242 static enum GNUNET_GenericReturnValue 243 order_claim_traits (void *cls, 244 const void **ret, 245 const char *trait, 246 unsigned int index) 247 { 248 struct OrderClaimState *pls = cls; 249 250 struct TALER_TESTING_Trait traits[] = { 251 TALER_TESTING_make_trait_contract_terms (pls->contract_terms), 252 TALER_TESTING_make_trait_h_contract_terms (&pls->contract_terms_hash), 253 TALER_TESTING_make_trait_merchant_sig (&pls->merchant_sig), 254 TALER_TESTING_make_trait_merchant_pub (&pls->merchant_pub), 255 TALER_TESTING_trait_end () 256 }; 257 258 return TALER_TESTING_get_trait (traits, 259 ret, 260 trait, 261 index); 262 } 263 264 265 struct TALER_TESTING_Command 266 TALER_TESTING_cmd_merchant_claim_order ( 267 const char *label, 268 const char *merchant_url, 269 unsigned int http_status, 270 const char *order_reference, 271 const char *order_id) 272 { 273 struct OrderClaimState *pls; 274 275 pls = GNUNET_new (struct OrderClaimState); 276 pls->http_status = http_status; 277 pls->order_reference = order_reference; 278 pls->merchant_url = merchant_url; 279 pls->order_id = order_id; 280 { 281 struct TALER_TESTING_Command cmd = { 282 .cls = pls, 283 .label = label, 284 .run = &order_claim_run, 285 .cleanup = &order_claim_cleanup, 286 .traits = &order_claim_traits 287 }; 288 289 return cmd; 290 } 291 }