Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2015-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
15 : <http://www.gnu.org/licenses/>
16 : */
17 : /**
18 : * @file lib/exchange_api_post-management-auditors.c
19 : * @brief functions to enable an auditor
20 : * @author Christian Grothoff
21 : */
22 : #include "taler/platform.h"
23 : #include "taler/taler_json_lib.h"
24 : #include <gnunet/gnunet_curl_lib.h>
25 : #include <microhttpd.h>
26 : #include "taler/taler_exchange_service.h"
27 : #include "taler/taler-exchange/post-management-auditors.h"
28 : #include "exchange_api_curl_defaults.h"
29 : #include "taler/taler_signatures.h"
30 : #include "taler/taler_curl_lib.h"
31 :
32 :
33 : /**
34 : * @brief Handle for a POST /management/auditors request.
35 : */
36 : struct TALER_EXCHANGE_PostManagementAuditorsHandle
37 : {
38 :
39 : /**
40 : * The base URL for this request.
41 : */
42 : char *base_url;
43 :
44 : /**
45 : * The full URL for this request, set during _start.
46 : */
47 : char *url;
48 :
49 : /**
50 : * Minor context that holds body and headers.
51 : */
52 : struct TALER_CURL_PostContext post_ctx;
53 :
54 : /**
55 : * Handle for the request.
56 : */
57 : struct GNUNET_CURL_Job *job;
58 :
59 : /**
60 : * Function to call with the result.
61 : */
62 : TALER_EXCHANGE_PostManagementAuditorsCallback cb;
63 :
64 : /**
65 : * Closure for @a cb.
66 : */
67 : TALER_EXCHANGE_POST_MANAGEMENT_AUDITORS_RESULT_CLOSURE *cb_cls;
68 :
69 : /**
70 : * Reference to the execution context.
71 : */
72 : struct GNUNET_CURL_Context *ctx;
73 :
74 : /**
75 : * Public signing key of the auditor.
76 : */
77 : struct TALER_AuditorPublicKeyP auditor_pub;
78 :
79 : /**
80 : * Base URL of the auditor.
81 : */
82 : char *auditor_url;
83 :
84 : /**
85 : * Human-readable name of the auditor.
86 : */
87 : char *auditor_name;
88 :
89 : /**
90 : * When was this decided?
91 : */
92 : struct GNUNET_TIME_Timestamp validity_start;
93 :
94 : /**
95 : * Signature affirming the auditor addition.
96 : */
97 : struct TALER_MasterSignatureP master_sig;
98 :
99 : };
100 :
101 :
102 : /**
103 : * Function called when we're done processing the
104 : * HTTP POST /management/auditors request.
105 : *
106 : * @param cls the `struct TALER_EXCHANGE_PostManagementAuditorsHandle`
107 : * @param response_code HTTP response code, 0 on error
108 : * @param response response body, NULL if not in JSON
109 : */
110 : static void
111 10 : handle_auditors_finished (void *cls,
112 : long response_code,
113 : const void *response)
114 : {
115 10 : struct TALER_EXCHANGE_PostManagementAuditorsHandle *pmah = cls;
116 10 : const json_t *json = response;
117 10 : struct TALER_EXCHANGE_PostManagementAuditorsResponse res = {
118 10 : .hr.http_status = (unsigned int) response_code,
119 : .hr.reply = json
120 : };
121 :
122 10 : pmah->job = NULL;
123 10 : switch (response_code)
124 : {
125 8 : case MHD_HTTP_NO_CONTENT:
126 8 : break;
127 2 : case MHD_HTTP_FORBIDDEN:
128 2 : res.hr.ec = TALER_JSON_get_error_code (json);
129 2 : res.hr.hint = TALER_JSON_get_error_hint (json);
130 2 : break;
131 0 : case MHD_HTTP_NOT_FOUND:
132 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
133 : "Server did not find handler at `%s'. Did you configure the correct exchange base URL?\n",
134 : pmah->url);
135 0 : if (NULL != json)
136 : {
137 0 : res.hr.ec = TALER_JSON_get_error_code (json);
138 0 : res.hr.hint = TALER_JSON_get_error_hint (json);
139 : }
140 : else
141 : {
142 0 : res.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
143 0 : res.hr.hint = TALER_ErrorCode_get_hint (res.hr.ec);
144 : }
145 0 : break;
146 0 : case MHD_HTTP_CONFLICT:
147 0 : res.hr.ec = TALER_JSON_get_error_code (json);
148 0 : res.hr.hint = TALER_JSON_get_error_hint (json);
149 0 : break;
150 0 : default:
151 : /* unexpected response code */
152 0 : GNUNET_break_op (0);
153 0 : res.hr.ec = TALER_JSON_get_error_code (json);
154 0 : res.hr.hint = TALER_JSON_get_error_hint (json);
155 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
156 : "Unexpected response code %u/%d for exchange management auditor enable\n",
157 : (unsigned int) response_code,
158 : (int) res.hr.ec);
159 0 : break;
160 : }
161 10 : if (NULL != pmah->cb)
162 : {
163 10 : pmah->cb (pmah->cb_cls,
164 : &res);
165 10 : pmah->cb = NULL;
166 : }
167 10 : TALER_EXCHANGE_post_management_auditors_cancel (pmah);
168 10 : }
169 :
170 :
171 : struct TALER_EXCHANGE_PostManagementAuditorsHandle *
172 10 : TALER_EXCHANGE_post_management_auditors_create (
173 : struct GNUNET_CURL_Context *ctx,
174 : const char *url,
175 : const struct TALER_AuditorPublicKeyP *auditor_pub,
176 : const char *auditor_url,
177 : const char *auditor_name,
178 : struct GNUNET_TIME_Timestamp validity_start,
179 : const struct TALER_MasterSignatureP *master_sig)
180 : {
181 : struct TALER_EXCHANGE_PostManagementAuditorsHandle *pmah;
182 :
183 10 : pmah = GNUNET_new (struct TALER_EXCHANGE_PostManagementAuditorsHandle);
184 10 : pmah->ctx = ctx;
185 10 : pmah->base_url = GNUNET_strdup (url);
186 10 : pmah->auditor_pub = *auditor_pub;
187 10 : pmah->auditor_url = GNUNET_strdup (auditor_url);
188 10 : pmah->auditor_name = GNUNET_strdup (auditor_name);
189 10 : pmah->validity_start = validity_start;
190 10 : pmah->master_sig = *master_sig;
191 10 : return pmah;
192 : }
193 :
194 :
195 : enum TALER_ErrorCode
196 10 : TALER_EXCHANGE_post_management_auditors_start (
197 : struct TALER_EXCHANGE_PostManagementAuditorsHandle *pmah,
198 : TALER_EXCHANGE_PostManagementAuditorsCallback cb,
199 : TALER_EXCHANGE_POST_MANAGEMENT_AUDITORS_RESULT_CLOSURE *cb_cls)
200 : {
201 : CURL *eh;
202 : json_t *body;
203 :
204 10 : pmah->cb = cb;
205 10 : pmah->cb_cls = cb_cls;
206 10 : pmah->url = TALER_url_join (pmah->base_url,
207 : "management/auditors",
208 : NULL);
209 10 : if (NULL == pmah->url)
210 : {
211 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
212 : "Could not construct request URL.\n");
213 0 : return TALER_EC_GENERIC_CONFIGURATION_INVALID;
214 : }
215 10 : body = GNUNET_JSON_PACK (
216 : GNUNET_JSON_pack_string ("auditor_url",
217 : pmah->auditor_url),
218 : GNUNET_JSON_pack_string ("auditor_name",
219 : pmah->auditor_name),
220 : GNUNET_JSON_pack_data_auto ("auditor_pub",
221 : &pmah->auditor_pub),
222 : GNUNET_JSON_pack_data_auto ("master_sig",
223 : &pmah->master_sig),
224 : GNUNET_JSON_pack_timestamp ("validity_start",
225 : pmah->validity_start));
226 10 : eh = TALER_EXCHANGE_curl_easy_get_ (pmah->url);
227 20 : if ( (NULL == eh) ||
228 : (GNUNET_OK !=
229 10 : TALER_curl_easy_post (&pmah->post_ctx,
230 : eh,
231 : body)) )
232 : {
233 0 : GNUNET_break (0);
234 0 : if (NULL != eh)
235 0 : curl_easy_cleanup (eh);
236 0 : json_decref (body);
237 0 : GNUNET_free (pmah->url);
238 0 : pmah->url = NULL;
239 0 : return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
240 : }
241 10 : json_decref (body);
242 10 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
243 : "Requesting URL '%s'\n",
244 : pmah->url);
245 20 : pmah->job = GNUNET_CURL_job_add2 (pmah->ctx,
246 : eh,
247 10 : pmah->post_ctx.headers,
248 : &handle_auditors_finished,
249 : pmah);
250 10 : if (NULL == pmah->job)
251 : {
252 0 : TALER_curl_easy_post_finished (&pmah->post_ctx);
253 0 : GNUNET_free (pmah->url);
254 0 : pmah->url = NULL;
255 0 : return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
256 : }
257 10 : return TALER_EC_NONE;
258 : }
259 :
260 :
261 : void
262 10 : TALER_EXCHANGE_post_management_auditors_cancel (
263 : struct TALER_EXCHANGE_PostManagementAuditorsHandle *pmah)
264 : {
265 10 : if (NULL != pmah->job)
266 : {
267 0 : GNUNET_CURL_job_cancel (pmah->job);
268 0 : pmah->job = NULL;
269 : }
270 10 : TALER_curl_easy_post_finished (&pmah->post_ctx);
271 10 : GNUNET_free (pmah->auditor_url);
272 10 : GNUNET_free (pmah->auditor_name);
273 10 : GNUNET_free (pmah->url);
274 10 : GNUNET_free (pmah->base_url);
275 10 : GNUNET_free (pmah);
276 10 : }
277 :
278 :
279 : /* end of exchange_api_post-management-auditors.c */
|