exchange_api_post-management-auditors.c (7269B)
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-auditors.c 19 * @brief functions to enable an auditor 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-auditors.h" 26 #include "exchange_api_curl_defaults.h" 27 #include "taler/taler_curl_lib.h" 28 29 30 /** 31 * @brief Handle for a POST /management/auditors request. 32 */ 33 struct TALER_EXCHANGE_PostManagementAuditorsHandle 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_PostManagementAuditorsCallback cb; 60 61 /** 62 * Closure for @a cb. 63 */ 64 TALER_EXCHANGE_POST_MANAGEMENT_AUDITORS_RESULT_CLOSURE *cb_cls; 65 66 /** 67 * Reference to the execution context. 68 */ 69 struct GNUNET_CURL_Context *ctx; 70 71 /** 72 * Public signing key of the auditor. 73 */ 74 struct TALER_AuditorPublicKeyP auditor_pub; 75 76 /** 77 * Base URL of the auditor. 78 */ 79 char *auditor_url; 80 81 /** 82 * Human-readable name of the auditor. 83 */ 84 char *auditor_name; 85 86 /** 87 * When was this decided? 88 */ 89 struct GNUNET_TIME_Timestamp validity_start; 90 91 /** 92 * Signature affirming the auditor addition. 93 */ 94 struct TALER_MasterSignatureP master_sig; 95 96 }; 97 98 99 /** 100 * Function called when we're done processing the 101 * HTTP POST /management/auditors request. 102 * 103 * @param cls the `struct TALER_EXCHANGE_PostManagementAuditorsHandle` 104 * @param response_code HTTP response code, 0 on error 105 * @param response response body, NULL if not in JSON 106 */ 107 static void 108 handle_auditors_finished (void *cls, 109 long response_code, 110 const void *response) 111 { 112 struct TALER_EXCHANGE_PostManagementAuditorsHandle *pmah = cls; 113 const json_t *json = response; 114 struct TALER_EXCHANGE_PostManagementAuditorsResponse res = { 115 .hr.http_status = (unsigned int) response_code, 116 .hr.reply = json 117 }; 118 119 pmah->job = NULL; 120 switch (response_code) 121 { 122 case MHD_HTTP_NO_CONTENT: 123 break; 124 case MHD_HTTP_FORBIDDEN: 125 res.hr.ec = TALER_JSON_get_error_code (json); 126 res.hr.hint = TALER_JSON_get_error_hint (json); 127 break; 128 case MHD_HTTP_CONFLICT: 129 res.hr.ec = TALER_JSON_get_error_code (json); 130 res.hr.hint = TALER_JSON_get_error_hint (json); 131 break; 132 default: 133 /* unexpected response code */ 134 GNUNET_break_op (0); 135 res.hr.ec = TALER_JSON_get_error_code (json); 136 res.hr.hint = TALER_JSON_get_error_hint (json); 137 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 138 "Unexpected response code %u/%d for exchange management auditor enable\n", 139 (unsigned int) response_code, 140 (int) res.hr.ec); 141 break; 142 } 143 if (NULL != pmah->cb) 144 { 145 pmah->cb (pmah->cb_cls, 146 &res); 147 pmah->cb = NULL; 148 } 149 TALER_EXCHANGE_post_management_auditors_cancel (pmah); 150 } 151 152 153 struct TALER_EXCHANGE_PostManagementAuditorsHandle * 154 TALER_EXCHANGE_post_management_auditors_create ( 155 struct GNUNET_CURL_Context *ctx, 156 const char *url, 157 const struct TALER_AuditorPublicKeyP *auditor_pub, 158 const char *auditor_url, 159 const char *auditor_name, 160 struct GNUNET_TIME_Timestamp validity_start, 161 const struct TALER_MasterSignatureP *master_sig) 162 { 163 struct TALER_EXCHANGE_PostManagementAuditorsHandle *pmah; 164 165 pmah = GNUNET_new (struct TALER_EXCHANGE_PostManagementAuditorsHandle); 166 pmah->ctx = ctx; 167 pmah->base_url = GNUNET_strdup (url); 168 pmah->auditor_pub = *auditor_pub; 169 pmah->auditor_url = GNUNET_strdup (auditor_url); 170 pmah->auditor_name = GNUNET_strdup (auditor_name); 171 pmah->validity_start = validity_start; 172 pmah->master_sig = *master_sig; 173 return pmah; 174 } 175 176 177 enum TALER_ErrorCode 178 TALER_EXCHANGE_post_management_auditors_start ( 179 struct TALER_EXCHANGE_PostManagementAuditorsHandle *pmah, 180 TALER_EXCHANGE_PostManagementAuditorsCallback cb, 181 TALER_EXCHANGE_POST_MANAGEMENT_AUDITORS_RESULT_CLOSURE *cb_cls) 182 { 183 CURL *eh; 184 json_t *body; 185 186 pmah->cb = cb; 187 pmah->cb_cls = cb_cls; 188 pmah->url = TALER_url_join (pmah->base_url, 189 "management/auditors", 190 NULL); 191 if (NULL == pmah->url) 192 { 193 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 194 "Could not construct request URL.\n"); 195 return TALER_EC_GENERIC_CONFIGURATION_INVALID; 196 } 197 body = GNUNET_JSON_PACK ( 198 GNUNET_JSON_pack_string ("auditor_url", 199 pmah->auditor_url), 200 GNUNET_JSON_pack_string ("auditor_name", 201 pmah->auditor_name), 202 GNUNET_JSON_pack_data_auto ("auditor_pub", 203 &pmah->auditor_pub), 204 GNUNET_JSON_pack_data_auto ("master_sig", 205 &pmah->master_sig), 206 GNUNET_JSON_pack_timestamp ("validity_start", 207 pmah->validity_start)); 208 eh = TALER_EXCHANGE_curl_easy_get_ (pmah->url); 209 if ( (NULL == eh) || 210 (GNUNET_OK != 211 TALER_curl_easy_post (&pmah->post_ctx, 212 eh, 213 body)) ) 214 { 215 GNUNET_break (0); 216 if (NULL != eh) 217 curl_easy_cleanup (eh); 218 json_decref (body); 219 GNUNET_free (pmah->url); 220 pmah->url = NULL; 221 return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; 222 } 223 json_decref (body); 224 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 225 "Requesting URL '%s'\n", 226 pmah->url); 227 pmah->job = GNUNET_CURL_job_add2 (pmah->ctx, 228 eh, 229 pmah->post_ctx.headers, 230 &handle_auditors_finished, 231 pmah); 232 if (NULL == pmah->job) 233 { 234 TALER_curl_easy_post_finished (&pmah->post_ctx); 235 GNUNET_free (pmah->url); 236 pmah->url = NULL; 237 return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; 238 } 239 return TALER_EC_NONE; 240 } 241 242 243 void 244 TALER_EXCHANGE_post_management_auditors_cancel ( 245 struct TALER_EXCHANGE_PostManagementAuditorsHandle *pmah) 246 { 247 if (NULL != pmah->job) 248 { 249 GNUNET_CURL_job_cancel (pmah->job); 250 pmah->job = NULL; 251 } 252 TALER_curl_easy_post_finished (&pmah->post_ctx); 253 GNUNET_free (pmah->auditor_url); 254 GNUNET_free (pmah->auditor_name); 255 GNUNET_free (pmah->url); 256 GNUNET_free (pmah->base_url); 257 GNUNET_free (pmah); 258 } 259 260 261 /* end of exchange_api_post-management-auditors.c */