diff options
Diffstat (limited to 'src/testing/testing_api_cmd_policy_store.c')
-rw-r--r-- | src/testing/testing_api_cmd_policy_store.c | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/src/testing/testing_api_cmd_policy_store.c b/src/testing/testing_api_cmd_policy_store.c new file mode 100644 index 0000000..a8f0a70 --- /dev/null +++ b/src/testing/testing_api_cmd_policy_store.c | |||
@@ -0,0 +1,397 @@ | |||
1 | /* | ||
2 | This file is part of ANASTASIS | ||
3 | Copyright (C) 2014-2019 Taler Systems SA | ||
4 | |||
5 | ANASTASIS 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 | ANASTASIS 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 ANASTASIS; see the file COPYING. If not, see | ||
17 | <http://www.gnu.org/licenses/> | ||
18 | */ | ||
19 | |||
20 | /** | ||
21 | * @file lib/testing_api_cmd_policy_store.c | ||
22 | * @brief command to execute the anastasis backend service. | ||
23 | * @author Christian Grothoff | ||
24 | * @author Dominik Meister | ||
25 | * @author Dennis Neufeld | ||
26 | */ | ||
27 | |||
28 | #include "platform.h" | ||
29 | #include "anastasis_testing_lib.h" | ||
30 | #include <taler/taler_util.h> | ||
31 | #include <taler/taler_testing_lib.h> | ||
32 | #include <taler/taler_merchant_service.h> | ||
33 | |||
34 | |||
35 | /** | ||
36 | * State for a "policy store" CMD. | ||
37 | */ | ||
38 | struct PolicyStoreState | ||
39 | { | ||
40 | /** | ||
41 | * Claim token we got back, if any. Otherwise all zeros. | ||
42 | */ | ||
43 | struct TALER_ClaimTokenP claim_token; | ||
44 | |||
45 | /** | ||
46 | * The policy data. | ||
47 | */ | ||
48 | const void *recovery_data; | ||
49 | |||
50 | /** | ||
51 | * Number of bytes in @e recovery_data | ||
52 | */ | ||
53 | size_t recovery_data_size; | ||
54 | |||
55 | /** | ||
56 | * Expected status code. | ||
57 | */ | ||
58 | unsigned int http_status; | ||
59 | |||
60 | /** | ||
61 | * Eddsa Publickey. | ||
62 | */ | ||
63 | struct ANASTASIS_CRYPTO_AccountPublicKeyP anastasis_pub; | ||
64 | |||
65 | /** | ||
66 | * Eddsa Privatekey. | ||
67 | */ | ||
68 | struct ANASTASIS_CRYPTO_AccountPrivateKeyP anastasis_priv; | ||
69 | |||
70 | /** | ||
71 | * Hash of uploaded data, used to verify the response. | ||
72 | */ | ||
73 | struct GNUNET_HashCode curr_hash; | ||
74 | |||
75 | /** | ||
76 | * The /policy POST operation handle. | ||
77 | */ | ||
78 | struct ANASTASIS_PolicyStoreOperation *pso; | ||
79 | |||
80 | /** | ||
81 | * The nonce. | ||
82 | */ | ||
83 | struct ANASTASIS_CRYPTO_NonceP nonce; | ||
84 | |||
85 | /** | ||
86 | * URL of the anastasis backend. | ||
87 | */ | ||
88 | const char *anastasis_url; | ||
89 | |||
90 | /** | ||
91 | * The interpreter state. | ||
92 | */ | ||
93 | struct TALER_TESTING_Interpreter *is; | ||
94 | |||
95 | /** | ||
96 | * Previous upload, or NULL for none. Used to calculate what THIS | ||
97 | * upload is based on. | ||
98 | */ | ||
99 | const char *prev_upload; | ||
100 | |||
101 | /** | ||
102 | * Payment order ID we are to provide in the request, or zero. | ||
103 | */ | ||
104 | struct ANASTASIS_PaymentSecretP payment_secret_request; | ||
105 | |||
106 | /** | ||
107 | * The order ID, for making the payment. | ||
108 | */ | ||
109 | char *order_id; | ||
110 | |||
111 | /** | ||
112 | * Payment order ID we are to provide in the response, or zero. | ||
113 | */ | ||
114 | struct ANASTASIS_PaymentSecretP payment_secret_response; | ||
115 | |||
116 | /** | ||
117 | * Options for how we are supposed to do the upload. | ||
118 | */ | ||
119 | enum ANASTASIS_TESTING_PolicyStoreOption psopt; | ||
120 | |||
121 | /** | ||
122 | * True if @e payment_secret_request is initialized. | ||
123 | */ | ||
124 | bool payment_secret_set; | ||
125 | }; | ||
126 | |||
127 | /** | ||
128 | * Function called with the results of a #policy_store(). | ||
129 | * | ||
130 | * @param cls closure | ||
131 | * @param http_status HTTP status of the request | ||
132 | * @param ud details about the upload operation | ||
133 | */ | ||
134 | static void | ||
135 | policy_store_cb (void *cls, | ||
136 | const struct ANASTASIS_UploadDetails *ud) | ||
137 | { | ||
138 | struct PolicyStoreState *pss = cls; | ||
139 | |||
140 | pss->pso = NULL; | ||
141 | if (ud->http_status != pss->http_status) | ||
142 | { | ||
143 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
144 | "Unexpected response code %u to command %s in %s:%u\n", | ||
145 | ud->http_status, | ||
146 | pss->is->commands[pss->is->ip].label, | ||
147 | __FILE__, | ||
148 | __LINE__); | ||
149 | TALER_TESTING_interpreter_fail (pss->is); | ||
150 | return; | ||
151 | } | ||
152 | switch (ud->us) | ||
153 | { | ||
154 | case ANASTASIS_US_SUCCESS: | ||
155 | if (0 != GNUNET_memcmp (&pss->curr_hash, | ||
156 | ud->details.success.curr_backup_hash)) | ||
157 | { | ||
158 | GNUNET_break (0); | ||
159 | TALER_TESTING_interpreter_fail (pss->is); | ||
160 | return; | ||
161 | } | ||
162 | break; | ||
163 | case ANASTASIS_US_PAYMENT_REQUIRED: | ||
164 | pss->payment_secret_response = ud->details.payment.ps; | ||
165 | { | ||
166 | struct TALER_MERCHANT_PayUriData pd; | ||
167 | |||
168 | if (GNUNET_OK != | ||
169 | TALER_MERCHANT_parse_pay_uri (ud->details.payment.payment_request, | ||
170 | &pd)) | ||
171 | { | ||
172 | GNUNET_break (0); | ||
173 | TALER_TESTING_interpreter_fail (pss->is); | ||
174 | return; | ||
175 | } | ||
176 | pss->order_id = GNUNET_strdup (pd.order_id); | ||
177 | if (NULL != pd.claim_token) | ||
178 | pss->claim_token = *pd.claim_token; | ||
179 | TALER_MERCHANT_parse_pay_uri_free (&pd); | ||
180 | } | ||
181 | break; | ||
182 | case ANASTASIS_US_HTTP_ERROR: | ||
183 | break; | ||
184 | case ANASTASIS_US_CLIENT_ERROR: | ||
185 | GNUNET_break (0); | ||
186 | TALER_TESTING_interpreter_fail (pss->is); | ||
187 | return; | ||
188 | case ANASTASIS_US_SERVER_ERROR: | ||
189 | GNUNET_break (0); | ||
190 | TALER_TESTING_interpreter_fail (pss->is); | ||
191 | return; | ||
192 | default: | ||
193 | GNUNET_break (0); | ||
194 | TALER_TESTING_interpreter_fail (pss->is); | ||
195 | return; | ||
196 | } | ||
197 | TALER_TESTING_interpreter_next (pss->is); | ||
198 | } | ||
199 | |||
200 | |||
201 | /** | ||
202 | * Run a "policy store" CMD. | ||
203 | * | ||
204 | * @param cls closure. | ||
205 | * @param cmd command currently being run. | ||
206 | * @param is interpreter state. | ||
207 | */ | ||
208 | static void | ||
209 | policy_store_run (void *cls, | ||
210 | const struct TALER_TESTING_Command *cmd, | ||
211 | struct TALER_TESTING_Interpreter *is) | ||
212 | { | ||
213 | struct PolicyStoreState *pss = cls; | ||
214 | |||
215 | pss->is = is; | ||
216 | if (NULL != pss->prev_upload) | ||
217 | { | ||
218 | const struct TALER_TESTING_Command *ref; | ||
219 | |||
220 | ref = TALER_TESTING_interpreter_lookup_command (is, | ||
221 | pss->prev_upload); | ||
222 | if (NULL == ref) | ||
223 | { | ||
224 | GNUNET_break (0); | ||
225 | TALER_TESTING_interpreter_fail (pss->is); | ||
226 | return; | ||
227 | } | ||
228 | { | ||
229 | const struct ANASTASIS_CRYPTO_AccountPrivateKeyP *priv; | ||
230 | |||
231 | if (GNUNET_OK != | ||
232 | ANASTASIS_TESTING_get_trait_account_priv (ref, | ||
233 | 0, | ||
234 | &priv)) | ||
235 | { | ||
236 | GNUNET_break (0); | ||
237 | TALER_TESTING_interpreter_fail (pss->is); | ||
238 | return; | ||
239 | } | ||
240 | pss->anastasis_priv = *priv; | ||
241 | } | ||
242 | { | ||
243 | const struct ANASTASIS_CRYPTO_AccountPublicKeyP *pub; | ||
244 | |||
245 | if (GNUNET_OK != | ||
246 | ANASTASIS_TESTING_get_trait_account_pub (ref, | ||
247 | 0, | ||
248 | &pub)) | ||
249 | { | ||
250 | GNUNET_break (0); | ||
251 | TALER_TESTING_interpreter_fail (pss->is); | ||
252 | return; | ||
253 | } | ||
254 | pss->anastasis_pub = *pub; | ||
255 | } | ||
256 | { | ||
257 | const struct ANASTASIS_PaymentSecretP *ps; | ||
258 | |||
259 | if (GNUNET_OK != | ||
260 | ANASTASIS_TESTING_get_trait_payment_secret (ref, | ||
261 | 0, | ||
262 | &ps)) | ||
263 | { | ||
264 | GNUNET_break (0); | ||
265 | TALER_TESTING_interpreter_fail (pss->is); | ||
266 | return; | ||
267 | } | ||
268 | pss->payment_secret_request = *ps; | ||
269 | pss->payment_secret_set = true; | ||
270 | } | ||
271 | } | ||
272 | else | ||
273 | { | ||
274 | GNUNET_CRYPTO_eddsa_key_create (&pss->anastasis_priv.priv); | ||
275 | GNUNET_CRYPTO_eddsa_key_get_public (&pss->anastasis_priv.priv, | ||
276 | &pss->anastasis_pub.pub); | ||
277 | } | ||
278 | |||
279 | GNUNET_CRYPTO_hash (pss->recovery_data, | ||
280 | pss->recovery_data_size, | ||
281 | &pss->curr_hash); | ||
282 | pss->pso = ANASTASIS_policy_store ( | ||
283 | is->ctx, | ||
284 | pss->anastasis_url, | ||
285 | &pss->anastasis_priv, | ||
286 | pss->recovery_data, | ||
287 | pss->recovery_data_size, | ||
288 | (0 != (ANASTASIS_TESTING_PSO_REQUEST_PAYMENT & pss->psopt)), | ||
289 | pss->payment_secret_set ? &pss->payment_secret_request : NULL, | ||
290 | GNUNET_TIME_UNIT_ZERO, | ||
291 | &policy_store_cb, | ||
292 | pss); | ||
293 | if (NULL == pss->pso) | ||
294 | { | ||
295 | GNUNET_break (0); | ||
296 | TALER_TESTING_interpreter_fail (pss->is); | ||
297 | return; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | |||
302 | /** | ||
303 | * Free the state of a "policy store" CMD, and possibly | ||
304 | * cancel it if it did not complete. | ||
305 | * | ||
306 | * @param cls closure. | ||
307 | * @param cmd command being freed. | ||
308 | */ | ||
309 | static void | ||
310 | policy_store_cleanup (void *cls, | ||
311 | const struct TALER_TESTING_Command *cmd) | ||
312 | { | ||
313 | struct PolicyStoreState *pss = cls; | ||
314 | |||
315 | if (NULL != pss->pso) | ||
316 | { | ||
317 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
318 | "Command '%s' did not complete (policy post)\n", | ||
319 | cmd->label); | ||
320 | ANASTASIS_policy_store_cancel (pss->pso); | ||
321 | pss->pso = NULL; | ||
322 | } | ||
323 | GNUNET_free (pss->order_id); | ||
324 | GNUNET_free (pss); | ||
325 | } | ||
326 | |||
327 | |||
328 | /** | ||
329 | * Offer internal data to other commands. | ||
330 | * | ||
331 | * @param cls closure | ||
332 | * @param[out] ret result (could be anything) | ||
333 | * @param trait name of the trait | ||
334 | * @param index index number of the object to extract. | ||
335 | * @return #GNUNET_OK on success | ||
336 | */ | ||
337 | static int | ||
338 | policy_store_traits (void *cls, | ||
339 | const void **ret, | ||
340 | const char *trait, | ||
341 | unsigned int index) | ||
342 | { | ||
343 | struct PolicyStoreState *pss = cls; | ||
344 | struct TALER_TESTING_Trait traits[] = { | ||
345 | TALER_TESTING_make_trait_claim_token (0, | ||
346 | &pss->claim_token), | ||
347 | TALER_TESTING_make_trait_order_id (0, | ||
348 | pss->order_id), | ||
349 | ANASTASIS_TESTING_make_trait_hash (0, | ||
350 | &pss->curr_hash), | ||
351 | ANASTASIS_TESTING_make_trait_account_pub (0, | ||
352 | &pss->anastasis_pub), | ||
353 | ANASTASIS_TESTING_make_trait_account_priv (0, | ||
354 | &pss->anastasis_priv), | ||
355 | ANASTASIS_TESTING_make_trait_payment_secret (0, | ||
356 | &pss->payment_secret_response), | ||
357 | TALER_TESTING_trait_end () | ||
358 | }; | ||
359 | |||
360 | return TALER_TESTING_get_trait (traits, | ||
361 | ret, | ||
362 | trait, | ||
363 | index); | ||
364 | } | ||
365 | |||
366 | |||
367 | struct TALER_TESTING_Command | ||
368 | ANASTASIS_TESTING_cmd_policy_store ( | ||
369 | const char *label, | ||
370 | const char *anastasis_url, | ||
371 | const char *prev_upload, | ||
372 | unsigned int http_status, | ||
373 | enum ANASTASIS_TESTING_PolicyStoreOption pso, | ||
374 | const void *recovery_data, | ||
375 | size_t recovery_data_size) | ||
376 | { | ||
377 | struct PolicyStoreState *pss; | ||
378 | |||
379 | pss = GNUNET_new (struct PolicyStoreState); | ||
380 | pss->recovery_data = recovery_data; | ||
381 | pss->recovery_data_size = recovery_data_size; | ||
382 | pss->http_status = http_status; | ||
383 | pss->psopt = pso; | ||
384 | pss->anastasis_url = anastasis_url; | ||
385 | pss->prev_upload = prev_upload; | ||
386 | { | ||
387 | struct TALER_TESTING_Command cmd = { | ||
388 | .cls = pss, | ||
389 | .label = label, | ||
390 | .run = &policy_store_run, | ||
391 | .cleanup = &policy_store_cleanup, | ||
392 | .traits = &policy_store_traits | ||
393 | }; | ||
394 | |||
395 | return cmd; | ||
396 | } | ||
397 | } | ||