testing_api_cmd_policy_store.c (9756B)
1 /* 2 This file is part of ANASTASIS 3 Copyright (C) 2014-2019 Anastasis SARL 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 testing/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 an #ANASTASIS_policy_store() operation. 129 * 130 * @param cls closure 131 * @param ud details about the upload operation 132 */ 133 static void 134 policy_store_cb (void *cls, 135 const struct ANASTASIS_UploadDetails *ud) 136 { 137 struct PolicyStoreState *pss = cls; 138 139 pss->pso = NULL; 140 if (ud->http_status != pss->http_status) 141 { 142 TALER_TESTING_unexpected_status (pss->is, 143 ud->http_status, 144 pss->http_status); 145 return; 146 } 147 switch (ud->us) 148 { 149 case ANASTASIS_US_SUCCESS: 150 if (0 != GNUNET_memcmp (&pss->curr_hash, 151 ud->details.success.curr_backup_hash)) 152 { 153 GNUNET_break (0); 154 TALER_TESTING_interpreter_fail (pss->is); 155 return; 156 } 157 break; 158 case ANASTASIS_US_PAYMENT_REQUIRED: 159 pss->payment_secret_response = ud->details.payment.ps; 160 { 161 struct TALER_MERCHANT_PayUriData pd; 162 163 if (GNUNET_OK != 164 TALER_MERCHANT_parse_pay_uri (ud->details.payment.payment_request, 165 &pd)) 166 { 167 GNUNET_break (0); 168 TALER_TESTING_interpreter_fail (pss->is); 169 return; 170 } 171 pss->order_id = GNUNET_strdup (pd.order_id); 172 if (NULL != pd.claim_token) 173 pss->claim_token = *pd.claim_token; 174 TALER_MERCHANT_parse_pay_uri_free (&pd); 175 } 176 break; 177 case ANASTASIS_US_HTTP_ERROR: 178 break; 179 case ANASTASIS_US_CLIENT_ERROR: 180 GNUNET_break (0); 181 TALER_TESTING_interpreter_fail (pss->is); 182 return; 183 case ANASTASIS_US_SERVER_ERROR: 184 GNUNET_break (0); 185 TALER_TESTING_interpreter_fail (pss->is); 186 return; 187 default: 188 GNUNET_break (0); 189 TALER_TESTING_interpreter_fail (pss->is); 190 return; 191 } 192 TALER_TESTING_interpreter_next (pss->is); 193 } 194 195 196 /** 197 * Run a "policy store" CMD. 198 * 199 * @param cls closure. 200 * @param cmd command currently being run. 201 * @param is interpreter state. 202 */ 203 static void 204 policy_store_run (void *cls, 205 const struct TALER_TESTING_Command *cmd, 206 struct TALER_TESTING_Interpreter *is) 207 { 208 struct PolicyStoreState *pss = cls; 209 210 pss->is = is; 211 if (NULL != pss->prev_upload) 212 { 213 const struct TALER_TESTING_Command *ref; 214 215 ref = TALER_TESTING_interpreter_lookup_command (is, 216 pss->prev_upload); 217 if (NULL == ref) 218 { 219 GNUNET_break (0); 220 TALER_TESTING_interpreter_fail (pss->is); 221 return; 222 } 223 { 224 const struct ANASTASIS_CRYPTO_AccountPrivateKeyP *priv; 225 226 if (GNUNET_OK != 227 ANASTASIS_TESTING_get_trait_account_priv (ref, 228 &priv)) 229 { 230 GNUNET_break (0); 231 TALER_TESTING_interpreter_fail (pss->is); 232 return; 233 } 234 pss->anastasis_priv = *priv; 235 } 236 { 237 const struct ANASTASIS_CRYPTO_AccountPublicKeyP *pub; 238 239 if (GNUNET_OK != 240 ANASTASIS_TESTING_get_trait_account_pub (ref, 241 &pub)) 242 { 243 GNUNET_break (0); 244 TALER_TESTING_interpreter_fail (pss->is); 245 return; 246 } 247 pss->anastasis_pub = *pub; 248 } 249 { 250 const struct ANASTASIS_PaymentSecretP *ps; 251 252 if (GNUNET_OK != 253 ANASTASIS_TESTING_get_trait_payment_secret (ref, 254 &ps)) 255 { 256 GNUNET_break (0); 257 TALER_TESTING_interpreter_fail (pss->is); 258 return; 259 } 260 pss->payment_secret_request = *ps; 261 pss->payment_secret_set = true; 262 } 263 } 264 else 265 { 266 GNUNET_CRYPTO_eddsa_key_create (&pss->anastasis_priv.priv); 267 GNUNET_CRYPTO_eddsa_key_get_public (&pss->anastasis_priv.priv, 268 &pss->anastasis_pub.pub); 269 } 270 271 GNUNET_CRYPTO_hash (pss->recovery_data, 272 pss->recovery_data_size, 273 &pss->curr_hash); 274 pss->pso = ANASTASIS_policy_store ( 275 TALER_TESTING_interpreter_get_context (is), 276 pss->anastasis_url, 277 &pss->anastasis_priv, 278 pss->recovery_data, 279 pss->recovery_data_size, 280 "metadata", strlen ("metadata"), 281 (0 != (ANASTASIS_TESTING_PSO_REQUEST_PAYMENT & pss->psopt)), 282 pss->payment_secret_set ? &pss->payment_secret_request : NULL, 283 GNUNET_TIME_UNIT_ZERO, 284 &policy_store_cb, 285 pss); 286 if (NULL == pss->pso) 287 { 288 GNUNET_break (0); 289 TALER_TESTING_interpreter_fail (pss->is); 290 return; 291 } 292 } 293 294 295 /** 296 * Free the state of a "policy store" CMD, and possibly 297 * cancel it if it did not complete. 298 * 299 * @param cls closure. 300 * @param cmd command being freed. 301 */ 302 static void 303 policy_store_cleanup (void *cls, 304 const struct TALER_TESTING_Command *cmd) 305 { 306 struct PolicyStoreState *pss = cls; 307 308 if (NULL != pss->pso) 309 { 310 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 311 "Command '%s' did not complete (policy post)\n", 312 cmd->label); 313 ANASTASIS_policy_store_cancel (pss->pso); 314 pss->pso = NULL; 315 } 316 GNUNET_free (pss->order_id); 317 GNUNET_free (pss); 318 } 319 320 321 /** 322 * Offer internal data to other commands. 323 * 324 * @param cls closure 325 * @param[out] ret result (could be anything) 326 * @param trait name of the trait 327 * @param index index number of the object to extract. 328 * @return #GNUNET_OK on success 329 */ 330 static int 331 policy_store_traits (void *cls, 332 const void **ret, 333 const char *trait, 334 unsigned int index) 335 { 336 struct PolicyStoreState *pss = cls; 337 struct TALER_TESTING_Trait traits[] = { 338 TALER_TESTING_make_trait_claim_token (&pss->claim_token), 339 TALER_TESTING_make_trait_order_id (pss->order_id), 340 ANASTASIS_TESTING_make_trait_hash (&pss->curr_hash), 341 ANASTASIS_TESTING_make_trait_account_pub (&pss->anastasis_pub), 342 ANASTASIS_TESTING_make_trait_account_priv (&pss->anastasis_priv), 343 ANASTASIS_TESTING_make_trait_payment_secret (&pss->payment_secret_response), 344 TALER_TESTING_trait_end () 345 }; 346 347 return TALER_TESTING_get_trait (traits, 348 ret, 349 trait, 350 index); 351 } 352 353 354 struct TALER_TESTING_Command 355 ANASTASIS_TESTING_cmd_policy_store ( 356 const char *label, 357 const char *anastasis_url, 358 const char *prev_upload, 359 unsigned int http_status, 360 enum ANASTASIS_TESTING_PolicyStoreOption pso, 361 const void *recovery_data, 362 size_t recovery_data_size) 363 { 364 struct PolicyStoreState *pss; 365 366 pss = GNUNET_new (struct PolicyStoreState); 367 pss->recovery_data = recovery_data; 368 pss->recovery_data_size = recovery_data_size; 369 pss->http_status = http_status; 370 pss->psopt = pso; 371 pss->anastasis_url = anastasis_url; 372 pss->prev_upload = prev_upload; 373 { 374 struct TALER_TESTING_Command cmd = { 375 .cls = pss, 376 .label = label, 377 .run = &policy_store_run, 378 .cleanup = &policy_store_cleanup, 379 .traits = &policy_store_traits 380 }; 381 382 return cmd; 383 } 384 }