Line data Source code
1 : /* 2 : This file is part of TALER 3 : Copyright (C) 2015-2021 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_HttpResponse hr = { 87 0 : .http_status = (unsigned int) response_code, 88 : .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 : hr.ec = TALER_JSON_get_error_code (json); 98 0 : hr.hint = TALER_JSON_get_error_hint (json); 99 0 : break; 100 0 : case MHD_HTTP_NOT_FOUND: 101 0 : hr.ec = TALER_JSON_get_error_code (json); 102 0 : hr.hint = TALER_JSON_get_error_hint (json); 103 0 : break; 104 0 : default: 105 : /* unexpected response code */ 106 0 : GNUNET_break_op (0); 107 0 : hr.ec = TALER_JSON_get_error_code (json); 108 0 : hr.hint = TALER_JSON_get_error_hint (json); 109 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 110 : "Unexpected response code %u/%d for exchange management post extensions\n", 111 : (unsigned int) response_code, 112 : (int) hr.ec); 113 0 : break; 114 : } 115 0 : if (NULL != ph->cb) 116 : { 117 0 : ph->cb (ph->cb_cls, 118 : &hr); 119 0 : ph->cb = NULL; 120 : } 121 0 : TALER_EXCHANGE_management_post_extensions_cancel (ph); 122 0 : } 123 : 124 : 125 : struct TALER_EXCHANGE_ManagementPostExtensionsHandle * 126 0 : TALER_EXCHANGE_management_post_extensions ( 127 : struct GNUNET_CURL_Context *ctx, 128 : const char *url, 129 : struct TALER_EXCHANGE_ManagementPostExtensionsData *ped, 130 : TALER_EXCHANGE_ManagementPostExtensionsCallback cb, 131 : void *cb_cls) 132 : { 133 : struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph; 134 0 : CURL *eh = NULL; 135 0 : json_t *body = NULL; 136 : 137 0 : ph = GNUNET_new (struct TALER_EXCHANGE_ManagementPostExtensionsHandle); 138 0 : ph->cb = cb; 139 0 : ph->cb_cls = cb_cls; 140 0 : ph->ctx = ctx; 141 0 : ph->url = TALER_url_join (url, 142 : "management/extensions", 143 : NULL); 144 0 : if (NULL == ph->url) 145 : { 146 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 147 : "Could not construct request URL.\n"); 148 0 : GNUNET_free (ph); 149 0 : return NULL; 150 : } 151 : 152 0 : body = GNUNET_JSON_PACK ( 153 : GNUNET_JSON_pack_object_steal ("extensions", 154 : ped->extensions), 155 : GNUNET_JSON_pack_data_auto ("extensions_sig", 156 : &ped->extensions_sig)); 157 : 158 0 : eh = TALER_EXCHANGE_curl_easy_get_ (ph->url); 159 0 : if ( (NULL == eh) || 160 : (GNUNET_OK != 161 0 : TALER_curl_easy_post (&ph->post_ctx, 162 : eh, 163 : body)) ) 164 : { 165 0 : GNUNET_break (0); 166 0 : if (NULL != eh) 167 0 : curl_easy_cleanup (eh); 168 0 : json_decref (body); 169 0 : GNUNET_free (ph->url); 170 0 : return NULL; 171 : } 172 0 : json_decref (body); 173 0 : GNUNET_log (GNUNET_ERROR_TYPE_INFO, 174 : "Requesting URL '%s'\n", 175 : ph->url); 176 0 : ph->job = GNUNET_CURL_job_add2 (ctx, 177 : eh, 178 0 : ph->post_ctx.headers, 179 : &handle_post_extensions_finished, 180 : ph); 181 0 : if (NULL == ph->job) 182 : { 183 0 : TALER_EXCHANGE_management_post_extensions_cancel (ph); 184 0 : return NULL; 185 : } 186 0 : return ph; 187 : } 188 : 189 : 190 : void 191 0 : TALER_EXCHANGE_management_post_extensions_cancel ( 192 : struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph) 193 : { 194 0 : if (NULL != ph->job) 195 : { 196 0 : GNUNET_CURL_job_cancel (ph->job); 197 0 : ph->job = NULL; 198 : } 199 0 : TALER_curl_easy_post_finished (&ph->post_ctx); 200 0 : GNUNET_free (ph->url); 201 0 : GNUNET_free (ph); 202 0 : }