testing_api_cmd_donation_statement_get.c (6731B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2024 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/testing_api_cmd_donation_statement_get.c 21 * @brief Implement the GET /donation-statement/$YEAR/$HASH_DONOR_ID test command. 22 * @author Marcello Stanisci 23 * @author Lukas Matyja 24 */ 25 #include <donau_config.h> 26 #include <taler/taler_json_lib.h> 27 #include <gnunet/gnunet_curl_lib.h> 28 #include <taler/taler_testing_lib.h> 29 struct StatusState; 30 #define DONAU_GET_DONATION_STATEMENT_RESULT_CLOSURE struct StatusState 31 #include "donau_testing_lib.h" 32 33 34 /** 35 * State for a "status" CMD. 36 */ 37 struct StatusState 38 { 39 /** 40 * Handle to the "charity status" operation. 41 */ 42 struct DONAU_DonationStatementGetHandle *dsgh; 43 44 /** 45 * Expected HTTP response code. 46 */ 47 unsigned int expected_response_code; 48 49 /** 50 * Interpreter state. 51 */ 52 struct TALER_TESTING_Interpreter *is; 53 54 /** 55 * The Donation Statement 56 */ 57 struct DONAU_DonationStatement donation_statement; 58 59 /** 60 * The Donau keys 61 */ 62 struct DONAU_Keys *keys; 63 64 }; 65 66 /** 67 * Check that the reserve balance and HTTP response code are 68 * both acceptable. 69 * 70 * @param ss closure. 71 * @param dsr HTTP response details 72 */ 73 static void 74 donation_statement_status_cb (struct StatusState *ss, 75 const struct DONAU_DonationStatementResponse *dsr) 76 { 77 ss->dsgh = NULL; 78 if (ss->expected_response_code != dsr->hr.http_status) 79 { 80 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 81 "Unexpected HTTP response code: %d in %s:%u\n", 82 dsr->hr.http_status, 83 __FILE__, 84 __LINE__); 85 json_dumpf (dsr->hr.reply, 86 stderr, 87 0); 88 TALER_TESTING_interpreter_fail (ss->is); 89 return; 90 } 91 92 /* Get donau keys from trait */ 93 { 94 const struct TALER_TESTING_Command *keys_cmd; 95 struct DONAU_Keys *keys; 96 97 keys_cmd = TALER_TESTING_interpreter_lookup_command (ss->is, 98 "get-donau"); 99 100 if (GNUNET_OK != 101 TALER_TESTING_get_trait_donau_keys (keys_cmd, 102 &keys)) 103 { 104 GNUNET_break (0); 105 TALER_TESTING_interpreter_fail (ss->is); 106 return; 107 } 108 ss->keys = keys; 109 } 110 111 ss->donation_statement.total_amount = dsr->details.ok.total_amount; 112 ss->donation_statement.donation_statement_sig = 113 dsr->details.ok.donation_statement_sig; 114 115 for (unsigned int i = 0; i < ss->keys->num_sign_keys; i++) 116 { 117 if (0 != 118 GNUNET_memcmp (&ss->keys->sign_keys[i].key, 119 &dsr->details.ok.donau_pub)) 120 continue; 121 if (GNUNET_OK == 122 DONAU_donation_statement_verify ( 123 &ss->donation_statement.total_amount, 124 ss->donation_statement.year, 125 ss->donation_statement.h_donor_tax_id, 126 &ss->keys->sign_keys[i].key, 127 &ss->donation_statement.donation_statement_sig)) 128 { 129 char *qr_string = DONAU_generate_qr_string (&dsr->details.ok.donau_pub, 130 &ss->donation_statement); 131 132 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 133 "qr-string: %s\n", 134 qr_string); 135 GNUNET_free (qr_string); 136 137 TALER_TESTING_interpreter_next (ss->is); 138 return; 139 } 140 } 141 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 142 "Verify donation statement signature failed!"); 143 TALER_TESTING_interpreter_fail (ss->is); 144 } 145 146 147 /** 148 * Run the command. 149 * 150 * @param cls closure. 151 * @param cmd the command being executed. 152 * @param is the interpreter state. 153 */ 154 static void 155 status_run (void *cls, 156 const struct TALER_TESTING_Command *cmd, 157 struct TALER_TESTING_Interpreter *is) 158 { 159 struct StatusState *ss = cls; 160 161 (void) cmd; 162 ss->is = is; 163 /* Get charity salted tax id hash from trait */ 164 { 165 const struct TALER_TESTING_Command *issue_receipts_cmd; 166 const struct DONAU_HashDonorTaxId *h_donor_tax_id; 167 const char *donor_salt; 168 const char *donor_tax_id; 169 170 issue_receipts_cmd = TALER_TESTING_interpreter_lookup_command (is, 171 "issue-receipts"); 172 173 if (GNUNET_OK != TALER_TESTING_get_trait_salted_tax_id_hash 174 (issue_receipts_cmd, &h_donor_tax_id) || 175 GNUNET_OK != TALER_TESTING_get_trait_donor_salt 176 (issue_receipts_cmd, &donor_salt) || 177 GNUNET_OK != TALER_TESTING_get_trait_donor_tax_id 178 (issue_receipts_cmd, &donor_tax_id)) 179 { 180 GNUNET_break (0); 181 TALER_TESTING_interpreter_fail (is); 182 return; 183 } 184 ss->donation_statement.donor_tax_id = donor_tax_id; 185 ss->donation_statement.salt = donor_salt; 186 ss->donation_statement.h_donor_tax_id = h_donor_tax_id; 187 } 188 189 ss->dsgh = DONAU_donation_statement_get ( 190 TALER_TESTING_interpreter_get_context (is), 191 TALER_TESTING_get_donau_url (is), 192 ss->donation_statement.year, 193 ss->donation_statement.h_donor_tax_id, 194 &donation_statement_status_cb, 195 ss); 196 } 197 198 199 /** 200 * Cleanup the state from a "reserve status" CMD, and possibly 201 * cancel a pending operation thereof. 202 * 203 * @param cls closure. 204 * @param cmd the command which is being cleaned up. 205 */ 206 static void 207 status_cleanup (void *cls, 208 const struct TALER_TESTING_Command *cmd) 209 { 210 struct StatusState *ss = cls; 211 212 if (NULL != ss->dsgh) 213 { 214 // log incomplete command 215 TALER_TESTING_command_incomplete (ss->is, 216 cmd->label); 217 DONAU_donation_statement_get_cancel (ss->dsgh); 218 ss->dsgh = NULL; 219 } 220 GNUNET_free (ss); 221 } 222 223 224 struct TALER_TESTING_Command 225 TALER_TESTING_cmd_donation_statement_get (const char *label, 226 uint64_t year, 227 unsigned int expected_response_code) 228 { 229 struct StatusState *ss; 230 231 ss = GNUNET_new (struct StatusState); 232 ss->donation_statement.year = year; 233 ss->expected_response_code = expected_response_code; 234 { 235 struct TALER_TESTING_Command cmd = { 236 .cls = ss, 237 .label = label, 238 .run = &status_run, 239 .cleanup = &status_cleanup 240 }; 241 242 return cmd; 243 } 244 }