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