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