exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

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 }