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_CONFLICT:
132 0 : res.hr.ec = TALER_JSON_get_error_code (json);
133 0 : res.hr.hint = TALER_JSON_get_error_hint (json);
134 0 : break;
135 0 : default:
136 : /* unexpected response code */
137 0 : GNUNET_break_op (0);
138 0 : res.hr.ec = TALER_JSON_get_error_code (json);
139 0 : res.hr.hint = TALER_JSON_get_error_hint (json);
140 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
141 : "Unexpected response code %u/%d for exchange management auditor enable\n",
142 : (unsigned int) response_code,
143 : (int) res.hr.ec);
144 0 : break;
145 : }
146 10 : if (NULL != pmah->cb)
147 : {
148 10 : pmah->cb (pmah->cb_cls,
149 : &res);
150 10 : pmah->cb = NULL;
151 : }
152 10 : TALER_EXCHANGE_post_management_auditors_cancel (pmah);
153 10 : }
154 :
155 :
156 : struct TALER_EXCHANGE_PostManagementAuditorsHandle *
157 10 : TALER_EXCHANGE_post_management_auditors_create (
158 : struct GNUNET_CURL_Context *ctx,
159 : const char *url,
160 : const struct TALER_AuditorPublicKeyP *auditor_pub,
161 : const char *auditor_url,
162 : const char *auditor_name,
163 : struct GNUNET_TIME_Timestamp validity_start,
164 : const struct TALER_MasterSignatureP *master_sig)
165 : {
166 : struct TALER_EXCHANGE_PostManagementAuditorsHandle *pmah;
167 :
168 10 : pmah = GNUNET_new (struct TALER_EXCHANGE_PostManagementAuditorsHandle);
169 10 : pmah->ctx = ctx;
170 10 : pmah->base_url = GNUNET_strdup (url);
171 10 : pmah->auditor_pub = *auditor_pub;
172 10 : pmah->auditor_url = GNUNET_strdup (auditor_url);
173 10 : pmah->auditor_name = GNUNET_strdup (auditor_name);
174 10 : pmah->validity_start = validity_start;
175 10 : pmah->master_sig = *master_sig;
176 10 : return pmah;
177 : }
178 :
179 :
180 : enum TALER_ErrorCode
181 10 : TALER_EXCHANGE_post_management_auditors_start (
182 : struct TALER_EXCHANGE_PostManagementAuditorsHandle *pmah,
183 : TALER_EXCHANGE_PostManagementAuditorsCallback cb,
184 : TALER_EXCHANGE_POST_MANAGEMENT_AUDITORS_RESULT_CLOSURE *cb_cls)
185 : {
186 : CURL *eh;
187 : json_t *body;
188 :
189 10 : pmah->cb = cb;
190 10 : pmah->cb_cls = cb_cls;
191 10 : pmah->url = TALER_url_join (pmah->base_url,
192 : "management/auditors",
193 : NULL);
194 10 : if (NULL == pmah->url)
195 : {
196 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
197 : "Could not construct request URL.\n");
198 0 : return TALER_EC_GENERIC_CONFIGURATION_INVALID;
199 : }
200 10 : body = GNUNET_JSON_PACK (
201 : GNUNET_JSON_pack_string ("auditor_url",
202 : pmah->auditor_url),
203 : GNUNET_JSON_pack_string ("auditor_name",
204 : pmah->auditor_name),
205 : GNUNET_JSON_pack_data_auto ("auditor_pub",
206 : &pmah->auditor_pub),
207 : GNUNET_JSON_pack_data_auto ("master_sig",
208 : &pmah->master_sig),
209 : GNUNET_JSON_pack_timestamp ("validity_start",
210 : pmah->validity_start));
211 10 : eh = TALER_EXCHANGE_curl_easy_get_ (pmah->url);
212 20 : if ( (NULL == eh) ||
213 : (GNUNET_OK !=
214 10 : TALER_curl_easy_post (&pmah->post_ctx,
215 : eh,
216 : body)) )
217 : {
218 0 : GNUNET_break (0);
219 0 : if (NULL != eh)
220 0 : curl_easy_cleanup (eh);
221 0 : json_decref (body);
222 0 : GNUNET_free (pmah->url);
223 0 : pmah->url = NULL;
224 0 : return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
225 : }
226 10 : json_decref (body);
227 10 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
228 : "Requesting URL '%s'\n",
229 : pmah->url);
230 20 : pmah->job = GNUNET_CURL_job_add2 (pmah->ctx,
231 : eh,
232 10 : pmah->post_ctx.headers,
233 : &handle_auditors_finished,
234 : pmah);
235 10 : if (NULL == pmah->job)
236 : {
237 0 : TALER_curl_easy_post_finished (&pmah->post_ctx);
238 0 : GNUNET_free (pmah->url);
239 0 : pmah->url = NULL;
240 0 : return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
241 : }
242 10 : return TALER_EC_NONE;
243 : }
244 :
245 :
246 : void
247 10 : TALER_EXCHANGE_post_management_auditors_cancel (
248 : struct TALER_EXCHANGE_PostManagementAuditorsHandle *pmah)
249 : {
250 10 : if (NULL != pmah->job)
251 : {
252 0 : GNUNET_CURL_job_cancel (pmah->job);
253 0 : pmah->job = NULL;
254 : }
255 10 : TALER_curl_easy_post_finished (&pmah->post_ctx);
256 10 : GNUNET_free (pmah->auditor_url);
257 10 : GNUNET_free (pmah->auditor_name);
258 10 : GNUNET_free (pmah->url);
259 10 : GNUNET_free (pmah->base_url);
260 10 : GNUNET_free (pmah);
261 10 : }
262 :
263 :
264 : /* end of exchange_api_post-management-auditors.c */
|