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