testing_api_cmd_claim_order.c (8034B)
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 (&dummy_nonce, 190 sizeof (dummy_nonce)); 191 nonce = &dummy_nonce; 192 claim_token = NULL; 193 } 194 else 195 { 196 const struct TALER_TESTING_Command *order_cmd; 197 198 order_cmd 199 = TALER_TESTING_interpreter_lookup_command (is, 200 pls->order_reference); 201 if (NULL == order_cmd) 202 TALER_TESTING_FAIL (is); 203 if (GNUNET_OK != 204 TALER_TESTING_get_trait_claim_nonce (order_cmd, 205 &nonce)) 206 { 207 GNUNET_CRYPTO_random_block (&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_post_orders_claim_create ( 221 TALER_TESTING_interpreter_get_context (is), 222 pls->merchant_url, 223 order_id, 224 nonce); 225 if (NULL != claim_token) 226 TALER_MERCHANT_post_orders_claim_set_options ( 227 pls->och, 228 TALER_MERCHANT_post_orders_claim_option_token (claim_token)); 229 { 230 enum TALER_ErrorCode ec; 231 232 ec = TALER_MERCHANT_post_orders_claim_start ( 233 pls->och, 234 &order_claim_cb, 235 pls); 236 GNUNET_assert (TALER_EC_NONE == ec); 237 } 238 } 239 240 241 /** 242 * Offer internal data to other commands. 243 * 244 * @param cls closure 245 * @param[out] ret result (could be anything) 246 * @param trait name of the trait 247 * @param index index number of the object to extract. 248 * @return #GNUNET_OK on success 249 */ 250 static enum GNUNET_GenericReturnValue 251 order_claim_traits (void *cls, 252 const void **ret, 253 const char *trait, 254 unsigned int index) 255 { 256 struct OrderClaimState *pls = cls; 257 258 struct TALER_TESTING_Trait traits[] = { 259 TALER_TESTING_make_trait_contract_terms (pls->contract_terms), 260 TALER_TESTING_make_trait_h_contract_terms (&pls->contract_terms_hash), 261 TALER_TESTING_make_trait_merchant_sig (&pls->merchant_sig), 262 TALER_TESTING_make_trait_merchant_pub (&pls->merchant_pub), 263 TALER_TESTING_trait_end () 264 }; 265 266 return TALER_TESTING_get_trait (traits, 267 ret, 268 trait, 269 index); 270 } 271 272 273 struct TALER_TESTING_Command 274 TALER_TESTING_cmd_merchant_claim_order ( 275 const char *label, 276 const char *merchant_url, 277 unsigned int http_status, 278 const char *order_reference, 279 const char *order_id) 280 { 281 struct OrderClaimState *pls; 282 283 pls = GNUNET_new (struct OrderClaimState); 284 pls->http_status = http_status; 285 pls->order_reference = order_reference; 286 pls->merchant_url = merchant_url; 287 pls->order_id = order_id; 288 { 289 struct TALER_TESTING_Command cmd = { 290 .cls = pls, 291 .label = label, 292 .run = &order_claim_run, 293 .cleanup = &order_claim_cleanup, 294 .traits = &order_claim_traits 295 }; 296 297 return cmd; 298 } 299 }