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