merchant_api_delete-management-instances-INSTANCE.c (7424B)
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/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 handle_delete_instance_finished (void *cls, 91 long response_code, 92 const void *response) 93 { 94 struct TALER_MERCHANT_DeleteManagementInstanceHandle *dih = cls; 95 const json_t *json = response; 96 struct TALER_MERCHANT_DeleteManagementInstanceResponse dir = { 97 .hr.http_status = (unsigned int) response_code, 98 .hr.reply = json 99 }; 100 101 dih->job = NULL; 102 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 103 "Got /management/instances/$INSTANCE DELETE response with status code %u\n", 104 (unsigned int) response_code); 105 switch (response_code) 106 { 107 case MHD_HTTP_NO_CONTENT: 108 break; 109 case MHD_HTTP_ACCEPTED: 110 if (GNUNET_OK != 111 TALER_MERCHANT_parse_mfa_challenge_response_ ( 112 json, 113 &dir.details.accepted)) 114 { 115 GNUNET_break_op (0); 116 dir.hr.http_status = 0; 117 dir.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; 118 } 119 break; 120 case MHD_HTTP_UNAUTHORIZED: 121 dir.hr.ec = TALER_JSON_get_error_code (json); 122 dir.hr.hint = TALER_JSON_get_error_hint (json); 123 break; 124 case MHD_HTTP_NOT_FOUND: 125 dir.hr.ec = TALER_JSON_get_error_code (json); 126 dir.hr.hint = TALER_JSON_get_error_hint (json); 127 break; 128 case MHD_HTTP_CONFLICT: 129 dir.hr.ec = TALER_JSON_get_error_code (json); 130 dir.hr.hint = TALER_JSON_get_error_hint (json); 131 break; 132 default: 133 dir.hr.ec = TALER_JSON_get_error_code (json); 134 dir.hr.hint = TALER_JSON_get_error_hint (json); 135 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 break; 140 } 141 dih->cb (dih->cb_cls, 142 &dir); 143 if (MHD_HTTP_ACCEPTED == response_code) 144 TALER_MERCHANT_mfa_challenge_response_free ( 145 &dir.details.accepted); 146 TALER_MERCHANT_delete_management_instance_cancel (dih); 147 } 148 149 150 struct TALER_MERCHANT_DeleteManagementInstanceHandle * 151 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 dih = GNUNET_new (struct TALER_MERCHANT_DeleteManagementInstanceHandle); 159 dih->ctx = ctx; 160 dih->base_url = GNUNET_strdup (url); 161 if (NULL != instance_id) 162 dih->instance_id = GNUNET_strdup (instance_id); 163 return dih; 164 } 165 166 167 void 168 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 for (unsigned int i = 0; i < num_options; i++) 174 { 175 switch (options[i].option) 176 { 177 case TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTION_END: 178 return; 179 case TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTION_PURGE: 180 handle->purge = true; 181 break; 182 } 183 } 184 } 185 186 187 enum TALER_ErrorCode 188 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 dih->cb = cb; 196 dih->cb_cls = cb_cls; 197 if (NULL != dih->instance_id) 198 { 199 char *path; 200 201 GNUNET_asprintf (&path, 202 "management/instances/%s", 203 dih->instance_id); 204 dih->url = TALER_url_join (dih->base_url, 205 path, 206 "purge", 207 (dih->purge) ? "yes" : NULL, 208 NULL); 209 GNUNET_free (path); 210 } 211 else 212 { 213 /* backend_url is already identifying the instance */ 214 dih->url = TALER_url_join (dih->base_url, 215 "private", 216 "purge", 217 (dih->purge) ? "yes" : NULL, 218 NULL); 219 } 220 if (NULL == dih->url) 221 return TALER_EC_GENERIC_CONFIGURATION_INVALID; 222 eh = TALER_MERCHANT_curl_easy_get_ (dih->url); 223 if (NULL == eh) 224 return TALER_EC_GENERIC_CONFIGURATION_INVALID; 225 GNUNET_assert (CURLE_OK == 226 curl_easy_setopt (eh, 227 CURLOPT_CUSTOMREQUEST, 228 MHD_HTTP_METHOD_DELETE)); 229 dih->job = GNUNET_CURL_job_add (dih->ctx, 230 eh, 231 &handle_delete_instance_finished, 232 dih); 233 if (NULL == dih->job) 234 return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; 235 return TALER_EC_NONE; 236 } 237 238 239 void 240 TALER_MERCHANT_delete_management_instance_cancel ( 241 struct TALER_MERCHANT_DeleteManagementInstanceHandle *dih) 242 { 243 if (NULL != dih->job) 244 { 245 GNUNET_CURL_job_cancel (dih->job); 246 dih->job = NULL; 247 } 248 GNUNET_free (dih->url); 249 GNUNET_free (dih->instance_id); 250 GNUNET_free (dih->base_url); 251 GNUNET_free (dih); 252 } 253 254 255 /* end of merchant_api_delete-management-instances-INSTANCE-new.c */