LCOV - code coverage report
Current view: top level - exchange - taler-exchange-httpd_admin.c (source / functions) Hit Total Coverage
Test: rcoverage.info Lines: 29 47 61.7 %
Date: 2017-09-17 17:24:28 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014, 2015 GNUnet e.V.
       4             : 
       5             :   TALER is free software; you can redistribute it and/or modify it under the
       6             :   terms of the GNU Affero 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 Affero General Public License for more details.
      12             : 
      13             :   You should have received a copy of the GNU Affero General Public License along with
      14             :   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
      15             : */
      16             : /**
      17             :  * @file taler-exchange-httpd_admin.c
      18             :  * @brief Handle /admin/ requests
      19             :  * @author Christian Grothoff
      20             :  */
      21             : #include "platform.h"
      22             : #include <gnunet/gnunet_util_lib.h>
      23             : #include <jansson.h>
      24             : #include "taler-exchange-httpd_admin.h"
      25             : #include "taler-exchange-httpd_parsing.h"
      26             : #include "taler-exchange-httpd_responses.h"
      27             : #include "taler-exchange-httpd_validation.h"
      28             : 
      29             : 
      30             : /**
      31             :  * Closure for #admin_add_incoming_transaction()
      32             :  */
      33             : struct AddIncomingContext
      34             : {
      35             :   /**
      36             :    * public key of the reserve
      37             :    */
      38             :   struct TALER_ReservePublicKeyP reserve_pub;
      39             : 
      40             :   /**
      41             :    * amount to add to the reserve
      42             :    */
      43             :   struct TALER_Amount amount;
      44             : 
      45             :   /**
      46             :    * When did we receive the wire transfer
      47             :    */
      48             :   struct GNUNET_TIME_Absolute execution_time;
      49             : 
      50             :   /**
      51             :    * which account send the funds
      52             :    */
      53             :   json_t *sender_account_details;
      54             : 
      55             :   /**
      56             :    * Information that uniquely identifies the transfer
      57             :    */
      58             :   json_t *transfer_details;
      59             : 
      60             :   /**
      61             :    * Set to the transaction status.
      62             :    */
      63             :   enum GNUNET_DB_QueryStatus qs;
      64             : };
      65             : 
      66             : 
      67             : /** 
      68             :  * Add an incoming transaction to the database.  Checks if the
      69             :  * transaction is fresh (not a duplicate) and if so adds it to
      70             :  * the database.
      71             :  *
      72             :  * If it returns a non-error code, the transaction logic MUST
      73             :  * NOT queue a MHD response.  IF it returns an hard error, the
      74             :  * transaction logic MUST queue a MHD response and set @a mhd_ret.  IF
      75             :  * it returns the soft error code, the function MAY be called again to
      76             :  * retry and MUST not queue a MHD response.
      77             :  *
      78             :  * @param cls closure with the `struct AddIncomingContext *`
      79             :  * @param connection MHD request which triggered the transaction
      80             :  * @param session database session to use
      81             :  * @param[out] mhd_ret set to MHD response status for @a connection,
      82             :  *             if transaction failed (!)
      83             :  * @return transaction status
      84             :  */
      85             : static enum GNUNET_DB_QueryStatus
      86           6 : admin_add_incoming_transaction (void *cls,
      87             :                                 struct MHD_Connection *connection,
      88             :                                 struct TALER_EXCHANGEDB_Session *session,
      89             :                                 int *mhd_ret)
      90             : {
      91           6 :   struct AddIncomingContext *aic = cls;
      92             :   void *json_str;
      93             : 
      94           6 :   json_str = json_dumps (aic->transfer_details,
      95             :                          JSON_INDENT(2));
      96           6 :   if (NULL == json_str)
      97             :   {
      98           0 :     GNUNET_break (0);
      99           0 :     *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
     100             :                                                      TALER_EC_PARSER_OUT_OF_MEMORY);
     101           0 :     return GNUNET_DB_STATUS_HARD_ERROR;
     102             :   }
     103          12 :   aic->qs = TEH_plugin->reserves_in_insert (TEH_plugin->cls,
     104             :                                             session,
     105           6 :                                             &aic->reserve_pub,
     106           6 :                                             &aic->amount,
     107             :                                             aic->execution_time,
     108           6 :                                             aic->sender_account_details,
     109             :                                             json_str,
     110             :                                             strlen (json_str));
     111           6 :   free (json_str);
     112             :   
     113           6 :   if (GNUNET_DB_STATUS_HARD_ERROR == aic->qs)
     114             :   {
     115           0 :     GNUNET_break (0);
     116           0 :     *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
     117             :                                                      TALER_EC_ADMIN_ADD_INCOMING_DB_STORE);
     118           0 :     return GNUNET_DB_STATUS_HARD_ERROR;
     119             :   }
     120           6 :   return aic->qs;
     121             : }
     122             : 
     123             : 
     124             : /**
     125             :  * Handle a "/admin/add/incoming" request.  Parses the
     126             :  * given "reserve_pub", "amount", "transaction" and "h_wire"
     127             :  * details and adds the respective transaction to the database.
     128             :  *
     129             :  * @param rh context of the handler
     130             :  * @param connection the MHD connection to handle
     131             :  * @param[in,out] connection_cls the connection's closure (can be updated)
     132             :  * @param upload_data upload data
     133             :  * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
     134             :  * @return MHD result code
     135             :   */
     136             : int
     137          18 : TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh,
     138             :                                       struct MHD_Connection *connection,
     139             :                                       void **connection_cls,
     140             :                                       const char *upload_data,
     141             :                                       size_t *upload_data_size)
     142             : {
     143             :   struct AddIncomingContext aic;
     144             :   enum TALER_ErrorCode ec;
     145             :   char *emsg;
     146             :   json_t *root;
     147          18 :   struct GNUNET_JSON_Specification spec[] = {
     148             :     GNUNET_JSON_spec_fixed_auto ("reserve_pub", &aic.reserve_pub),
     149             :     TALER_JSON_spec_amount ("amount", &aic.amount),
     150             :     GNUNET_JSON_spec_absolute_time ("execution_date", &aic.execution_time),
     151             :     GNUNET_JSON_spec_json ("sender_account_details", &aic.sender_account_details),
     152             :     GNUNET_JSON_spec_json ("transfer_details", &aic.transfer_details),
     153             :     GNUNET_JSON_spec_end ()
     154             :   };
     155             :   int res;
     156             :   int mhd_ret;
     157             : 
     158          18 :   res = TEH_PARSE_post_json (connection,
     159             :                              connection_cls,
     160             :                              upload_data,
     161             :                              upload_data_size,
     162             :                              &root);
     163          18 :   if (GNUNET_SYSERR == res)
     164           0 :     return MHD_NO;
     165          36 :   if ( (GNUNET_NO == res) ||
     166          18 :        (NULL == root) )
     167          12 :     return MHD_YES;
     168           6 :   res = TEH_PARSE_json_data (connection,
     169             :                              root,
     170             :                              spec);
     171           6 :   json_decref (root);
     172           6 :   if (GNUNET_OK != res)
     173             :   {
     174           0 :     GNUNET_break_op (0);
     175           0 :     json_decref (root);
     176           0 :     return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
     177             :   }
     178           6 :   if (TALER_EC_NONE !=
     179           6 :       (ec = TEH_json_validate_wireformat (aic.sender_account_details,
     180             :                                           GNUNET_NO,
     181             :                                           &emsg)))
     182             :   {
     183           0 :     GNUNET_JSON_parse_free (spec);
     184           0 :     mhd_ret = TEH_RESPONSE_reply_external_error (connection,
     185             :                                                  ec,
     186             :                                                  emsg);
     187           0 :     GNUNET_free (emsg);
     188           0 :     return mhd_ret;
     189             :   }
     190           6 :   if (0 != strcasecmp (aic.amount.currency,
     191             :                        TEH_exchange_currency_string))
     192             :   {
     193           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     194             :                 "Exchange uses currency `%s', but /admin/add/incoming tried to use currency `%s'\n",
     195             :                 TEH_exchange_currency_string,
     196             :                 aic.amount.currency);
     197           0 :     GNUNET_JSON_parse_free (spec);
     198           0 :     return TEH_RESPONSE_reply_arg_invalid (connection,
     199             :                                            TALER_EC_ADMIN_ADD_INCOMING_CURRENCY_UNSUPPORTED,
     200             :                                            "amount:currency");
     201             :   }
     202           6 :   res = TEH_DB_run_transaction (connection,
     203             :                                 &mhd_ret,
     204             :                                 &admin_add_incoming_transaction,
     205             :                                 &aic);
     206           6 :   GNUNET_JSON_parse_free (spec);
     207           6 :   if (GNUNET_OK != res)
     208           0 :     return mhd_ret;
     209           6 :   return TEH_RESPONSE_reply_json_pack (connection,
     210             :                                        MHD_HTTP_OK,
     211             :                                        "{s:s}",
     212             :                                        "status",
     213           6 :                                        (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == aic.qs)
     214             :                                        ? "NEW"
     215             :                                        : "DUP");
     216             : }
     217             : 
     218             : /* end of taler-exchange-httpd_admin.c */

Generated by: LCOV version 1.13