Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2026 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : #include <gnunet/gnunet_util_lib.h>
17 : #include <gnunet/gnunet_json_lib.h>
18 : #include <jansson.h>
19 : #include <microhttpd.h>
20 : #include <pthread.h>
21 : #include "taler/taler_json_lib.h"
22 : #include "taler/taler_mhd_lib.h"
23 : #include "exchangedb_lib.h"
24 : #include "taler-auditor-httpd.h"
25 : #include "taler-auditor-httpd_get-monitoring-aml-holds.h"
26 : #define TALER_AUDITORDB_AUDITOR_AML_HOLD_RESULT_CLOSURE json_t
27 : #include "auditor-database/iterate_auditor_aml_holds.h"
28 : #include "auditor-database/preflight.h"
29 :
30 :
31 : /**
32 : * Convert the reason the exchange gave for not making a transfer into the
33 : * string the REST API uses for it.
34 : *
35 : * @param reason an `enum TALER_EXCHANGEDB_DeferralReason` value
36 : * @return human-readable name of @a reason
37 : */
38 : static const char *
39 0 : reason2s (uint32_t reason)
40 : {
41 0 : switch ((enum TALER_EXCHANGEDB_DeferralReason) reason)
42 : {
43 0 : case TALER_EXCHANGEDB_DR_NONE:
44 0 : return "NONE";
45 0 : case TALER_EXCHANGEDB_DR_AMOUNT_TOO_SMALL:
46 0 : return "AMOUNT_TOO_SMALL";
47 0 : case TALER_EXCHANGEDB_DR_KYC:
48 0 : return "KYC";
49 : }
50 : /* the exchange wrote a reason this auditor does not know; say so rather
51 : than guess, the row is still a hold either way */
52 0 : GNUNET_break (0);
53 0 : return "INVALID";
54 : }
55 :
56 :
57 : /**
58 : * Add an AML hold to the list.
59 : *
60 : * @param[in,out] list a `json_t *` array to extend
61 : * @param ah the hold
62 : * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating
63 : */
64 : static enum GNUNET_GenericReturnValue
65 0 : process_aml_holds (
66 : json_t *list,
67 : const struct TALER_AUDITORDB_AmlHold *ah)
68 : {
69 : json_t *obj;
70 :
71 0 : obj = GNUNET_JSON_PACK (
72 : GNUNET_JSON_pack_uint64 ("row_id",
73 : ah->row_id),
74 : GNUNET_JSON_pack_data_auto ("wtid",
75 : &ah->wtid),
76 : GNUNET_JSON_pack_data_auto ("wire_target_h_payto",
77 : &ah->wire_target_h_payto),
78 : TALER_JSON_pack_full_payto ("account",
79 : ah->account),
80 : TALER_JSON_pack_amount ("amount",
81 : &ah->amount),
82 : GNUNET_JSON_pack_string ("deferral_reason",
83 : reason2s (ah->deferral_reason)),
84 : GNUNET_JSON_pack_uint64 ("legitimization_measure_serial_id",
85 : ah->legitimization_measure_serial_id),
86 : TALER_JSON_pack_time_abs_human ("first_seen",
87 : ah->creation_date),
88 : GNUNET_JSON_pack_bool ("suppressed",
89 : ah->suppressed)
90 : );
91 0 : GNUNET_break (0 ==
92 : json_array_append_new (list,
93 : obj));
94 0 : return GNUNET_OK;
95 : }
96 :
97 :
98 : enum MHD_Result
99 0 : TAH_get_monitoring_aml_holds (
100 : struct TAH_RequestHandler *rh,
101 : struct MHD_Connection *connection,
102 : void **connection_cls,
103 : const char *upload_data,
104 : size_t *upload_data_size,
105 : const char *const args[])
106 : {
107 : json_t *ja;
108 : enum GNUNET_DB_QueryStatus qs;
109 0 : int64_t limit = -20;
110 : uint64_t offset;
111 0 : bool return_suppressed = false;
112 :
113 0 : if (GNUNET_SYSERR ==
114 0 : TALER_AUDITORDB_preflight (TAH_apg))
115 : {
116 0 : GNUNET_break (0);
117 0 : return TALER_MHD_reply_with_error (connection,
118 : MHD_HTTP_INTERNAL_SERVER_ERROR,
119 : TALER_EC_GENERIC_DB_SETUP_FAILED,
120 : NULL);
121 : }
122 0 : TAH_PARSE_REQUEST_LIMIT (connection,
123 : "limit",
124 : &limit);
125 0 : if (limit < 0)
126 0 : offset = TAH_SAFE_UINT64_MAX;
127 : else
128 0 : offset = 0;
129 0 : TAH_PARSE_SAFE_REQUEST_NUMBER (connection,
130 : "offset",
131 : &offset);
132 : {
133 : const char *ret_s
134 0 : = MHD_lookup_connection_value (connection,
135 : MHD_GET_ARGUMENT_KIND,
136 : "return_suppressed");
137 0 : if (ret_s != NULL && strcmp (ret_s, "true") == 0)
138 : {
139 0 : return_suppressed = true;
140 : }
141 : }
142 0 : ja = json_array ();
143 0 : GNUNET_break (NULL != ja);
144 0 : qs = TALER_AUDITORDB_iterate_auditor_aml_holds (
145 : TAH_apg,
146 : limit,
147 : offset,
148 : return_suppressed,
149 : &process_aml_holds,
150 : ja);
151 0 : if (0 > qs)
152 : {
153 0 : GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
154 0 : json_decref (ja);
155 0 : TALER_LOG_WARNING (
156 : "Failed to handle GET /monitoring/aml-holds\n");
157 0 : return TALER_MHD_reply_with_error (connection,
158 : MHD_HTTP_INTERNAL_SERVER_ERROR,
159 : TALER_EC_GENERIC_DB_FETCH_FAILED,
160 : "iterate_auditor_aml_holds");
161 : }
162 0 : return TAH_reply_json_records (connection,
163 : ja);
164 : }
|