testing_api_cmd_check_aml_decisions.c (8139B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2023, 2024, 2026 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it 6 under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3, or (at your 8 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 GNU 13 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_check_aml_decisions.c 21 * @brief command for testing GET /aml/$OFFICER_PUB/decisions 22 * @author Christian Grothoff 23 */ 24 #include "taler/taler_json_lib.h" 25 #include <gnunet/gnunet_curl_lib.h> 26 27 /** 28 * State for a "check_aml_decisions" CMD. 29 */ 30 struct AmlCheckState; 31 32 #define TALER_EXCHANGE_GET_AML_DECISIONS_RESULT_CLOSURE \ 33 struct AmlCheckState 34 #include "taler/exchange/get-aml-OFFICER_PUB-decisions.h" 35 #include "taler/taler_testing_lib.h" 36 #include "taler/taler_signatures.h" 37 38 39 /** 40 * State for a "check_aml_decisions" CMD. 41 */ 42 struct AmlCheckState 43 { 44 45 /** 46 * Handle while operation is running. 47 */ 48 struct TALER_EXCHANGE_GetAmlDecisionsHandle *dh; 49 50 /** 51 * Our interpreter. 52 */ 53 struct TALER_TESTING_Interpreter *is; 54 55 /** 56 * Reference to command to previous set officer. 57 */ 58 const char *ref_officer; 59 60 /** 61 * Reference to a command with a trait of a payto-URI for an account we want 62 * to get the status on; NULL to match all accounts. If it has also a 63 * justification trait, we check that this is the current justification for 64 * the latest AML decision. 65 */ 66 const char *ref_operation; 67 68 /** 69 * Expected HTTP status. 70 */ 71 unsigned int expected_http_status; 72 73 }; 74 75 76 /** 77 * Callback to analyze the /aml/$OFFICER_PUB/$decision/$H_PAYTO response, just used to check 78 * if the response code is acceptable. 79 * 80 * @param ds our state 81 * @param adr response details 82 */ 83 static void 84 check_aml_decisions_cb ( 85 TALER_EXCHANGE_GET_AML_DECISIONS_RESULT_CLOSURE *ds, 86 const struct TALER_EXCHANGE_GetAmlDecisionsResponse *adr) 87 { 88 ds->dh = NULL; 89 if (ds->expected_http_status != adr->hr.http_status) 90 { 91 TALER_TESTING_unexpected_status (ds->is, 92 adr->hr.http_status, 93 ds->expected_http_status); 94 return; 95 } 96 if (MHD_HTTP_OK == adr->hr.http_status) 97 { 98 const struct TALER_TESTING_Command *ref; 99 const char *justification; 100 const struct TALER_EXCHANGE_GetAmlDecisionsDecision *latest = NULL; 101 102 if (NULL != ds->ref_operation) 103 { 104 ref = TALER_TESTING_interpreter_lookup_command ( 105 ds->is, 106 ds->ref_operation); 107 if (NULL == ref) 108 { 109 GNUNET_break (0); 110 TALER_TESTING_interpreter_fail (ds->is); 111 return; 112 } 113 if (GNUNET_OK == 114 TALER_TESTING_get_trait_aml_justification ( 115 ref, 116 &justification)) 117 { 118 for (unsigned int i = 0; i<adr->details.ok.records_length; i++) 119 { 120 const struct TALER_EXCHANGE_GetAmlDecisionsDecision *aml_history 121 = &adr->details.ok.records[i]; 122 123 if ( (NULL == latest) || 124 (GNUNET_TIME_timestamp_cmp (latest->decision_time, 125 <, 126 aml_history->decision_time)) ) 127 latest = aml_history; 128 } 129 if (NULL == latest) 130 { 131 GNUNET_break (0); 132 TALER_TESTING_interpreter_fail (ds->is); 133 return; 134 } 135 if (0 != strcmp (latest->justification, 136 justification) ) 137 { 138 GNUNET_break (0); 139 TALER_TESTING_interpreter_fail (ds->is); 140 return; 141 } 142 } 143 } 144 } 145 TALER_TESTING_interpreter_next (ds->is); 146 } 147 148 149 /** 150 * Run the command. 151 * 152 * @param cls closure. 153 * @param cmd the command to execute. 154 * @param is the interpreter state. 155 */ 156 static void 157 check_aml_decisions_run ( 158 void *cls, 159 const struct TALER_TESTING_Command *cmd, 160 struct TALER_TESTING_Interpreter *is) 161 { 162 struct AmlCheckState *ds = cls; 163 const struct TALER_NormalizedPaytoHashP *h_payto = NULL; 164 const struct TALER_AmlOfficerPrivateKeyP *officer_priv; 165 const struct TALER_TESTING_Command *ref; 166 const char *exchange_url; 167 168 (void) cmd; 169 ds->is = is; 170 { 171 const struct TALER_TESTING_Command *exchange_cmd; 172 173 exchange_cmd 174 = TALER_TESTING_interpreter_get_command ( 175 is, 176 "exchange"); 177 if (NULL == exchange_cmd) 178 { 179 GNUNET_break (0); 180 TALER_TESTING_interpreter_fail (is); 181 return; 182 } 183 GNUNET_assert ( 184 GNUNET_OK == 185 TALER_TESTING_get_trait_exchange_url (exchange_cmd, 186 &exchange_url)); 187 } 188 189 if (NULL != ds->ref_operation) 190 { 191 ref = TALER_TESTING_interpreter_lookup_command ( 192 is, 193 ds->ref_operation); 194 if (NULL == ref) 195 { 196 GNUNET_break (0); 197 TALER_TESTING_interpreter_fail (is); 198 return; 199 } 200 GNUNET_assert (GNUNET_OK == 201 TALER_TESTING_get_trait_h_normalized_payto ( 202 ref, 203 &h_payto)); 204 } 205 ref = TALER_TESTING_interpreter_lookup_command ( 206 is, 207 ds->ref_officer); 208 if (NULL == ref) 209 { 210 GNUNET_break (0); 211 TALER_TESTING_interpreter_fail (is); 212 return; 213 } 214 GNUNET_assert (GNUNET_OK == 215 TALER_TESTING_get_trait_officer_priv ( 216 ref, 217 &officer_priv)); 218 ds->dh = TALER_EXCHANGE_get_aml_decisions_create ( 219 TALER_TESTING_interpreter_get_context (is), 220 exchange_url, 221 officer_priv); 222 if (NULL == ds->dh) 223 { 224 GNUNET_break (0); 225 TALER_TESTING_interpreter_fail (is); 226 return; 227 } 228 if (GNUNET_OK != 229 TALER_EXCHANGE_get_aml_decisions_set_options ( 230 ds->dh, 231 TALER_EXCHANGE_get_aml_decisions_option_offset (INT64_MAX), 232 TALER_EXCHANGE_get_aml_decisions_option_limit (-1))) 233 { 234 GNUNET_break (0); 235 TALER_TESTING_interpreter_fail (is); 236 return; 237 } 238 if ( (NULL != h_payto) && 239 (GNUNET_OK != 240 TALER_EXCHANGE_get_aml_decisions_set_options ( 241 ds->dh, 242 TALER_EXCHANGE_get_aml_decisions_option_filter_h_payto (h_payto))) ) 243 { 244 GNUNET_break (0); 245 TALER_TESTING_interpreter_fail (is); 246 return; 247 } 248 { 249 enum TALER_ErrorCode ec; 250 251 ec = TALER_EXCHANGE_get_aml_decisions_start (ds->dh, 252 &check_aml_decisions_cb, 253 ds); 254 if (TALER_EC_NONE != ec) 255 { 256 GNUNET_break (0); 257 ds->dh = NULL; 258 TALER_TESTING_interpreter_fail (is); 259 return; 260 } 261 } 262 } 263 264 265 /** 266 * Free the state of a "check_aml_decision" CMD, and possibly cancel a 267 * pending operation thereof. 268 * 269 * @param cls closure, must be a `struct AmlCheckState`. 270 * @param cmd the command which is being cleaned up. 271 */ 272 static void 273 check_aml_decisions_cleanup ( 274 void *cls, 275 const struct TALER_TESTING_Command *cmd) 276 { 277 struct AmlCheckState *ds = cls; 278 279 if (NULL != ds->dh) 280 { 281 TALER_TESTING_command_incomplete (ds->is, 282 cmd->label); 283 TALER_EXCHANGE_get_aml_decisions_cancel (ds->dh); 284 ds->dh = NULL; 285 } 286 GNUNET_free (ds); 287 } 288 289 290 struct TALER_TESTING_Command 291 TALER_TESTING_cmd_check_aml_decisions ( 292 const char *label, 293 const char *ref_officer, 294 const char *ref_operation, 295 unsigned int expected_http_status) 296 { 297 struct AmlCheckState *ds; 298 299 ds = GNUNET_new (struct AmlCheckState); 300 ds->ref_officer = ref_officer; 301 ds->ref_operation = ref_operation; 302 ds->expected_http_status = expected_http_status; 303 { 304 struct TALER_TESTING_Command cmd = { 305 .cls = ds, 306 .label = label, 307 .run = &check_aml_decisions_run, 308 .cleanup = &check_aml_decisions_cleanup 309 }; 310 311 return cmd; 312 } 313 } 314 315 316 /* end of testing_api_cmd_check_aml_decisions.c */