fakebank_twg_transfer.c (5682B)
1 /* 2 This file is part of TALER 3 (C) 2016-2024 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or 6 modify it under the terms of the GNU General Public License 7 as published by the Free Software Foundation; either version 3, 8 or (at your option) any later version. 9 10 TALER is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public 16 License along with TALER; see the file COPYING. If not, 17 see <http://www.gnu.org/licenses/> 18 */ 19 /** 20 * @file bank-lib/fakebank_twg_transfer.c 21 * @brief implementation of the Taler Wire Gateway "/transfer" endpoint 22 * @author Christian Grothoff <christian@grothoff.org> 23 */ 24 #include "taler/platform.h" 25 #include "taler/taler_fakebank_lib.h" 26 #include "taler/taler_bank_service.h" 27 #include "taler/taler_mhd_lib.h" 28 #include <gnunet/gnunet_mhd_compat.h> 29 #include <gnunet/gnunet_mhd_lib.h> 30 #include "fakebank.h" 31 #include "fakebank_common_transact.h" 32 #include "fakebank_twg_transfer.h" 33 34 35 /** 36 * Handle incoming HTTP request for /transfer. 37 * 38 * @param h the fakebank handle 39 * @param connection the connection 40 * @param account account making the transfer 41 * @param upload_data request data 42 * @param upload_data_size size of @a upload_data in bytes 43 * @param con_cls closure for request (a `struct ConnectionContext *`) 44 * @return MHD result code 45 */ 46 MHD_RESULT 47 TALER_FAKEBANK_handle_transfer_ ( 48 struct TALER_FAKEBANK_Handle *h, 49 struct MHD_Connection *connection, 50 const char *account, 51 const char *upload_data, 52 size_t *upload_data_size, 53 void **con_cls) 54 { 55 struct ConnectionContext *cc = *con_cls; 56 enum GNUNET_MHD_PostResult pr; 57 json_t *json; 58 uint64_t row_id; 59 struct GNUNET_TIME_Timestamp ts; 60 61 if (NULL == cc) 62 { 63 cc = GNUNET_new (struct ConnectionContext); 64 cc->ctx_cleaner = &GNUNET_MHD_post_parser_cleanup; 65 *con_cls = cc; 66 } 67 pr = GNUNET_MHD_post_parser (REQUEST_BUFFER_MAX, 68 connection, 69 &cc->ctx, 70 upload_data, 71 upload_data_size, 72 &json); 73 switch (pr) 74 { 75 case GNUNET_MHD_PR_OUT_OF_MEMORY: 76 GNUNET_break (0); 77 return MHD_NO; 78 case GNUNET_MHD_PR_CONTINUE: 79 return MHD_YES; 80 case GNUNET_MHD_PR_REQUEST_TOO_LARGE: 81 GNUNET_break (0); 82 return MHD_NO; 83 case GNUNET_MHD_PR_JSON_INVALID: 84 GNUNET_break (0); 85 return MHD_NO; 86 case GNUNET_MHD_PR_SUCCESS: 87 break; 88 } 89 { 90 struct GNUNET_HashCode uuid; 91 struct TALER_WireTransferIdentifierRawP wtid; 92 struct TALER_FullPayto credit_account; 93 char *credit; 94 const char *base_url; 95 struct TALER_Amount amount; 96 enum GNUNET_GenericReturnValue ret; 97 struct GNUNET_JSON_Specification spec[] = { 98 GNUNET_JSON_spec_fixed_auto ("request_uid", 99 &uuid), 100 TALER_JSON_spec_amount ("amount", 101 h->currency, 102 &amount), 103 GNUNET_JSON_spec_string ("exchange_base_url", 104 &base_url), 105 GNUNET_JSON_spec_fixed_auto ("wtid", 106 &wtid), 107 TALER_JSON_spec_full_payto_uri ("credit_account", 108 &credit_account), 109 GNUNET_JSON_spec_end () 110 }; 111 112 if (GNUNET_OK != 113 (ret = TALER_MHD_parse_json_data (connection, 114 json, 115 spec))) 116 { 117 GNUNET_break_op (0); 118 json_decref (json); 119 return (GNUNET_NO == ret) ? MHD_YES : MHD_NO; 120 } 121 credit = TALER_xtalerbank_account_from_payto (credit_account); 122 if (NULL == credit) 123 { 124 GNUNET_break_op (0); 125 return TALER_MHD_reply_with_error ( 126 connection, 127 MHD_HTTP_BAD_REQUEST, 128 TALER_EC_GENERIC_PAYTO_URI_MALFORMED, 129 credit_account.full_payto); 130 } 131 ret = TALER_FAKEBANK_make_transfer_ (h, 132 account, 133 credit, 134 &amount, 135 &wtid, 136 base_url, 137 &uuid, 138 &row_id, 139 &ts); 140 if (GNUNET_OK != ret) 141 { 142 MHD_RESULT res; 143 char *uids; 144 145 GNUNET_break (0); 146 uids = GNUNET_STRINGS_data_to_string_alloc (&uuid, 147 sizeof (uuid)); 148 json_decref (json); 149 res = TALER_MHD_reply_with_error (connection, 150 MHD_HTTP_CONFLICT, 151 TALER_EC_BANK_TRANSFER_REQUEST_UID_REUSED, 152 uids); 153 GNUNET_free (uids); 154 return res; 155 } 156 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 157 "Receiving incoming wire transfer: %s->%s, subject: %s, amount: %s, from %s\n", 158 account, 159 credit, 160 TALER_B2S (&wtid), 161 TALER_amount2s (&amount), 162 base_url); 163 GNUNET_free (credit); 164 } 165 json_decref (json); 166 167 /* Finally build response object */ 168 return TALER_MHD_REPLY_JSON_PACK ( 169 connection, 170 MHD_HTTP_OK, 171 GNUNET_JSON_pack_uint64 ("row_id", 172 row_id), 173 GNUNET_JSON_pack_timestamp ("timestamp", 174 ts)); 175 }