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