Line data Source code
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 19 : order_claim_cleanup (void *cls,
103 : const struct TALER_TESTING_Command *cmd)
104 : {
105 19 : struct OrderClaimState *pls = cls;
106 :
107 19 : if (NULL != pls->och)
108 : {
109 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
110 : "Command '%s' did not complete\n",
111 : cmd->label);
112 0 : TALER_MERCHANT_post_orders_claim_cancel (pls->och);
113 0 : pls->och = NULL;
114 : }
115 19 : if (NULL != pls->contract_terms)
116 : {
117 15 : json_decref (pls->contract_terms);
118 15 : pls->contract_terms = NULL;
119 : }
120 19 : GNUNET_free (pls);
121 19 : }
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 19 : order_claim_cb (struct OrderClaimState *pls,
133 : const struct TALER_MERCHANT_PostOrdersClaimResponse *ocr)
134 : {
135 :
136 19 : pls->och = NULL;
137 19 : if (pls->http_status != ocr->hr.http_status)
138 0 : TALER_TESTING_FAIL (pls->is);
139 19 : if (MHD_HTTP_OK == ocr->hr.http_status)
140 : {
141 : pls->contract_terms
142 15 : = json_incref ((json_t *) ocr->details.ok.contract_terms);
143 15 : pls->contract_terms_hash = ocr->details.ok.h_contract_terms;
144 15 : 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 15 : GNUNET_JSON_spec_fixed_auto ("merchant_pub",
150 : &pls->merchant_pub),
151 15 : GNUNET_JSON_spec_end ()
152 : };
153 :
154 15 : if (GNUNET_OK !=
155 15 : GNUNET_JSON_parse (pls->contract_terms,
156 : spec,
157 : &error_name,
158 : &error_line))
159 0 : TALER_TESTING_FAIL (pls->is);
160 : }
161 : }
162 19 : 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 19 : order_claim_run (void *cls,
175 : const struct TALER_TESTING_Command *cmd,
176 : struct TALER_TESTING_Interpreter *is)
177 : {
178 19 : 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 19 : pls->is = is;
186 19 : if (NULL != pls->order_id)
187 : {
188 4 : order_id = pls->order_id;
189 4 : GNUNET_CRYPTO_random_block (&dummy_nonce,
190 : sizeof (dummy_nonce));
191 4 : nonce = &dummy_nonce;
192 4 : claim_token = NULL;
193 : }
194 : else
195 : {
196 : const struct TALER_TESTING_Command *order_cmd;
197 :
198 : order_cmd
199 15 : = TALER_TESTING_interpreter_lookup_command (is,
200 : pls->order_reference);
201 15 : if (NULL == order_cmd)
202 0 : TALER_TESTING_FAIL (is);
203 15 : if (GNUNET_OK !=
204 15 : TALER_TESTING_get_trait_claim_nonce (order_cmd,
205 : &nonce))
206 : {
207 0 : GNUNET_CRYPTO_random_block (&dummy_nonce,
208 : sizeof (dummy_nonce));
209 0 : nonce = &dummy_nonce;
210 : }
211 15 : if (GNUNET_OK !=
212 15 : TALER_TESTING_get_trait_claim_token (order_cmd,
213 : &claim_token))
214 0 : claim_token = NULL;
215 15 : if (GNUNET_OK !=
216 15 : TALER_TESTING_get_trait_order_id (order_cmd,
217 : &order_id))
218 0 : TALER_TESTING_FAIL (is);
219 : }
220 19 : 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 19 : if (NULL != claim_token)
226 15 : 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 19 : ec = TALER_MERCHANT_post_orders_claim_start (
233 : pls->och,
234 : &order_claim_cb,
235 : pls);
236 19 : 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 20 : order_claim_traits (void *cls,
252 : const void **ret,
253 : const char *trait,
254 : unsigned int index)
255 : {
256 20 : struct OrderClaimState *pls = cls;
257 :
258 : struct TALER_TESTING_Trait traits[] = {
259 20 : TALER_TESTING_make_trait_contract_terms (pls->contract_terms),
260 20 : TALER_TESTING_make_trait_h_contract_terms (&pls->contract_terms_hash),
261 20 : TALER_TESTING_make_trait_merchant_sig (&pls->merchant_sig),
262 20 : TALER_TESTING_make_trait_merchant_pub (&pls->merchant_pub),
263 20 : TALER_TESTING_trait_end ()
264 : };
265 :
266 20 : return TALER_TESTING_get_trait (traits,
267 : ret,
268 : trait,
269 : index);
270 : }
271 :
272 :
273 : struct TALER_TESTING_Command
274 19 : 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 19 : pls = GNUNET_new (struct OrderClaimState);
284 19 : pls->http_status = http_status;
285 19 : pls->order_reference = order_reference;
286 19 : pls->merchant_url = merchant_url;
287 19 : pls->order_id = order_id;
288 : {
289 19 : 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 19 : return cmd;
298 : }
299 : }
|