exchange_api_post-management-wire-disable.c (7659B)
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-wire-disable.c 19 * @brief functions to disable an exchange wire method / bank account 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-wire-disable.h" 28 #include "exchange_api_curl_defaults.h" 29 #include "taler/taler_signatures.h" 30 #include "taler/taler_curl_lib.h" 31 32 33 struct TALER_EXCHANGE_PostManagementWireDisableHandle 34 { 35 36 /** 37 * The base URL for this request. 38 */ 39 char *base_url; 40 41 /** 42 * The full URL for this request, set during _start. 43 */ 44 char *url; 45 46 /** 47 * Minor context that holds body and headers. 48 */ 49 struct TALER_CURL_PostContext post_ctx; 50 51 /** 52 * Handle for the request. 53 */ 54 struct GNUNET_CURL_Job *job; 55 56 /** 57 * Function to call with the result. 58 */ 59 TALER_EXCHANGE_PostManagementWireDisableCallback cb; 60 61 /** 62 * Closure for @a cb. 63 */ 64 TALER_EXCHANGE_POST_MANAGEMENT_WIRE_DISABLE_RESULT_CLOSURE *cb_cls; 65 66 /** 67 * Reference to the execution context. 68 */ 69 struct GNUNET_CURL_Context *ctx; 70 71 /** 72 * Payto URI of the account to disable. 73 */ 74 char *payto_uri_str; 75 76 /** 77 * When was this decided? 78 */ 79 struct GNUNET_TIME_Timestamp validity_end; 80 81 /** 82 * Signature affirming the wire disablement. 83 */ 84 struct TALER_MasterSignatureP master_sig; 85 86 }; 87 88 89 /** 90 * Function called when we're done processing the 91 * HTTP POST /management/wire/disable request. 92 * 93 * @param cls the `struct TALER_EXCHANGE_PostManagementWireDisableHandle` 94 * @param response_code HTTP response code, 0 on error 95 * @param response response body, NULL if not in JSON 96 */ 97 static void 98 handle_wire_disable_finished (void *cls, 99 long response_code, 100 const void *response) 101 { 102 struct TALER_EXCHANGE_PostManagementWireDisableHandle *pmwdh = cls; 103 const json_t *json = response; 104 struct TALER_EXCHANGE_PostManagementWireDisableResponse res = { 105 .hr.http_status = (unsigned int) response_code, 106 .hr.reply = json 107 }; 108 109 pmwdh->job = NULL; 110 switch (response_code) 111 { 112 case 0: 113 /* no reply */ 114 res.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; 115 res.hr.hint = "server offline?"; 116 break; 117 case MHD_HTTP_NO_CONTENT: 118 break; 119 case MHD_HTTP_FORBIDDEN: 120 res.hr.ec = TALER_JSON_get_error_code (json); 121 res.hr.hint = TALER_JSON_get_error_hint (json); 122 break; 123 case MHD_HTTP_NOT_FOUND: 124 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 125 "Server did not find handler at `%s'. Did you configure the correct exchange base URL?\n", 126 pmwdh->url); 127 if (NULL != json) 128 { 129 res.hr.ec = TALER_JSON_get_error_code (json); 130 res.hr.hint = TALER_JSON_get_error_hint (json); 131 } 132 else 133 { 134 res.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; 135 res.hr.hint = TALER_ErrorCode_get_hint (res.hr.ec); 136 } 137 break; 138 case MHD_HTTP_CONFLICT: 139 res.hr.ec = TALER_JSON_get_error_code (json); 140 res.hr.hint = TALER_JSON_get_error_hint (json); 141 break; 142 default: 143 /* unexpected response code */ 144 GNUNET_break_op (0); 145 res.hr.ec = TALER_JSON_get_error_code (json); 146 res.hr.hint = TALER_JSON_get_error_hint (json); 147 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 148 "Unexpected response code %u/%d for exchange management disable wire\n", 149 (unsigned int) response_code, 150 (int) res.hr.ec); 151 break; 152 } 153 if (NULL != pmwdh->cb) 154 { 155 pmwdh->cb (pmwdh->cb_cls, 156 &res); 157 pmwdh->cb = NULL; 158 } 159 TALER_EXCHANGE_post_management_wire_disable_cancel (pmwdh); 160 } 161 162 163 struct TALER_EXCHANGE_PostManagementWireDisableHandle * 164 TALER_EXCHANGE_post_management_wire_disable_create ( 165 struct GNUNET_CURL_Context *ctx, 166 const char *exchange_url, 167 const struct TALER_FullPayto payto_uri, 168 struct GNUNET_TIME_Timestamp validity_end, 169 const struct TALER_MasterSignatureP *master_sig) 170 { 171 struct TALER_EXCHANGE_PostManagementWireDisableHandle *pmwdh; 172 173 pmwdh = GNUNET_new (struct TALER_EXCHANGE_PostManagementWireDisableHandle); 174 pmwdh->ctx = ctx; 175 pmwdh->base_url = GNUNET_strdup (exchange_url); 176 pmwdh->payto_uri_str = GNUNET_strdup (payto_uri.full_payto); 177 pmwdh->validity_end = validity_end; 178 pmwdh->master_sig = *master_sig; 179 return pmwdh; 180 } 181 182 183 enum TALER_ErrorCode 184 TALER_EXCHANGE_post_management_wire_disable_start ( 185 struct TALER_EXCHANGE_PostManagementWireDisableHandle *pmwdh, 186 TALER_EXCHANGE_PostManagementWireDisableCallback cb, 187 TALER_EXCHANGE_POST_MANAGEMENT_WIRE_DISABLE_RESULT_CLOSURE *cb_cls) 188 { 189 CURL *eh; 190 json_t *body; 191 struct TALER_FullPayto payto_uri = { 192 .full_payto = pmwdh->payto_uri_str 193 }; 194 195 pmwdh->cb = cb; 196 pmwdh->cb_cls = cb_cls; 197 pmwdh->url = TALER_url_join (pmwdh->base_url, 198 "management/wire/disable", 199 NULL); 200 if (NULL == pmwdh->url) 201 { 202 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 203 "Could not construct request URL.\n"); 204 return TALER_EC_GENERIC_CONFIGURATION_INVALID; 205 } 206 body = GNUNET_JSON_PACK ( 207 TALER_JSON_pack_full_payto ("payto_uri", 208 payto_uri), 209 GNUNET_JSON_pack_data_auto ("master_sig_del", 210 &pmwdh->master_sig), 211 GNUNET_JSON_pack_timestamp ("validity_end", 212 pmwdh->validity_end)); 213 eh = TALER_EXCHANGE_curl_easy_get_ (pmwdh->url); 214 if ( (NULL == eh) || 215 (GNUNET_OK != 216 TALER_curl_easy_post (&pmwdh->post_ctx, 217 eh, 218 body)) ) 219 { 220 GNUNET_break (0); 221 if (NULL != eh) 222 curl_easy_cleanup (eh); 223 json_decref (body); 224 GNUNET_free (pmwdh->url); 225 pmwdh->url = NULL; 226 return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; 227 } 228 json_decref (body); 229 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 230 "Requesting URL '%s'\n", 231 pmwdh->url); 232 pmwdh->job = GNUNET_CURL_job_add2 (pmwdh->ctx, 233 eh, 234 pmwdh->post_ctx.headers, 235 &handle_wire_disable_finished, 236 pmwdh); 237 if (NULL == pmwdh->job) 238 { 239 TALER_curl_easy_post_finished (&pmwdh->post_ctx); 240 GNUNET_free (pmwdh->url); 241 pmwdh->url = NULL; 242 return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; 243 } 244 return TALER_EC_NONE; 245 } 246 247 248 void 249 TALER_EXCHANGE_post_management_wire_disable_cancel ( 250 struct TALER_EXCHANGE_PostManagementWireDisableHandle *pmwdh) 251 { 252 if (NULL != pmwdh->job) 253 { 254 GNUNET_CURL_job_cancel (pmwdh->job); 255 pmwdh->job = NULL; 256 } 257 TALER_curl_easy_post_finished (&pmwdh->post_ctx); 258 GNUNET_free (pmwdh->payto_uri_str); 259 GNUNET_free (pmwdh->url); 260 GNUNET_free (pmwdh->base_url); 261 GNUNET_free (pmwdh); 262 } 263 264 265 /* end of exchange_api_post-management-wire-disable.c */