Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2022, 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 : /**
17 : * @file src/backenddb/iterate_kyc_statuses.c
18 : * @brief Implementation of the iterate_kyc_statuses function for Postgres
19 : * @author Iván Ávalos
20 : */
21 : #include "platform.h"
22 : #include <taler/taler_pq_lib.h>
23 : #include "merchant-database/iterate_kyc_statuses.h"
24 : #include "helper.h"
25 :
26 : /**
27 : * Closure for kyc_status_cb().
28 : */
29 : struct KycStatusContext
30 : {
31 : /**
32 : * Function to call with results.
33 : */
34 : TALER_MERCHANTDB_KycCallback kyc_cb;
35 :
36 : /**
37 : * Closure for @e kyc_cb.
38 : */
39 : void *kyc_cb_cls;
40 :
41 : /**
42 : * Number of results found.
43 : */
44 : unsigned int count;
45 :
46 : /**
47 : * Set to true on failure(s).
48 : */
49 : bool failure;
50 : };
51 :
52 :
53 : /**
54 : * Function to be called with the results of a SELECT statement
55 : * that has returned @a num_results results about accounts.
56 : *
57 : * @param[in,out] cls of type `struct KycStatusContext *`
58 : * @param result the postgres result
59 : * @param num_results the number of results in @a result
60 : */
61 : static void
62 18 : kyc_status_cb (void *cls,
63 : PGresult *result,
64 : unsigned int num_results)
65 : {
66 18 : struct KycStatusContext *ksc = cls;
67 :
68 18 : GNUNET_log (GNUNET_ERROR_TYPE_INFO,
69 : "Got %u KYC records\n",
70 : num_results);
71 38 : for (unsigned int i = 0; i < num_results; i++)
72 : {
73 : struct TALER_MerchantWireHashP h_wire;
74 20 : char *exchange_url = NULL;
75 : struct TALER_FullPayto payto_uri;
76 20 : struct GNUNET_TIME_Timestamp last_check
77 : = GNUNET_TIME_UNIT_ZERO_TS;
78 20 : bool kyc_ok = false;
79 : struct TALER_AccountAccessTokenP access_token;
80 20 : bool no_auth = false;
81 20 : uint32_t h32 = 0;
82 20 : uint32_t e32 = 0;
83 20 : bool in_aml_review = false;
84 : bool no_mk; /* left join on merchant_kyc table yielded nothing */
85 20 : json_t *jlimits = NULL;
86 20 : struct GNUNET_PQ_ResultSpec rs[] = {
87 20 : GNUNET_PQ_result_spec_auto_from_type ("h_wire",
88 : &h_wire),
89 20 : GNUNET_PQ_result_spec_string ("payto_uri",
90 : &payto_uri.full_payto),
91 20 : GNUNET_PQ_result_spec_allow_null (
92 : GNUNET_PQ_result_spec_string ("exchange_url",
93 : &exchange_url),
94 : &no_mk),
95 20 : GNUNET_PQ_result_spec_allow_null (
96 : GNUNET_PQ_result_spec_timestamp ("kyc_timestamp",
97 : &last_check),
98 : &no_mk),
99 20 : GNUNET_PQ_result_spec_allow_null (
100 : GNUNET_PQ_result_spec_bool ("kyc_ok",
101 : &kyc_ok),
102 : &no_mk),
103 20 : GNUNET_PQ_result_spec_allow_null (
104 : GNUNET_PQ_result_spec_auto_from_type ("access_token",
105 : &access_token),
106 : &no_auth),
107 20 : GNUNET_PQ_result_spec_allow_null (
108 : GNUNET_PQ_result_spec_uint32 ("exchange_http_status",
109 : &h32),
110 : &no_mk),
111 20 : GNUNET_PQ_result_spec_allow_null (
112 : GNUNET_PQ_result_spec_uint32 ("exchange_ec_code",
113 : &e32),
114 : &no_mk),
115 20 : GNUNET_PQ_result_spec_allow_null (
116 : GNUNET_PQ_result_spec_bool ("aml_review",
117 : &in_aml_review),
118 : &no_mk),
119 20 : GNUNET_PQ_result_spec_allow_null (
120 : TALER_PQ_result_spec_json ("jaccount_limits",
121 : &jlimits),
122 : NULL),
123 : GNUNET_PQ_result_spec_end
124 : };
125 : unsigned int last_http_status;
126 : enum TALER_ErrorCode last_ec;
127 :
128 20 : if (GNUNET_OK !=
129 20 : GNUNET_PQ_extract_result (result,
130 : rs,
131 : i))
132 : {
133 0 : GNUNET_break (0);
134 0 : ksc->failure = true;
135 0 : return;
136 : }
137 20 : last_http_status = (unsigned int) h32;
138 20 : last_ec = (enum TALER_ErrorCode) (int) e32;
139 20 : ksc->count++;
140 20 : ksc->kyc_cb (ksc->kyc_cb_cls,
141 : &h_wire,
142 : payto_uri,
143 : exchange_url,
144 : last_check,
145 : kyc_ok,
146 : (no_auth)
147 : ? NULL
148 : : &access_token,
149 : last_http_status,
150 : last_ec,
151 : in_aml_review,
152 : jlimits);
153 20 : GNUNET_PQ_cleanup_result (rs);
154 : }
155 : }
156 :
157 :
158 : enum GNUNET_DB_QueryStatus
159 18 : TALER_MERCHANTDB_iterate_kyc_statuses (
160 : struct TALER_MERCHANTDB_PostgresContext *pg,
161 : const char *merchant_id,
162 : const struct TALER_MerchantWireHashP *h_wire,
163 : const char *exchange_url,
164 : TALER_MERCHANTDB_KycCallback kyc_cb,
165 : void *kyc_cb_cls)
166 : {
167 18 : struct KycStatusContext ksc = {
168 : .kyc_cb = kyc_cb,
169 : .kyc_cb_cls = kyc_cb_cls
170 : };
171 : struct GNUNET_TIME_Absolute now
172 18 : = GNUNET_TIME_absolute_get ();
173 18 : struct GNUNET_PQ_QueryParam params[] = {
174 18 : GNUNET_PQ_query_param_absolute_time (&now),
175 : NULL == exchange_url
176 5 : ? GNUNET_PQ_query_param_null ()
177 18 : : GNUNET_PQ_query_param_string (exchange_url),
178 : NULL == h_wire
179 13 : ? GNUNET_PQ_query_param_null ()
180 18 : : GNUNET_PQ_query_param_auto_from_type (h_wire),
181 : GNUNET_PQ_query_param_end
182 : };
183 : enum GNUNET_DB_QueryStatus qs;
184 :
185 18 : GNUNET_assert (NULL != pg->current_merchant_id);
186 18 : GNUNET_assert (0 == strcmp (merchant_id,
187 : pg->current_merchant_id));
188 18 : TMH_PQ_prepare_anon (pg,
189 : "SELECT "
190 : " out_h_wire AS h_wire"
191 : " ,out_payto_uri AS payto_uri"
192 : " ,out_exchange_url AS exchange_url"
193 : " ,out_kyc_timestamp AS kyc_timestamp"
194 : " ,out_kyc_ok AS kyc_ok"
195 : " ,out_access_token AS access_token"
196 : " ,out_exchange_http_status AS exchange_http_status"
197 : " ,out_exchange_ec_code AS exchange_ec_code"
198 : " ,out_aml_review AS aml_review"
199 : " ,out_jaccount_limits::TEXT AS jaccount_limits"
200 : " FROM merchant_do_account_kyc_get_status($1, $2, $3);");
201 18 : qs = GNUNET_PQ_eval_prepared_multi_select (
202 : pg->conn,
203 : "",
204 : params,
205 : &kyc_status_cb,
206 : &ksc);
207 18 : if (ksc.failure)
208 : {
209 0 : GNUNET_break (0);
210 0 : return GNUNET_DB_STATUS_HARD_ERROR;
211 : }
212 18 : if (0 > qs)
213 0 : return qs;
214 18 : return ksc.count;
215 : }
|