bank_api_admin_add_kycauth.c (7153B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2015--2024 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 bank-lib/bank_api_admin_add_kycauth.c 19 * @brief Implementation of the /admin/add-kycauth requests of the bank's HTTP API 20 * @author Christian Grothoff 21 */ 22 #include "bank_api_common.h" 23 #include <microhttpd.h> /* just for HTTP status codes */ 24 #include "taler/taler_signatures.h" 25 #include "taler/taler_curl_lib.h" 26 27 28 /** 29 * @brief An /admin/add-kycauth Handle 30 */ 31 struct TALER_BANK_AdminAddKycauthHandle 32 { 33 34 /** 35 * The url for this request. 36 */ 37 char *request_url; 38 39 /** 40 * POST context. 41 */ 42 struct TALER_CURL_PostContext post_ctx; 43 44 /** 45 * Handle for the request. 46 */ 47 struct GNUNET_CURL_Job *job; 48 49 /** 50 * Function to call with the result. 51 */ 52 TALER_BANK_AdminAddKycauthCallback cb; 53 54 /** 55 * Closure for @a cb. 56 */ 57 void *cb_cls; 58 59 }; 60 61 62 /** 63 * Function called when we're done processing the 64 * HTTP /admin/add-kycauth request. 65 * 66 * @param cls the `struct TALER_BANK_AdminAddKycauthHandle` 67 * @param response_code HTTP response code, 0 on error 68 * @param response parsed JSON result, NULL on error 69 */ 70 static void 71 handle_admin_add_kycauth_finished (void *cls, 72 long response_code, 73 const void *response) 74 { 75 struct TALER_BANK_AdminAddKycauthHandle *aai = cls; 76 const json_t *j = response; 77 struct TALER_BANK_AdminAddKycauthResponse ir = { 78 .http_status = response_code, 79 .response = response 80 }; 81 82 aai->job = NULL; 83 switch (response_code) 84 { 85 case 0: 86 ir.ec = TALER_EC_GENERIC_INVALID_RESPONSE; 87 break; 88 case MHD_HTTP_OK: 89 { 90 struct GNUNET_JSON_Specification spec[] = { 91 GNUNET_JSON_spec_uint64 ("row_id", 92 &ir.details.ok.serial_id), 93 GNUNET_JSON_spec_timestamp ("timestamp", 94 &ir.details.ok.timestamp), 95 GNUNET_JSON_spec_end () 96 }; 97 98 if (GNUNET_OK != 99 GNUNET_JSON_parse (j, 100 spec, 101 NULL, NULL)) 102 { 103 GNUNET_break_op (0); 104 ir.http_status = 0; 105 ir.ec = TALER_EC_GENERIC_INVALID_RESPONSE; 106 break; 107 } 108 } 109 break; 110 case MHD_HTTP_BAD_REQUEST: 111 /* This should never happen, either us or the bank is buggy 112 (or API version conflict); just pass JSON reply to the application */ 113 GNUNET_break_op (0); 114 ir.ec = TALER_JSON_get_error_code (j); 115 break; 116 case MHD_HTTP_FORBIDDEN: 117 /* Access denied */ 118 ir.ec = TALER_JSON_get_error_code (j); 119 break; 120 case MHD_HTTP_UNAUTHORIZED: 121 /* Nothing really to verify, bank says the password is invalid; we should 122 pass the JSON reply to the application */ 123 ir.ec = TALER_JSON_get_error_code (j); 124 break; 125 case MHD_HTTP_NOT_FOUND: 126 /* Nothing really to verify, maybe account really does not exist. 127 We should pass the JSON reply to the application */ 128 ir.ec = TALER_JSON_get_error_code (j); 129 break; 130 case MHD_HTTP_INTERNAL_SERVER_ERROR: 131 /* Server had an internal issue; we should retry, but this API 132 leaves this to the application */ 133 ir.ec = TALER_JSON_get_error_code (j); 134 break; 135 default: 136 /* unexpected response code */ 137 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 138 "Unexpected response code %u\n", 139 (unsigned int) response_code); 140 GNUNET_break (0); 141 ir.ec = TALER_JSON_get_error_code (j); 142 break; 143 } 144 aai->cb (aai->cb_cls, 145 &ir); 146 TALER_BANK_admin_add_kycauth_cancel (aai); 147 } 148 149 150 struct TALER_BANK_AdminAddKycauthHandle * 151 TALER_BANK_admin_add_kycauth ( 152 struct GNUNET_CURL_Context *ctx, 153 const struct TALER_BANK_AuthenticationData *auth, 154 const union TALER_AccountPublicKeyP *account_pub, 155 const struct TALER_Amount *amount, 156 const struct TALER_FullPayto debit_account, 157 TALER_BANK_AdminAddKycauthCallback res_cb, 158 void *res_cb_cls) 159 { 160 struct TALER_BANK_AdminAddKycauthHandle *aai; 161 json_t *admin_obj; 162 CURL *eh; 163 164 if (NULL == debit_account.full_payto) 165 { 166 GNUNET_break (0); 167 return NULL; 168 } 169 if (NULL == account_pub) 170 { 171 GNUNET_break (0); 172 return NULL; 173 } 174 if (NULL == amount) 175 { 176 GNUNET_break (0); 177 return NULL; 178 } 179 admin_obj = GNUNET_JSON_PACK ( 180 GNUNET_JSON_pack_data_auto ("account_pub", 181 account_pub), 182 TALER_JSON_pack_amount ("amount", 183 amount), 184 TALER_JSON_pack_full_payto ("debit_account", 185 debit_account)); 186 if (NULL == admin_obj) 187 { 188 GNUNET_break (0); 189 return NULL; 190 } 191 aai = GNUNET_new (struct TALER_BANK_AdminAddKycauthHandle); 192 aai->cb = res_cb; 193 aai->cb_cls = res_cb_cls; 194 aai->request_url = TALER_url_join (auth->wire_gateway_url, 195 "admin/add-kycauth", 196 NULL); 197 if (NULL == aai->request_url) 198 { 199 GNUNET_free (aai); 200 json_decref (admin_obj); 201 return NULL; 202 } 203 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 204 "Requesting administrative transaction at `%s' for account %s\n", 205 aai->request_url, 206 TALER_B2S (account_pub)); 207 aai->post_ctx.headers 208 = curl_slist_append ( 209 aai->post_ctx.headers, 210 "Content-Type: application/json"); 211 212 eh = curl_easy_init (); 213 if ( (NULL == eh) || 214 (GNUNET_OK != 215 TALER_BANK_setup_auth_ (eh, 216 auth)) || 217 (CURLE_OK != 218 curl_easy_setopt (eh, 219 CURLOPT_URL, 220 aai->request_url)) || 221 (GNUNET_OK != 222 TALER_curl_easy_post (&aai->post_ctx, 223 eh, 224 admin_obj)) ) 225 { 226 GNUNET_break (0); 227 TALER_BANK_admin_add_kycauth_cancel (aai); 228 if (NULL != eh) 229 curl_easy_cleanup (eh); 230 json_decref (admin_obj); 231 return NULL; 232 } 233 json_decref (admin_obj); 234 235 aai->job = GNUNET_CURL_job_add2 (ctx, 236 eh, 237 aai->post_ctx.headers, 238 &handle_admin_add_kycauth_finished, 239 aai); 240 return aai; 241 } 242 243 244 void 245 TALER_BANK_admin_add_kycauth_cancel ( 246 struct TALER_BANK_AdminAddKycauthHandle *aai) 247 { 248 if (NULL != aai->job) 249 { 250 GNUNET_CURL_job_cancel (aai->job); 251 aai->job = NULL; 252 } 253 TALER_curl_easy_post_finished (&aai->post_ctx); 254 GNUNET_free (aai->request_url); 255 GNUNET_free (aai); 256 } 257 258 259 /* end of bank_api_admin_add_kycauth.c */