Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2015--2024 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
15 : <http://www.gnu.org/licenses/>
16 : */
17 : /**
18 : * @file bank-lib/bank_api_admin_add_kycauth.c
19 : * @brief Implementation of the /admin/add-kycauth requests of the bank's HTTP API
20 : * @author Christian Grothoff
21 : */
22 : #include "bank_api_common.h"
23 : #include <microhttpd.h> /* just for HTTP status codes */
24 : #include "taler/taler_signatures.h"
25 : #include "taler/taler_curl_lib.h"
26 :
27 :
28 : /**
29 : * @brief An /admin/add-kycauth Handle
30 : */
31 : struct TALER_BANK_AdminAddKycauthHandle
32 : {
33 :
34 : /**
35 : * The url for this request.
36 : */
37 : char *request_url;
38 :
39 : /**
40 : * POST context.
41 : */
42 : struct TALER_CURL_PostContext post_ctx;
43 :
44 : /**
45 : * Handle for the request.
46 : */
47 : struct GNUNET_CURL_Job *job;
48 :
49 : /**
50 : * Function to call with the result.
51 : */
52 : TALER_BANK_AdminAddKycauthCallback cb;
53 :
54 : /**
55 : * Closure for @a cb.
56 : */
57 : void *cb_cls;
58 :
59 : };
60 :
61 :
62 : /**
63 : * Function called when we're done processing the
64 : * HTTP /admin/add-kycauth request.
65 : *
66 : * @param cls the `struct TALER_BANK_AdminAddKycauthHandle`
67 : * @param response_code HTTP response code, 0 on error
68 : * @param response parsed JSON result, NULL on error
69 : */
70 : static void
71 16 : handle_admin_add_kycauth_finished (void *cls,
72 : long response_code,
73 : const void *response)
74 : {
75 16 : struct TALER_BANK_AdminAddKycauthHandle *aai = cls;
76 16 : const json_t *j = response;
77 16 : struct TALER_BANK_AdminAddKycauthResponse ir = {
78 : .http_status = response_code,
79 : .response = response
80 : };
81 :
82 16 : aai->job = NULL;
83 16 : switch (response_code)
84 : {
85 0 : case 0:
86 0 : ir.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
87 0 : break;
88 16 : case MHD_HTTP_OK:
89 : {
90 : struct GNUNET_JSON_Specification spec[] = {
91 16 : GNUNET_JSON_spec_uint64 ("row_id",
92 : &ir.details.ok.serial_id),
93 16 : GNUNET_JSON_spec_timestamp ("timestamp",
94 : &ir.details.ok.timestamp),
95 16 : GNUNET_JSON_spec_end ()
96 : };
97 :
98 16 : if (GNUNET_OK !=
99 16 : GNUNET_JSON_parse (j,
100 : spec,
101 : NULL, NULL))
102 : {
103 0 : GNUNET_break_op (0);
104 0 : ir.http_status = 0;
105 0 : ir.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
106 0 : break;
107 : }
108 : }
109 16 : break;
110 0 : case MHD_HTTP_BAD_REQUEST:
111 : /* This should never happen, either us or the bank is buggy
112 : (or API version conflict); just pass JSON reply to the application */
113 0 : GNUNET_break_op (0);
114 0 : ir.ec = TALER_JSON_get_error_code (j);
115 0 : break;
116 0 : case MHD_HTTP_FORBIDDEN:
117 : /* Access denied */
118 0 : ir.ec = TALER_JSON_get_error_code (j);
119 0 : break;
120 0 : case MHD_HTTP_UNAUTHORIZED:
121 : /* Nothing really to verify, bank says the password is invalid; we should
122 : pass the JSON reply to the application */
123 0 : ir.ec = TALER_JSON_get_error_code (j);
124 0 : break;
125 0 : case MHD_HTTP_NOT_FOUND:
126 : /* Nothing really to verify, maybe account really does not exist.
127 : We should pass the JSON reply to the application */
128 0 : ir.ec = TALER_JSON_get_error_code (j);
129 0 : break;
130 0 : case MHD_HTTP_INTERNAL_SERVER_ERROR:
131 : /* Server had an internal issue; we should retry, but this API
132 : leaves this to the application */
133 0 : ir.ec = TALER_JSON_get_error_code (j);
134 0 : break;
135 0 : default:
136 : /* unexpected response code */
137 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
138 : "Unexpected response code %u\n",
139 : (unsigned int) response_code);
140 0 : GNUNET_break (0);
141 0 : ir.ec = TALER_JSON_get_error_code (j);
142 0 : break;
143 : }
144 16 : aai->cb (aai->cb_cls,
145 : &ir);
146 16 : TALER_BANK_admin_add_kycauth_cancel (aai);
147 16 : }
148 :
149 :
150 : struct TALER_BANK_AdminAddKycauthHandle *
151 16 : TALER_BANK_admin_add_kycauth (
152 : struct GNUNET_CURL_Context *ctx,
153 : const struct TALER_BANK_AuthenticationData *auth,
154 : const union TALER_AccountPublicKeyP *account_pub,
155 : const struct TALER_Amount *amount,
156 : const struct TALER_FullPayto debit_account,
157 : TALER_BANK_AdminAddKycauthCallback res_cb,
158 : void *res_cb_cls)
159 : {
160 : struct TALER_BANK_AdminAddKycauthHandle *aai;
161 : json_t *admin_obj;
162 : CURL *eh;
163 :
164 16 : if (NULL == debit_account.full_payto)
165 : {
166 0 : GNUNET_break (0);
167 0 : return NULL;
168 : }
169 16 : if (NULL == account_pub)
170 : {
171 0 : GNUNET_break (0);
172 0 : return NULL;
173 : }
174 16 : if (NULL == amount)
175 : {
176 0 : GNUNET_break (0);
177 0 : return NULL;
178 : }
179 16 : admin_obj = GNUNET_JSON_PACK (
180 : GNUNET_JSON_pack_data_auto ("account_pub",
181 : account_pub),
182 : TALER_JSON_pack_amount ("amount",
183 : amount),
184 : TALER_JSON_pack_full_payto ("debit_account",
185 : debit_account));
186 16 : if (NULL == admin_obj)
187 : {
188 0 : GNUNET_break (0);
189 0 : return NULL;
190 : }
191 16 : aai = GNUNET_new (struct TALER_BANK_AdminAddKycauthHandle);
192 16 : aai->cb = res_cb;
193 16 : aai->cb_cls = res_cb_cls;
194 16 : aai->request_url = TALER_url_join (auth->wire_gateway_url,
195 : "admin/add-kycauth",
196 : NULL);
197 16 : if (NULL == aai->request_url)
198 : {
199 0 : GNUNET_free (aai);
200 0 : json_decref (admin_obj);
201 0 : return NULL;
202 : }
203 16 : GNUNET_log (GNUNET_ERROR_TYPE_INFO,
204 : "Requesting administrative transaction at `%s' for account %s\n",
205 : aai->request_url,
206 : TALER_B2S (account_pub));
207 : aai->post_ctx.headers
208 16 : = curl_slist_append (
209 : aai->post_ctx.headers,
210 : "Content-Type: application/json");
211 :
212 16 : eh = curl_easy_init ();
213 32 : if ( (NULL == eh) ||
214 : (GNUNET_OK !=
215 16 : TALER_BANK_setup_auth_ (eh,
216 16 : auth)) ||
217 : (CURLE_OK !=
218 16 : curl_easy_setopt (eh,
219 : CURLOPT_URL,
220 16 : aai->request_url)) ||
221 : (GNUNET_OK !=
222 16 : TALER_curl_easy_post (&aai->post_ctx,
223 : eh,
224 : admin_obj)) )
225 : {
226 0 : GNUNET_break (0);
227 0 : TALER_BANK_admin_add_kycauth_cancel (aai);
228 0 : if (NULL != eh)
229 0 : curl_easy_cleanup (eh);
230 0 : json_decref (admin_obj);
231 0 : return NULL;
232 : }
233 16 : json_decref (admin_obj);
234 :
235 32 : aai->job = GNUNET_CURL_job_add2 (ctx,
236 : eh,
237 16 : aai->post_ctx.headers,
238 : &handle_admin_add_kycauth_finished,
239 : aai);
240 16 : return aai;
241 : }
242 :
243 :
244 : void
245 16 : TALER_BANK_admin_add_kycauth_cancel (
246 : struct TALER_BANK_AdminAddKycauthHandle *aai)
247 : {
248 16 : if (NULL != aai->job)
249 : {
250 0 : GNUNET_CURL_job_cancel (aai->job);
251 0 : aai->job = NULL;
252 : }
253 16 : TALER_curl_easy_post_finished (&aai->post_ctx);
254 16 : GNUNET_free (aai->request_url);
255 16 : GNUNET_free (aai);
256 16 : }
257 :
258 :
259 : /* end of bank_api_admin_add_kycauth.c */
|