fakebank_twg_transfer.c (5654B)
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/taler_fakebank_lib.h" 25 #include "taler/taler_bank_service.h" 26 #include "taler/taler_mhd_lib.h" 27 #include <gnunet/gnunet_mhd_compat.h> 28 #include <gnunet/gnunet_mhd_lib.h> 29 #include "fakebank.h" 30 #include "fakebank_common_transact.h" 31 #include "fakebank_twg_transfer.h" 32 33 34 /** 35 * Handle incoming HTTP request for /transfer. 36 * 37 * @param h the fakebank handle 38 * @param connection the connection 39 * @param account account making the transfer 40 * @param upload_data request data 41 * @param upload_data_size size of @a upload_data in bytes 42 * @param con_cls closure for request (a `struct ConnectionContext *`) 43 * @return MHD result code 44 */ 45 MHD_RESULT 46 TALER_FAKEBANK_handle_transfer_ ( 47 struct TALER_FAKEBANK_Handle *h, 48 struct MHD_Connection *connection, 49 const char *account, 50 const char *upload_data, 51 size_t *upload_data_size, 52 void **con_cls) 53 { 54 struct ConnectionContext *cc = *con_cls; 55 enum GNUNET_MHD_PostResult pr; 56 json_t *json; 57 uint64_t row_id; 58 struct GNUNET_TIME_Timestamp ts; 59 60 if (NULL == cc) 61 { 62 cc = GNUNET_new (struct ConnectionContext); 63 cc->ctx_cleaner = &GNUNET_MHD_post_parser_cleanup; 64 *con_cls = cc; 65 } 66 pr = GNUNET_MHD_post_parser (REQUEST_BUFFER_MAX, 67 connection, 68 &cc->ctx, 69 upload_data, 70 upload_data_size, 71 &json); 72 switch (pr) 73 { 74 case GNUNET_MHD_PR_OUT_OF_MEMORY: 75 GNUNET_break (0); 76 return MHD_NO; 77 case GNUNET_MHD_PR_CONTINUE: 78 return MHD_YES; 79 case GNUNET_MHD_PR_REQUEST_TOO_LARGE: 80 GNUNET_break (0); 81 return MHD_NO; 82 case GNUNET_MHD_PR_JSON_INVALID: 83 GNUNET_break (0); 84 return MHD_NO; 85 case GNUNET_MHD_PR_SUCCESS: 86 break; 87 } 88 { 89 struct GNUNET_HashCode uuid; 90 struct TALER_WireTransferIdentifierRawP wtid; 91 struct TALER_FullPayto credit_account; 92 char *credit; 93 const char *base_url; 94 struct TALER_Amount amount; 95 enum GNUNET_GenericReturnValue ret; 96 struct GNUNET_JSON_Specification spec[] = { 97 GNUNET_JSON_spec_fixed_auto ("request_uid", 98 &uuid), 99 TALER_JSON_spec_amount ("amount", 100 h->currency, 101 &amount), 102 GNUNET_JSON_spec_string ("exchange_base_url", 103 &base_url), 104 GNUNET_JSON_spec_fixed_auto ("wtid", 105 &wtid), 106 TALER_JSON_spec_full_payto_uri ("credit_account", 107 &credit_account), 108 GNUNET_JSON_spec_end () 109 }; 110 111 if (GNUNET_OK != 112 (ret = TALER_MHD_parse_json_data (connection, 113 json, 114 spec))) 115 { 116 GNUNET_break_op (0); 117 json_decref (json); 118 return (GNUNET_NO == ret) ? MHD_YES : MHD_NO; 119 } 120 credit = TALER_xtalerbank_account_from_payto (credit_account); 121 if (NULL == credit) 122 { 123 GNUNET_break_op (0); 124 return TALER_MHD_reply_with_error ( 125 connection, 126 MHD_HTTP_BAD_REQUEST, 127 TALER_EC_GENERIC_PAYTO_URI_MALFORMED, 128 credit_account.full_payto); 129 } 130 ret = TALER_FAKEBANK_make_transfer_ (h, 131 account, 132 credit, 133 &amount, 134 &wtid, 135 base_url, 136 &uuid, 137 &row_id, 138 &ts); 139 if (GNUNET_OK != ret) 140 { 141 MHD_RESULT res; 142 char *uids; 143 144 GNUNET_break (0); 145 uids = GNUNET_STRINGS_data_to_string_alloc (&uuid, 146 sizeof (uuid)); 147 json_decref (json); 148 res = TALER_MHD_reply_with_error (connection, 149 MHD_HTTP_CONFLICT, 150 TALER_EC_BANK_TRANSFER_REQUEST_UID_REUSED, 151 uids); 152 GNUNET_free (uids); 153 return res; 154 } 155 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 156 "Receiving incoming wire transfer: %s->%s, subject: %s, amount: %s, from %s\n", 157 account, 158 credit, 159 TALER_B2S (&wtid), 160 TALER_amount2s (&amount), 161 base_url); 162 GNUNET_free (credit); 163 } 164 json_decref (json); 165 166 /* Finally build response object */ 167 return TALER_MHD_REPLY_JSON_PACK ( 168 connection, 169 MHD_HTTP_OK, 170 GNUNET_JSON_pack_uint64 ("row_id", 171 row_id), 172 GNUNET_JSON_pack_timestamp ("timestamp", 173 ts)); 174 }