Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2014-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 Lesser General Public License as published by the Free Software
7 : Foundation; either version 2.1, 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 Lesser General Public License for more details.
12 :
13 : You should have received a copy of the GNU Lesser General Public License along with
14 : TALER; see the file COPYING.LGPL. If not, see
15 : <http://www.gnu.org/licenses/>
16 : */
17 : /**
18 : * @file merchant_api_delete-management-instances-INSTANCE-new.c
19 : * @brief Implementation of the DELETE /management/instances/$INSTANCE request
20 : * @author Christian Grothoff
21 : */
22 : #include "taler/platform.h"
23 : #include <curl/curl.h>
24 : #include <jansson.h>
25 : #include <microhttpd.h> /* just for HTTP status codes */
26 : #include <gnunet/gnunet_util_lib.h>
27 : #include <gnunet/gnunet_curl_lib.h>
28 : #include <taler/merchant/delete-management-instances-INSTANCE.h>
29 : #include "merchant_api_curl_defaults.h"
30 : #include <taler/taler_json_lib.h>
31 : #include "merchant_api_common.h"
32 :
33 :
34 : /**
35 : * Handle for a DELETE /management/instances/$INSTANCE operation.
36 : */
37 : struct TALER_MERCHANT_DeleteManagementInstanceHandle
38 : {
39 : /**
40 : * Base URL of the merchant backend.
41 : */
42 : char *base_url;
43 :
44 : /**
45 : * The full URL for this request.
46 : */
47 : char *url;
48 :
49 : /**
50 : * Handle for the request.
51 : */
52 : struct GNUNET_CURL_Job *job;
53 :
54 : /**
55 : * Function to call with the result.
56 : */
57 : TALER_MERCHANT_DeleteManagementInstanceCallback cb;
58 :
59 : /**
60 : * Closure for @a cb.
61 : */
62 : TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cb_cls;
63 :
64 : /**
65 : * Reference to the execution context.
66 : */
67 : struct GNUNET_CURL_Context *ctx;
68 :
69 : /**
70 : * Identifier of the instance to delete.
71 : */
72 : char *instance_id;
73 :
74 : /**
75 : * Whether to purge (hard delete) the instance.
76 : */
77 : bool purge;
78 : };
79 :
80 :
81 : /**
82 : * Function called when we're done processing the
83 : * HTTP DELETE /management/instances/$INSTANCE request.
84 : *
85 : * @param cls the `struct TALER_MERCHANT_DeleteManagementInstanceHandle`
86 : * @param response_code HTTP response code, 0 on error
87 : * @param response response body, NULL if not in JSON
88 : */
89 : static void
90 0 : handle_delete_instance_finished (void *cls,
91 : long response_code,
92 : const void *response)
93 : {
94 0 : struct TALER_MERCHANT_DeleteManagementInstanceHandle *dih = cls;
95 0 : const json_t *json = response;
96 0 : struct TALER_MERCHANT_DeleteManagementInstanceResponse dir = {
97 0 : .hr.http_status = (unsigned int) response_code,
98 : .hr.reply = json
99 : };
100 :
101 0 : dih->job = NULL;
102 0 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
103 : "Got /management/instances/$INSTANCE DELETE response with status code %u\n",
104 : (unsigned int) response_code);
105 0 : switch (response_code)
106 : {
107 0 : case MHD_HTTP_NO_CONTENT:
108 0 : break;
109 0 : case MHD_HTTP_ACCEPTED:
110 0 : if (GNUNET_OK !=
111 0 : TALER_MERCHANT_parse_mfa_challenge_response_ (
112 : json,
113 : &dir.details.accepted))
114 : {
115 0 : GNUNET_break_op (0);
116 0 : dir.hr.http_status = 0;
117 0 : dir.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
118 : }
119 0 : break;
120 0 : case MHD_HTTP_UNAUTHORIZED:
121 0 : dir.hr.ec = TALER_JSON_get_error_code (json);
122 0 : dir.hr.hint = TALER_JSON_get_error_hint (json);
123 0 : break;
124 0 : case MHD_HTTP_NOT_FOUND:
125 0 : dir.hr.ec = TALER_JSON_get_error_code (json);
126 0 : dir.hr.hint = TALER_JSON_get_error_hint (json);
127 0 : break;
128 0 : case MHD_HTTP_CONFLICT:
129 0 : dir.hr.ec = TALER_JSON_get_error_code (json);
130 0 : dir.hr.hint = TALER_JSON_get_error_hint (json);
131 0 : break;
132 0 : default:
133 0 : dir.hr.ec = TALER_JSON_get_error_code (json);
134 0 : dir.hr.hint = TALER_JSON_get_error_hint (json);
135 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
136 : "Unexpected response code %u/%d for DELETE /management/instances/$INSTANCE\n",
137 : (unsigned int) response_code,
138 : (int) dir.hr.ec);
139 0 : break;
140 : }
141 0 : dih->cb (dih->cb_cls,
142 : &dir);
143 0 : if (MHD_HTTP_ACCEPTED == response_code)
144 0 : TALER_MERCHANT_mfa_challenge_response_free (
145 : &dir.details.accepted);
146 0 : TALER_MERCHANT_delete_management_instance_cancel (dih);
147 0 : }
148 :
149 :
150 : struct TALER_MERCHANT_DeleteManagementInstanceHandle *
151 0 : TALER_MERCHANT_delete_management_instance_create (
152 : struct GNUNET_CURL_Context *ctx,
153 : const char *url,
154 : const char *instance_id)
155 : {
156 : struct TALER_MERCHANT_DeleteManagementInstanceHandle *dih;
157 :
158 0 : dih = GNUNET_new (struct TALER_MERCHANT_DeleteManagementInstanceHandle);
159 0 : dih->ctx = ctx;
160 0 : dih->base_url = GNUNET_strdup (url);
161 0 : if (NULL != instance_id)
162 0 : dih->instance_id = GNUNET_strdup (instance_id);
163 0 : return dih;
164 : }
165 :
166 :
167 : void
168 0 : TALER_MERCHANT_delete_management_instance_set_options_ (
169 : struct TALER_MERCHANT_DeleteManagementInstanceHandle *handle,
170 : unsigned int num_options,
171 : const struct TALER_MERCHANT_DeleteManagementInstanceOptionValue options[])
172 : {
173 0 : for (unsigned int i = 0; i < num_options; i++)
174 : {
175 0 : switch (options[i].option)
176 : {
177 0 : case TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTION_END:
178 0 : return;
179 0 : case TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTION_PURGE:
180 0 : handle->purge = true;
181 0 : break;
182 : }
183 : }
184 : }
185 :
186 :
187 : enum TALER_ErrorCode
188 0 : TALER_MERCHANT_delete_management_instance_start (
189 : struct TALER_MERCHANT_DeleteManagementInstanceHandle *dih,
190 : TALER_MERCHANT_DeleteManagementInstanceCallback cb,
191 : TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cb_cls)
192 : {
193 : CURL *eh;
194 :
195 0 : dih->cb = cb;
196 0 : dih->cb_cls = cb_cls;
197 0 : if (NULL != dih->instance_id)
198 : {
199 : char *path;
200 :
201 0 : GNUNET_asprintf (&path,
202 : "management/instances/%s",
203 : dih->instance_id);
204 0 : dih->url = TALER_url_join (dih->base_url,
205 : path,
206 : "purge",
207 0 : (dih->purge) ? "yes" : NULL,
208 : NULL);
209 0 : GNUNET_free (path);
210 : }
211 : else
212 : {
213 : /* backend_url is already identifying the instance */
214 0 : dih->url = TALER_url_join (dih->base_url,
215 : "private",
216 : "purge",
217 0 : (dih->purge) ? "yes" : NULL,
218 : NULL);
219 : }
220 0 : if (NULL == dih->url)
221 0 : return TALER_EC_GENERIC_CONFIGURATION_INVALID;
222 0 : eh = TALER_MERCHANT_curl_easy_get_ (dih->url);
223 0 : if (NULL == eh)
224 0 : return TALER_EC_GENERIC_CONFIGURATION_INVALID;
225 0 : GNUNET_assert (CURLE_OK ==
226 : curl_easy_setopt (eh,
227 : CURLOPT_CUSTOMREQUEST,
228 : MHD_HTTP_METHOD_DELETE));
229 0 : dih->job = GNUNET_CURL_job_add (dih->ctx,
230 : eh,
231 : &handle_delete_instance_finished,
232 : dih);
233 0 : if (NULL == dih->job)
234 0 : return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
235 0 : return TALER_EC_NONE;
236 : }
237 :
238 :
239 : void
240 0 : TALER_MERCHANT_delete_management_instance_cancel (
241 : struct TALER_MERCHANT_DeleteManagementInstanceHandle *dih)
242 : {
243 0 : if (NULL != dih->job)
244 : {
245 0 : GNUNET_CURL_job_cancel (dih->job);
246 0 : dih->job = NULL;
247 : }
248 0 : GNUNET_free (dih->url);
249 0 : GNUNET_free (dih->instance_id);
250 0 : GNUNET_free (dih->base_url);
251 0 : GNUNET_free (dih);
252 0 : }
253 :
254 :
255 : /* end of merchant_api_delete-management-instances-INSTANCE-new.c */
|