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