merchant_api_delete_instance.c (7045B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2014-2018, 2020 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_instance.c 19 * @brief Implementation of the DELETE /instance/$ID request of the merchant's HTTP API 20 * @author Christian Grothoff 21 */ 22 #include "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_service.h" 29 #include "merchant_api_curl_defaults.h" 30 #include <taler/taler_json_lib.h> 31 #include <taler/taler_signatures.h> 32 33 34 /** 35 * Handle for a DELETE /instances/$ID operation. 36 */ 37 struct TALER_MERCHANT_InstanceDeleteHandle 38 { 39 /** 40 * The url for this request. 41 */ 42 char *url; 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_MERCHANT_InstanceDeleteCallback cb; 53 54 /** 55 * Closure for @a cb. 56 */ 57 void *cb_cls; 58 59 /** 60 * Reference to the execution context. 61 */ 62 struct GNUNET_CURL_Context *ctx; 63 64 }; 65 66 67 /** 68 * Function called when we're done processing the 69 * HTTP GET /instances/$ID request. 70 * 71 * @param cls the `struct TALER_MERCHANT_InstanceDeleteHandle` 72 * @param response_code HTTP response code, 0 on error 73 * @param response response body, NULL if not in JSON 74 */ 75 static void 76 handle_delete_instance_finished (void *cls, 77 long response_code, 78 const void *response) 79 { 80 struct TALER_MERCHANT_InstanceDeleteHandle *idh = cls; 81 const json_t *json = response; 82 struct TALER_MERCHANT_HttpResponse hr = { 83 .http_status = (unsigned int) response_code, 84 .reply = json 85 }; 86 87 idh->job = NULL; 88 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 89 "Got /instances/$ID response with status code %u\n", 90 (unsigned int) response_code); 91 switch (response_code) 92 { 93 case MHD_HTTP_NO_CONTENT: 94 break; 95 case MHD_HTTP_UNAUTHORIZED: 96 hr.ec = TALER_JSON_get_error_code (json); 97 hr.hint = TALER_JSON_get_error_hint (json); 98 /* Nothing really to verify, merchant says we need to authenticate. */ 99 break; 100 case MHD_HTTP_NOT_FOUND: 101 break; 102 default: 103 /* unexpected response code */ 104 hr.ec = TALER_JSON_get_error_code (json); 105 hr.hint = TALER_JSON_get_error_hint (json); 106 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 107 "Unexpected response code %u/%d for DELETE /instance/ID\n", 108 (unsigned int) response_code, 109 (int) hr.ec); 110 break; 111 } 112 idh->cb (idh->cb_cls, 113 &hr); 114 TALER_MERCHANT_instance_delete_cancel (idh); 115 } 116 117 118 /** 119 * Delete the private key of an instance of a backend, thereby disabling the 120 * instance for future requests. Will preserve the other instance data 121 * (i.e. for taxation). 122 * 123 * @param ctx the context 124 * @param backend_url HTTP base URL for the backend 125 * @param instance_id which instance should be deleted 126 * @param purge purge instead of just deleting 127 * @param cb function to call with the 128 * backend's return 129 * @param cb_cls closure for @a config_cb 130 * @return the instances handle; NULL upon error 131 */ 132 static struct TALER_MERCHANT_InstanceDeleteHandle * 133 instance_delete (struct GNUNET_CURL_Context *ctx, 134 const char *backend_url, 135 const char *instance_id, 136 bool purge, 137 TALER_MERCHANT_InstanceDeleteCallback cb, 138 void *cb_cls) 139 { 140 struct TALER_MERCHANT_InstanceDeleteHandle *idh; 141 142 idh = GNUNET_new (struct TALER_MERCHANT_InstanceDeleteHandle); 143 idh->ctx = ctx; 144 idh->cb = cb; 145 idh->cb_cls = cb_cls; 146 if (NULL != instance_id) 147 { 148 char *path; 149 150 GNUNET_asprintf (&path, 151 "management/instances/%s", 152 instance_id); 153 idh->url = TALER_url_join (backend_url, 154 path, 155 "purge", 156 (purge) ? "yes" : NULL, 157 NULL); 158 GNUNET_free (path); 159 } 160 else 161 { 162 /* backend_url is already identifying the instance */ 163 idh->url = TALER_url_join (backend_url, 164 "private", 165 "purge", 166 (purge) ? "yes" : NULL, 167 NULL); 168 } 169 if (NULL == idh->url) 170 { 171 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 172 "Could not construct request URL.\n"); 173 GNUNET_free (idh); 174 return NULL; 175 } 176 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 177 "Requesting URL '%s'\n", 178 idh->url); 179 { 180 CURL *eh; 181 182 eh = TALER_MERCHANT_curl_easy_get_ (idh->url); 183 GNUNET_assert (CURLE_OK == 184 curl_easy_setopt (eh, 185 CURLOPT_CUSTOMREQUEST, 186 MHD_HTTP_METHOD_DELETE)); 187 idh->job = GNUNET_CURL_job_add (ctx, 188 eh, 189 &handle_delete_instance_finished, 190 idh); 191 } 192 return idh; 193 } 194 195 196 struct TALER_MERCHANT_InstanceDeleteHandle * 197 TALER_MERCHANT_instance_delete (struct GNUNET_CURL_Context *ctx, 198 const char *backend_url, 199 const char *instance_id, 200 TALER_MERCHANT_InstanceDeleteCallback cb, 201 void *cb_cls) 202 { 203 return instance_delete (ctx, 204 backend_url, 205 instance_id, 206 false, 207 cb, 208 cb_cls); 209 } 210 211 212 struct TALER_MERCHANT_InstanceDeleteHandle * 213 TALER_MERCHANT_instance_purge (struct GNUNET_CURL_Context *ctx, 214 const char *backend_url, 215 const char *instance_id, 216 TALER_MERCHANT_InstanceDeleteCallback cb, 217 void *cb_cls) 218 { 219 return instance_delete (ctx, 220 backend_url, 221 instance_id, 222 true, 223 cb, 224 cb_cls); 225 } 226 227 228 void 229 TALER_MERCHANT_instance_delete_cancel ( 230 struct TALER_MERCHANT_InstanceDeleteHandle *idh) 231 { 232 if (NULL != idh->job) 233 GNUNET_CURL_job_cancel (idh->job); 234 GNUNET_free (idh->url); 235 GNUNET_free (idh); 236 }