testing_api_cmd_check_aml_decisions.c (7899B)
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 *oldest = 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 == oldest) || 124 (GNUNET_TIME_timestamp_cmp (oldest->decision_time, 125 >, 126 aml_history->decision_time)) ) 127 oldest = aml_history; 128 } 129 if (NULL == oldest) 130 { 131 GNUNET_break (0); 132 TALER_TESTING_interpreter_fail (ds->is); 133 return; 134 } 135 if (0 != strcmp (oldest->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 TALER_EXCHANGE_get_aml_decisions_set_options ( 229 ds->dh, 230 TALER_EXCHANGE_get_aml_decisions_option_offset (UINT64_MAX), 231 TALER_EXCHANGE_get_aml_decisions_option_limit (-1)); 232 if (NULL != h_payto) 233 TALER_EXCHANGE_get_aml_decisions_set_options ( 234 ds->dh, 235 TALER_EXCHANGE_get_aml_decisions_option_filter_h_payto (h_payto)); 236 { 237 enum TALER_ErrorCode ec; 238 239 ec = TALER_EXCHANGE_get_aml_decisions_start (ds->dh, 240 &check_aml_decisions_cb, 241 ds); 242 if (TALER_EC_NONE != ec) 243 { 244 GNUNET_break (0); 245 ds->dh = NULL; 246 TALER_TESTING_interpreter_fail (is); 247 return; 248 } 249 } 250 } 251 252 253 /** 254 * Free the state of a "check_aml_decision" CMD, and possibly cancel a 255 * pending operation thereof. 256 * 257 * @param cls closure, must be a `struct AmlCheckState`. 258 * @param cmd the command which is being cleaned up. 259 */ 260 static void 261 check_aml_decisions_cleanup ( 262 void *cls, 263 const struct TALER_TESTING_Command *cmd) 264 { 265 struct AmlCheckState *ds = cls; 266 267 if (NULL != ds->dh) 268 { 269 TALER_TESTING_command_incomplete (ds->is, 270 cmd->label); 271 TALER_EXCHANGE_get_aml_decisions_cancel (ds->dh); 272 ds->dh = NULL; 273 } 274 GNUNET_free (ds); 275 } 276 277 278 struct TALER_TESTING_Command 279 TALER_TESTING_cmd_check_aml_decisions ( 280 const char *label, 281 const char *ref_officer, 282 const char *ref_operation, 283 unsigned int expected_http_status) 284 { 285 struct AmlCheckState *ds; 286 287 ds = GNUNET_new (struct AmlCheckState); 288 ds->ref_officer = ref_officer; 289 ds->ref_operation = ref_operation; 290 ds->expected_http_status = expected_http_status; 291 { 292 struct TALER_TESTING_Command cmd = { 293 .cls = ds, 294 .label = label, 295 .run = &check_aml_decisions_run, 296 .cleanup = &check_aml_decisions_cleanup 297 }; 298 299 return cmd; 300 } 301 } 302 303 304 /* end of testing_api_cmd_check_aml_decisions.c */