Line data Source code
1 : /* 2 : This file is part of TALER 3 : Copyright (C) 2015-2023 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_management_post_extensions.c 19 : * @brief functions to handle the settings for extensions (p2p and age restriction) 20 : * @author Özgür Kesim 21 : */ 22 : #include "platform.h" 23 : #include "taler_json_lib.h" 24 : #include <gnunet/gnunet_curl_lib.h> 25 : #include "taler_extensions.h" 26 : #include "exchange_api_curl_defaults.h" 27 : #include "taler_exchange_service.h" 28 : #include "taler_signatures.h" 29 : #include "taler_curl_lib.h" 30 : #include "taler_json_lib.h" 31 : 32 : 33 : /** 34 : * @brief Handle for a POST /management/extensions request. 35 : */ 36 : struct TALER_EXCHANGE_ManagementPostExtensionsHandle 37 : { 38 : 39 : /** 40 : * The url for this request. 41 : */ 42 : char *url; 43 : 44 : /** 45 : * Minor context that holds body and headers. 46 : */ 47 : struct TALER_CURL_PostContext post_ctx; 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_EXCHANGE_ManagementPostExtensionsCallback cb; 58 : 59 : /** 60 : * Closure for @a cb. 61 : */ 62 : void *cb_cls; 63 : 64 : /** 65 : * Reference to the execution context. 66 : */ 67 : struct GNUNET_CURL_Context *ctx; 68 : }; 69 : 70 : 71 : /** 72 : * Function called when we're done processing the 73 : * HTTP POST /management/extensions request. 74 : * 75 : * @param cls the `struct TALER_EXCHANGE_ManagementPostExtensionsHandle *` 76 : * @param response_code HTTP response code, 0 on error 77 : * @param response response body, NULL if not in JSON 78 : */ 79 : static void 80 0 : handle_post_extensions_finished (void *cls, 81 : long response_code, 82 : const void *response) 83 : { 84 0 : struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph = cls; 85 0 : const json_t *json = response; 86 0 : struct TALER_EXCHANGE_ManagementPostExtensionsResponse per = { 87 0 : .hr.http_status = (unsigned int) response_code, 88 : .hr.reply = json 89 : }; 90 : 91 0 : ph->job = NULL; 92 0 : switch (response_code) 93 : { 94 0 : case MHD_HTTP_NO_CONTENT: 95 0 : break; 96 0 : case MHD_HTTP_FORBIDDEN: 97 0 : per.hr.ec = TALER_JSON_get_error_code (json); 98 0 : per.hr.hint = TALER_JSON_get_error_hint (json); 99 0 : break; 100 0 : case MHD_HTTP_NOT_FOUND: 101 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 102 : "Server did not find handler at `%s'. Did you configure the correct exchange base URL?\n", 103 : ph->url); 104 0 : if (NULL != json) 105 : { 106 0 : per.hr.ec = TALER_JSON_get_error_code (json); 107 0 : per.hr.hint = TALER_JSON_get_error_hint (json); 108 : } 109 : else 110 : { 111 0 : per.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; 112 0 : per.hr.hint = TALER_ErrorCode_get_hint (per.hr.ec); 113 : } 114 0 : break; 115 0 : default: 116 : /* unexpected response code */ 117 0 : GNUNET_break_op (0); 118 0 : per.hr.ec = TALER_JSON_get_error_code (json); 119 0 : per.hr.hint = TALER_JSON_get_error_hint (json); 120 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 121 : "Unexpected response code %u/%d for exchange management post extensions\n", 122 : (unsigned int) response_code, 123 : (int) per.hr.ec); 124 0 : break; 125 : } 126 0 : if (NULL != ph->cb) 127 : { 128 0 : ph->cb (ph->cb_cls, 129 : &per); 130 0 : ph->cb = NULL; 131 : } 132 0 : TALER_EXCHANGE_management_post_extensions_cancel (ph); 133 0 : } 134 : 135 : 136 : struct TALER_EXCHANGE_ManagementPostExtensionsHandle * 137 0 : TALER_EXCHANGE_management_post_extensions ( 138 : struct GNUNET_CURL_Context *ctx, 139 : const char *url, 140 : const struct TALER_EXCHANGE_ManagementPostExtensionsData *ped, 141 : TALER_EXCHANGE_ManagementPostExtensionsCallback cb, 142 : void *cb_cls) 143 : { 144 : struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph; 145 0 : CURL *eh = NULL; 146 0 : json_t *body = NULL; 147 : 148 0 : ph = GNUNET_new (struct TALER_EXCHANGE_ManagementPostExtensionsHandle); 149 0 : ph->cb = cb; 150 0 : ph->cb_cls = cb_cls; 151 0 : ph->ctx = ctx; 152 0 : ph->url = TALER_url_join (url, 153 : "management/extensions", 154 : NULL); 155 0 : if (NULL == ph->url) 156 : { 157 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 158 : "Could not construct request URL.\n"); 159 0 : GNUNET_free (ph); 160 0 : return NULL; 161 : } 162 : 163 0 : body = GNUNET_JSON_PACK ( 164 : GNUNET_JSON_pack_object_steal ("extensions", 165 : (json_t *) ped->extensions), 166 : GNUNET_JSON_pack_data_auto ("extensions_sig", 167 : &ped->extensions_sig)); 168 : 169 0 : eh = TALER_EXCHANGE_curl_easy_get_ (ph->url); 170 0 : if ( (NULL == eh) || 171 : (GNUNET_OK != 172 0 : TALER_curl_easy_post (&ph->post_ctx, 173 : eh, 174 : body)) ) 175 : { 176 0 : GNUNET_break (0); 177 0 : if (NULL != eh) 178 0 : curl_easy_cleanup (eh); 179 0 : json_decref (body); 180 0 : GNUNET_free (ph->url); 181 0 : return NULL; 182 : } 183 0 : json_decref (body); 184 0 : GNUNET_log (GNUNET_ERROR_TYPE_INFO, 185 : "Requesting URL '%s'\n", 186 : ph->url); 187 0 : ph->job = GNUNET_CURL_job_add2 (ctx, 188 : eh, 189 0 : ph->post_ctx.headers, 190 : &handle_post_extensions_finished, 191 : ph); 192 0 : if (NULL == ph->job) 193 : { 194 0 : TALER_EXCHANGE_management_post_extensions_cancel (ph); 195 0 : return NULL; 196 : } 197 0 : return ph; 198 : } 199 : 200 : 201 : void 202 0 : TALER_EXCHANGE_management_post_extensions_cancel ( 203 : struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph) 204 : { 205 0 : if (NULL != ph->job) 206 : { 207 0 : GNUNET_CURL_job_cancel (ph->job); 208 0 : ph->job = NULL; 209 : } 210 0 : TALER_curl_easy_post_finished (&ph->post_ctx); 211 0 : GNUNET_free (ph->url); 212 0 : GNUNET_free (ph); 213 0 : }