Line data Source code
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 4 : check_aml_decisions_cb (
85 : TALER_EXCHANGE_GET_AML_DECISIONS_RESULT_CLOSURE *ds,
86 : const struct TALER_EXCHANGE_GetAmlDecisionsResponse *adr)
87 : {
88 4 : ds->dh = NULL;
89 4 : if (ds->expected_http_status != adr->hr.http_status)
90 : {
91 0 : TALER_TESTING_unexpected_status (ds->is,
92 : adr->hr.http_status,
93 : ds->expected_http_status);
94 0 : return;
95 : }
96 4 : if (MHD_HTTP_OK == adr->hr.http_status)
97 : {
98 : const struct TALER_TESTING_Command *ref;
99 : const char *justification;
100 2 : const struct TALER_EXCHANGE_GetAmlDecisionsDecision *latest = NULL;
101 :
102 2 : if (NULL != ds->ref_operation)
103 : {
104 1 : ref = TALER_TESTING_interpreter_lookup_command (
105 : ds->is,
106 : ds->ref_operation);
107 1 : if (NULL == ref)
108 : {
109 0 : GNUNET_break (0);
110 0 : TALER_TESTING_interpreter_fail (ds->is);
111 0 : return;
112 : }
113 1 : if (GNUNET_OK ==
114 1 : TALER_TESTING_get_trait_aml_justification (
115 : ref,
116 : &justification))
117 : {
118 2 : for (unsigned int i = 0; i<adr->details.ok.records_length; i++)
119 : {
120 1 : const struct TALER_EXCHANGE_GetAmlDecisionsDecision *aml_history
121 1 : = &adr->details.ok.records[i];
122 :
123 1 : if ( (NULL == latest) ||
124 0 : (GNUNET_TIME_timestamp_cmp (latest->decision_time,
125 : <,
126 : aml_history->decision_time)) )
127 1 : latest = aml_history;
128 : }
129 1 : if (NULL == latest)
130 : {
131 0 : GNUNET_break (0);
132 0 : TALER_TESTING_interpreter_fail (ds->is);
133 0 : return;
134 : }
135 1 : if (0 != strcmp (latest->justification,
136 : justification) )
137 : {
138 0 : GNUNET_break (0);
139 0 : TALER_TESTING_interpreter_fail (ds->is);
140 0 : return;
141 : }
142 : }
143 : }
144 : }
145 4 : 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 4 : check_aml_decisions_run (
158 : void *cls,
159 : const struct TALER_TESTING_Command *cmd,
160 : struct TALER_TESTING_Interpreter *is)
161 : {
162 4 : struct AmlCheckState *ds = cls;
163 4 : 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 4 : ds->is = is;
170 : {
171 : const struct TALER_TESTING_Command *exchange_cmd;
172 :
173 : exchange_cmd
174 4 : = TALER_TESTING_interpreter_get_command (
175 : is,
176 : "exchange");
177 4 : if (NULL == exchange_cmd)
178 : {
179 0 : GNUNET_break (0);
180 0 : TALER_TESTING_interpreter_fail (is);
181 0 : return;
182 : }
183 4 : GNUNET_assert (
184 : GNUNET_OK ==
185 : TALER_TESTING_get_trait_exchange_url (exchange_cmd,
186 : &exchange_url));
187 : }
188 :
189 4 : if (NULL != ds->ref_operation)
190 : {
191 3 : ref = TALER_TESTING_interpreter_lookup_command (
192 : is,
193 : ds->ref_operation);
194 3 : if (NULL == ref)
195 : {
196 0 : GNUNET_break (0);
197 0 : TALER_TESTING_interpreter_fail (is);
198 0 : return;
199 : }
200 3 : GNUNET_assert (GNUNET_OK ==
201 : TALER_TESTING_get_trait_h_normalized_payto (
202 : ref,
203 : &h_payto));
204 : }
205 4 : ref = TALER_TESTING_interpreter_lookup_command (
206 : is,
207 : ds->ref_officer);
208 4 : if (NULL == ref)
209 : {
210 0 : GNUNET_break (0);
211 0 : TALER_TESTING_interpreter_fail (is);
212 0 : return;
213 : }
214 4 : GNUNET_assert (GNUNET_OK ==
215 : TALER_TESTING_get_trait_officer_priv (
216 : ref,
217 : &officer_priv));
218 4 : ds->dh = TALER_EXCHANGE_get_aml_decisions_create (
219 : TALER_TESTING_interpreter_get_context (is),
220 : exchange_url,
221 : officer_priv);
222 4 : if (NULL == ds->dh)
223 : {
224 0 : GNUNET_break (0);
225 0 : TALER_TESTING_interpreter_fail (is);
226 0 : return;
227 : }
228 4 : if (GNUNET_OK !=
229 4 : 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 0 : GNUNET_break (0);
235 0 : TALER_TESTING_interpreter_fail (is);
236 0 : return;
237 : }
238 7 : if ( (NULL != h_payto) &&
239 : (GNUNET_OK !=
240 3 : TALER_EXCHANGE_get_aml_decisions_set_options (
241 : ds->dh,
242 : TALER_EXCHANGE_get_aml_decisions_option_filter_h_payto (h_payto))) )
243 : {
244 0 : GNUNET_break (0);
245 0 : TALER_TESTING_interpreter_fail (is);
246 0 : return;
247 : }
248 : {
249 : enum TALER_ErrorCode ec;
250 :
251 4 : ec = TALER_EXCHANGE_get_aml_decisions_start (ds->dh,
252 : &check_aml_decisions_cb,
253 : ds);
254 4 : if (TALER_EC_NONE != ec)
255 : {
256 0 : GNUNET_break (0);
257 0 : ds->dh = NULL;
258 0 : TALER_TESTING_interpreter_fail (is);
259 0 : 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 4 : check_aml_decisions_cleanup (
274 : void *cls,
275 : const struct TALER_TESTING_Command *cmd)
276 : {
277 4 : struct AmlCheckState *ds = cls;
278 :
279 4 : if (NULL != ds->dh)
280 : {
281 0 : TALER_TESTING_command_incomplete (ds->is,
282 : cmd->label);
283 0 : TALER_EXCHANGE_get_aml_decisions_cancel (ds->dh);
284 0 : ds->dh = NULL;
285 : }
286 4 : GNUNET_free (ds);
287 4 : }
288 :
289 :
290 : struct TALER_TESTING_Command
291 4 : 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 4 : ds = GNUNET_new (struct AmlCheckState);
300 4 : ds->ref_officer = ref_officer;
301 4 : ds->ref_operation = ref_operation;
302 4 : ds->expected_http_status = expected_http_status;
303 : {
304 4 : 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 4 : return cmd;
312 : }
313 : }
314 :
315 :
316 : /* end of testing_api_cmd_check_aml_decisions.c */
|