test_exchange_api_revocation.c (11935B)
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 * @file testing/test_exchange_api_revocation.c 21 * @brief testcase to test key revocation handling via the exchange's HTTP API interface 22 * @author Sree Harsha Totakura <sreeharsha@totakura.in> 23 * @author Christian Grothoff 24 * @author Marcello Stanisci 25 */ 26 #include "taler/platform.h" 27 #include "taler/taler_util.h" 28 #include "taler/taler_signatures.h" 29 #include "taler/taler_exchange_service.h" 30 #include "taler/taler_json_lib.h" 31 #include <gnunet/gnunet_util_lib.h> 32 #include <gnunet/gnunet_testing_lib.h> 33 #include <microhttpd.h> 34 #include "taler/taler_bank_service.h" 35 #include "taler/taler_fakebank_lib.h" 36 #include "taler/taler_testing_lib.h" 37 38 /** 39 * Configuration file we use. One (big) configuration is used 40 * for the various components for this test. 41 */ 42 static char *config_file; 43 44 /** 45 * Our credentials. 46 */ 47 static struct TALER_TESTING_Credentials cred; 48 49 50 /** 51 * Execute the taler-exchange-wirewatch command with 52 * our configuration file. 53 * 54 * @param label label to use for the command. 55 */ 56 static struct TALER_TESTING_Command 57 CMD_EXEC_WIREWATCH (const char *label) 58 { 59 return TALER_TESTING_cmd_exec_wirewatch2 (label, 60 config_file, 61 "exchange-account-2"); 62 } 63 64 65 /** 66 * Main function that will tell the interpreter what commands to 67 * run. 68 * 69 * @param cls closure 70 */ 71 static void 72 run (void *cls, 73 struct TALER_TESTING_Interpreter *is) 74 { 75 struct TALER_TESTING_Command revocation[] = { 76 TALER_TESTING_cmd_run_fakebank ("run-fakebank", 77 cred.cfg, 78 "exchange-account-2"), 79 TALER_TESTING_cmd_system_start ("start-taler", 80 config_file, 81 "-e", 82 NULL), 83 TALER_TESTING_cmd_get_exchange ("get-exchange", 84 cred.cfg, 85 NULL, 86 true, 87 true), 88 /** 89 * Fill reserve with EUR:10.02, as withdraw fee is 1 ct per 90 * config. 91 */ 92 TALER_TESTING_cmd_admin_add_incoming ("create-reserve-1", 93 "EUR:10.02", 94 &cred.ba, 95 cred.user42_payto), 96 TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-1", 97 "EUR:10.02", 98 cred.user42_payto, 99 cred.exchange_payto, 100 "create-reserve-1"), 101 /** 102 * Run wire-watch to trigger the reserve creation. 103 */ 104 CMD_EXEC_WIREWATCH ("wirewatch-4"), 105 /* Withdraw a 5 EUR coin, at fee of 1 ct */ 106 TALER_TESTING_cmd_withdraw_amount ("withdraw-revocation-coin-1", 107 "create-reserve-1", 108 "EUR:5", 109 0, /* age restriction off */ 110 MHD_HTTP_OK), 111 /* Withdraw another 5 EUR coin, at fee of 1 ct */ 112 TALER_TESTING_cmd_withdraw_amount ("withdraw-revocation-coin-2", 113 "create-reserve-1", 114 "EUR:5", 115 0, /* age restriction off */ 116 MHD_HTTP_OK), 117 /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin (in full) 118 * (merchant would receive EUR:0.99 due to 1 ct deposit fee) */// 119 TALER_TESTING_cmd_set_var ( 120 "account-priv", 121 TALER_TESTING_cmd_deposit ( 122 "deposit-partial-fail-kyc", 123 "withdraw-revocation-coin-1", 124 0, 125 cred.user42_payto, 126 "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}", 127 GNUNET_TIME_UNIT_ZERO, 128 "EUR:1", 129 MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)), 130 TALER_TESTING_cmd_admin_add_kycauth ( 131 "kyc-auth-transfer", 132 "EUR:0.01", 133 &cred.ba, 134 cred.user42_payto, 135 "deposit-partial-fail-kyc"), 136 CMD_EXEC_WIREWATCH ( 137 "import-kyc-account-withdraw"), 138 TALER_TESTING_cmd_deposit ( 139 "deposit-partial", 140 "withdraw-revocation-coin-1", 141 0, 142 cred.user42_payto, 143 "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:2\"}]}", 144 GNUNET_TIME_UNIT_ZERO, 145 "EUR:1", 146 MHD_HTTP_OK), 147 /* Deposit another coin in full */ 148 TALER_TESTING_cmd_deposit ( 149 "deposit-full", 150 "withdraw-revocation-coin-2", 151 0, 152 cred.user42_payto, 153 "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:5\"}]}", 154 GNUNET_TIME_UNIT_ZERO, 155 "EUR:5", 156 MHD_HTTP_OK), 157 /** 158 * Melt SOME of the rest of the coin's value 159 * (EUR:3.17 = 3x EUR:1.03 + 7x EUR:0.13) 160 */ 161 TALER_TESTING_cmd_melt ("refresh-melt-1", 162 "withdraw-revocation-coin-1", 163 MHD_HTTP_OK, 164 NULL), 165 /** 166 * Complete (successful) melt operation, and withdraw the coins 167 */ 168 TALER_TESTING_cmd_refresh_reveal ("refresh-reveal-1", 169 "refresh-melt-1", 170 MHD_HTTP_OK), 171 /* Try to recoup before it's allowed */ 172 TALER_TESTING_cmd_recoup_refresh ("recoup-not-allowed", 173 MHD_HTTP_GONE, 174 "refresh-reveal-1#0", 175 "refresh-melt-1", 176 "EUR:0.1"), 177 /* Make refreshed coin invalid */ 178 TALER_TESTING_cmd_revoke ("revoke-2-EUR:5", 179 MHD_HTTP_OK, 180 "refresh-melt-1", 181 config_file), 182 /* Also make fully spent coin invalid (should be same denom) */ 183 TALER_TESTING_cmd_revoke ("revoke-2-EUR:5", 184 MHD_HTTP_OK, 185 "withdraw-revocation-coin-2", 186 config_file), 187 /* Refund fully spent coin (which should fail) */ 188 TALER_TESTING_cmd_recoup ("recoup-fully-spent", 189 MHD_HTTP_CONFLICT, 190 "withdraw-revocation-coin-2", 191 "EUR:0.1"), 192 /* Refund coin to original coin */ 193 TALER_TESTING_cmd_recoup_refresh ("recoup-1a", 194 MHD_HTTP_OK, 195 "refresh-reveal-1#0", 196 "refresh-melt-1", 197 "EUR:1"), 198 TALER_TESTING_cmd_recoup_refresh ("recoup-1b", 199 MHD_HTTP_OK, 200 "refresh-reveal-1#1", 201 "refresh-melt-1", 202 "EUR:1"), 203 TALER_TESTING_cmd_recoup_refresh ("recoup-1c", 204 MHD_HTTP_OK, 205 "refresh-reveal-1#2", 206 "refresh-melt-1", 207 "EUR:1"), 208 /* Repeat recoup to test idempotency */ 209 TALER_TESTING_cmd_recoup_refresh ("recoup-1c", 210 MHD_HTTP_OK, 211 "refresh-reveal-1#2", 212 "refresh-melt-1", 213 "EUR:1"), 214 TALER_TESTING_cmd_recoup_refresh ("recoup-1c", 215 MHD_HTTP_OK, 216 "refresh-reveal-1#2", 217 "refresh-melt-1", 218 "EUR:1"), 219 TALER_TESTING_cmd_recoup_refresh ("recoup-1c", 220 MHD_HTTP_OK, 221 "refresh-reveal-1#2", 222 "refresh-melt-1", 223 "EUR:1"), 224 TALER_TESTING_cmd_recoup_refresh ("recoup-1c", 225 MHD_HTTP_OK, 226 "refresh-reveal-1#2", 227 "refresh-melt-1", 228 "EUR:1"), 229 /* Now we have EUR:3.83 EUR back after 3x EUR:1 in recoups */ 230 /* Melt original coin AGAIN, but only create one 0.1 EUR coin; 231 This costs EUR:0.03 in refresh and EUR:01 in withdraw fees, 232 leaving EUR:3.69. */ 233 TALER_TESTING_cmd_melt ("refresh-melt-2", 234 "withdraw-revocation-coin-1", 235 MHD_HTTP_OK, 236 "EUR:0.1", 237 NULL), 238 /** 239 * Complete (successful) melt operation, and withdraw the coins 240 */ 241 TALER_TESTING_cmd_refresh_reveal ("refresh-reveal-2", 242 "refresh-melt-2", 243 MHD_HTTP_OK), 244 /* Revokes refreshed EUR:0.1 coin */ 245 TALER_TESTING_cmd_revoke ("revoke-3-EUR:0.1", 246 MHD_HTTP_OK, 247 "refresh-reveal-2", 248 config_file), 249 /* Revoke also original coin denomination */ 250 TALER_TESTING_cmd_revoke ("revoke-4-EUR:5", 251 MHD_HTTP_OK, 252 "withdraw-revocation-coin-1", 253 config_file), 254 /* Refund coin EUR:0.1 to original coin, creating zombie! */ 255 TALER_TESTING_cmd_recoup_refresh ("recoup-2", 256 MHD_HTTP_OK, 257 "refresh-reveal-2", 258 "refresh-melt-2", 259 "EUR:0.1"), 260 /* Due to recoup, original coin is now at EUR:3.79 */ 261 /* Refund original (now zombie) coin to reserve */ 262 TALER_TESTING_cmd_recoup ("recoup-3", 263 MHD_HTTP_OK, 264 "withdraw-revocation-coin-1", 265 "EUR:3.79"), 266 /* Check the money is back with the reserve */ 267 TALER_TESTING_cmd_status ("recoup-reserve-status-1", 268 "create-reserve-1", 269 "EUR:3.79", 270 MHD_HTTP_OK), 271 TALER_TESTING_cmd_end () 272 }; 273 274 (void) cls; 275 TALER_TESTING_run (is, 276 revocation); 277 } 278 279 280 int 281 main (int argc, 282 char *const *argv) 283 { 284 (void) argc; 285 { 286 char *cipher; 287 288 cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]); 289 GNUNET_assert (NULL != cipher); 290 GNUNET_asprintf (&config_file, 291 "test_exchange_api-%s.conf", 292 cipher); 293 GNUNET_free (cipher); 294 } 295 return TALER_TESTING_main (argv, 296 "INFO", 297 config_file, 298 "exchange-account-2", 299 TALER_TESTING_BS_FAKEBANK, 300 &cred, 301 &run, 302 NULL); 303 } 304 305 306 /* end of test_exchange_api_revocation.c */