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 *oldest = 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 == oldest) ||
124 0 : (GNUNET_TIME_timestamp_cmp (oldest->decision_time,
125 : >,
126 : aml_history->decision_time)) )
127 1 : oldest = aml_history;
128 : }
129 1 : if (NULL == oldest)
130 : {
131 0 : GNUNET_break (0);
132 0 : TALER_TESTING_interpreter_fail (ds->is);
133 0 : return;
134 : }
135 1 : if (0 != strcmp (oldest->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 : 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 4 : if (NULL != h_payto)
233 3 : 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 4 : ec = TALER_EXCHANGE_get_aml_decisions_start (ds->dh,
240 : &check_aml_decisions_cb,
241 : ds);
242 4 : if (TALER_EC_NONE != ec)
243 : {
244 0 : GNUNET_break (0);
245 0 : ds->dh = NULL;
246 0 : TALER_TESTING_interpreter_fail (is);
247 0 : 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 4 : check_aml_decisions_cleanup (
262 : void *cls,
263 : const struct TALER_TESTING_Command *cmd)
264 : {
265 4 : struct AmlCheckState *ds = cls;
266 :
267 4 : if (NULL != ds->dh)
268 : {
269 0 : TALER_TESTING_command_incomplete (ds->is,
270 : cmd->label);
271 0 : TALER_EXCHANGE_get_aml_decisions_cancel (ds->dh);
272 0 : ds->dh = NULL;
273 : }
274 4 : GNUNET_free (ds);
275 4 : }
276 :
277 :
278 : struct TALER_TESTING_Command
279 4 : 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 4 : ds = GNUNET_new (struct AmlCheckState);
288 4 : ds->ref_officer = ref_officer;
289 4 : ds->ref_operation = ref_operation;
290 4 : ds->expected_http_status = expected_http_status;
291 : {
292 4 : 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 4 : return cmd;
300 : }
301 : }
302 :
303 :
304 : /* end of testing_api_cmd_check_aml_decisions.c */
|