merchant_api_get-private-accounts-H_WIRE.c (7100B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2022-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 Lesser General Public License as published by the Free Software 7 Foundation; either version 2.1, 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 Lesser General Public License for more details. 12 13 You should have received a copy of the GNU Lesser General Public License along with 14 TALER; see the file COPYING.LGPL. If not, see 15 <http://www.gnu.org/licenses/> 16 */ 17 /** 18 * @file merchant_api_get-private-accounts-H_WIRE-new.c 19 * @brief Implementation of the GET /private/accounts/$H_WIRE request 20 * @author Christian Grothoff 21 */ 22 #include "taler/platform.h" 23 #include <curl/curl.h> 24 #include <jansson.h> 25 #include <microhttpd.h> /* just for HTTP status codes */ 26 #include <gnunet/gnunet_util_lib.h> 27 #include <gnunet/gnunet_curl_lib.h> 28 #include <taler/taler-merchant/get-private-accounts-H_WIRE.h> 29 #include "merchant_api_curl_defaults.h" 30 #include <taler/taler_json_lib.h> 31 32 33 /** 34 * Handle for a GET /private/accounts/$H_WIRE operation. 35 */ 36 struct TALER_MERCHANT_GetPrivateAccountHandle 37 { 38 /** 39 * Base URL of the merchant backend. 40 */ 41 char *base_url; 42 43 /** 44 * Instance identifier. 45 */ 46 char *instance_id; 47 48 /** 49 * Hash of the wire details identifying the account. 50 */ 51 struct TALER_MerchantWireHashP h_wire; 52 53 /** 54 * The full URL for this request. 55 */ 56 char *url; 57 58 /** 59 * Handle for the request. 60 */ 61 struct GNUNET_CURL_Job *job; 62 63 /** 64 * Function to call with the result. 65 */ 66 TALER_MERCHANT_GetPrivateAccountCallback cb; 67 68 /** 69 * Closure for @a cb. 70 */ 71 TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls; 72 73 /** 74 * Reference to the execution context. 75 */ 76 struct GNUNET_CURL_Context *ctx; 77 }; 78 79 80 /** 81 * Function called when we're done processing the 82 * HTTP GET /private/accounts/$H_WIRE request. 83 * 84 * @param cls the `struct TALER_MERCHANT_GetPrivateAccountHandle` 85 * @param response_code HTTP response code, 0 on error 86 * @param response response body, NULL if not in JSON 87 */ 88 static void 89 handle_get_account_finished (void *cls, 90 long response_code, 91 const void *response) 92 { 93 struct TALER_MERCHANT_GetPrivateAccountHandle *gpa = cls; 94 const json_t *json = response; 95 struct TALER_MERCHANT_GetPrivateAccountResponse agr = { 96 .hr.http_status = (unsigned int) response_code, 97 .hr.reply = json 98 }; 99 100 gpa->job = NULL; 101 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 102 "Got /private/accounts/$H_WIRE response with status code %u\n", 103 (unsigned int) response_code); 104 switch (response_code) 105 { 106 case MHD_HTTP_OK: 107 { 108 struct GNUNET_JSON_Specification spec[] = { 109 GNUNET_JSON_spec_fixed_auto ("salt", 110 &agr.details.ok.ad.salt), 111 GNUNET_JSON_spec_mark_optional ( 112 TALER_JSON_spec_web_url ("credit_facade_url", 113 &agr.details.ok.ad.credit_facade_url), 114 NULL), 115 TALER_JSON_spec_full_payto_uri ("payto_uri", 116 &agr.details.ok.ad.payto_uri), 117 GNUNET_JSON_spec_fixed_auto ("h_wire", 118 &agr.details.ok.ad.h_wire), 119 GNUNET_JSON_spec_bool ("active", 120 &agr.details.ok.ad.active), 121 GNUNET_JSON_spec_mark_optional ( 122 GNUNET_JSON_spec_object_const ( 123 "extra_wire_subject_metadata", 124 &agr.details.ok.ad.extra_wire_subject_metadata), 125 NULL), 126 GNUNET_JSON_spec_end () 127 }; 128 129 if (GNUNET_OK == 130 GNUNET_JSON_parse (json, 131 spec, 132 NULL, NULL)) 133 { 134 gpa->cb (gpa->cb_cls, 135 &agr); 136 TALER_MERCHANT_get_private_account_cancel (gpa); 137 return; 138 } 139 agr.hr.http_status = 0; 140 agr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; 141 break; 142 } 143 case MHD_HTTP_UNAUTHORIZED: 144 agr.hr.ec = TALER_JSON_get_error_code (json); 145 agr.hr.hint = TALER_JSON_get_error_hint (json); 146 break; 147 case MHD_HTTP_NOT_FOUND: 148 agr.hr.ec = TALER_JSON_get_error_code (json); 149 agr.hr.hint = TALER_JSON_get_error_hint (json); 150 break; 151 default: 152 agr.hr.ec = TALER_JSON_get_error_code (json); 153 agr.hr.hint = TALER_JSON_get_error_hint (json); 154 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 155 "Unexpected response code %u/%d\n", 156 (unsigned int) response_code, 157 (int) agr.hr.ec); 158 break; 159 } 160 gpa->cb (gpa->cb_cls, 161 &agr); 162 TALER_MERCHANT_get_private_account_cancel (gpa); 163 } 164 165 166 struct TALER_MERCHANT_GetPrivateAccountHandle * 167 TALER_MERCHANT_get_private_account_create ( 168 struct GNUNET_CURL_Context *ctx, 169 const char *url, 170 const char *instance_id, 171 const struct TALER_MerchantWireHashP *h_wire) 172 { 173 struct TALER_MERCHANT_GetPrivateAccountHandle *gpa; 174 175 gpa = GNUNET_new (struct TALER_MERCHANT_GetPrivateAccountHandle); 176 gpa->ctx = ctx; 177 gpa->base_url = GNUNET_strdup (url); 178 gpa->instance_id = GNUNET_strdup (instance_id); 179 gpa->h_wire = *h_wire; 180 return gpa; 181 } 182 183 184 enum TALER_ErrorCode 185 TALER_MERCHANT_get_private_account_start ( 186 struct TALER_MERCHANT_GetPrivateAccountHandle *gpa, 187 TALER_MERCHANT_GetPrivateAccountCallback cb, 188 TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls) 189 { 190 CURL *eh; 191 192 gpa->cb = cb; 193 gpa->cb_cls = cb_cls; 194 { 195 char w_str[sizeof (gpa->h_wire) * 2]; 196 char *path; 197 char *end; 198 199 end = GNUNET_STRINGS_data_to_string (&gpa->h_wire, 200 sizeof (gpa->h_wire), 201 w_str, 202 sizeof (w_str)); 203 *end = '\0'; 204 GNUNET_asprintf (&path, 205 "private/accounts/%s", 206 w_str); 207 gpa->url = TALER_url_join (gpa->base_url, 208 path, 209 NULL); 210 GNUNET_free (path); 211 } 212 if (NULL == gpa->url) 213 return TALER_EC_GENERIC_CONFIGURATION_INVALID; 214 eh = TALER_MERCHANT_curl_easy_get_ (gpa->url); 215 if (NULL == eh) 216 return TALER_EC_GENERIC_CONFIGURATION_INVALID; 217 gpa->job = GNUNET_CURL_job_add (gpa->ctx, 218 eh, 219 &handle_get_account_finished, 220 gpa); 221 if (NULL == gpa->job) 222 return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; 223 return TALER_EC_NONE; 224 } 225 226 227 void 228 TALER_MERCHANT_get_private_account_cancel ( 229 struct TALER_MERCHANT_GetPrivateAccountHandle *gpa) 230 { 231 if (NULL != gpa->job) 232 { 233 GNUNET_CURL_job_cancel (gpa->job); 234 gpa->job = NULL; 235 } 236 GNUNET_free (gpa->url); 237 GNUNET_free (gpa->instance_id); 238 GNUNET_free (gpa->base_url); 239 GNUNET_free (gpa); 240 } 241 242 243 /* end of merchant_api_get-private-accounts-H_WIRE-new.c */