sketch logic for wire-fee management endpoint
This commit is contained in:
parent
3d8abcc041
commit
b65a2f77eb
276
src/exchange/taler-exchange-httpd_management_wire_fees.c
Normal file
276
src/exchange/taler-exchange-httpd_management_wire_fees.c
Normal file
@ -0,0 +1,276 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2020 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Affero General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License along with
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file taler-exchange-httpd_management_wire_fees.c
|
||||
* @brief Handle request to add wire fee details
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include <gnunet/gnunet_util_lib.h>
|
||||
#include <gnunet/gnunet_json_lib.h>
|
||||
#include <jansson.h>
|
||||
#include <microhttpd.h>
|
||||
#include <pthread.h>
|
||||
#include "taler_json_lib.h"
|
||||
#include "taler_mhd_lib.h"
|
||||
#include "taler-exchange-httpd_refund.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
|
||||
/**
|
||||
* Closure for the #add_fee transaction.
|
||||
*/
|
||||
struct AddFeeContext
|
||||
{
|
||||
/**
|
||||
* Fee's signature affirming the #TALER_SIGNATURE_MASTER_WIRE_FEES operation.
|
||||
*/
|
||||
struct TALER_MasterSignatureP master_sig;
|
||||
|
||||
/**
|
||||
* Wire method this is about.
|
||||
*/
|
||||
const char *wire_method;
|
||||
|
||||
/**
|
||||
* Starting period.
|
||||
*/
|
||||
struct GNUNET_TIME_Absolute start_time;
|
||||
|
||||
/**
|
||||
* End of period.
|
||||
*/
|
||||
struct GNUNET_TIME_Absolute end_time;
|
||||
|
||||
/**
|
||||
* Wire fee amount.
|
||||
*/
|
||||
struct TALER_Amount wire_fee;
|
||||
|
||||
/**
|
||||
* Closing fee amount.
|
||||
*/
|
||||
struct TALER_Amount closing_fee;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function implementing database transaction to add a fee. Runs the
|
||||
* transaction logic; IF it returns a non-error code, the transaction logic
|
||||
* MUST NOT queue a MHD response. IF it returns an hard error, the
|
||||
* transaction logic MUST queue a MHD response and set @a mhd_ret. IF it
|
||||
* returns the soft error code, the function MAY be called again to retry and
|
||||
* MUST not queue a MHD response.
|
||||
*
|
||||
* @param cls closure with a `struct AddFeeContext`
|
||||
* @param connection MHD request which triggered the transaction
|
||||
* @param session database session to use
|
||||
* @param[out] mhd_ret set to MHD response status for @a connection,
|
||||
* if transaction failed (!)
|
||||
* @return transaction status
|
||||
*/
|
||||
static enum GNUNET_DB_QueryStatus
|
||||
add_fee (void *cls,
|
||||
struct MHD_Connection *connection,
|
||||
struct TALER_EXCHANGEDB_Session *session,
|
||||
MHD_RESULT *mhd_ret)
|
||||
{
|
||||
struct AddFeeContext *afc = cls;
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
struct TALER_Amount wire_fee;
|
||||
struct TALER_Amount closing_fee;
|
||||
|
||||
qs = TEH_plugin->lookup_wire_fee (
|
||||
TEH_plugin->cls,
|
||||
session,
|
||||
aws->wire_method,
|
||||
aws->start_time,
|
||||
aws->end_time,
|
||||
&wire_fee,
|
||||
&closing_fee);
|
||||
if (qs < 0)
|
||||
{
|
||||
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
|
||||
return qs;
|
||||
GNUNET_break (0);
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_GENERIC_DB_LOOKUP_FAILED,
|
||||
"lookup wire fee");
|
||||
return qs;
|
||||
}
|
||||
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs)
|
||||
{
|
||||
if ( (GNUNET_OK ==
|
||||
TALER_amount_is_valid (&wire_fee)) &&
|
||||
(0 ==
|
||||
TALER_amount_cmp (&wire_fee,
|
||||
&afc->wire_fee)) &&
|
||||
(0 ==
|
||||
TALER_amount_cmp (&closing_fee,
|
||||
&afc->closing_fee)) )
|
||||
{
|
||||
/* this will trigger the 'success' response */
|
||||
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_CONFLICT,
|
||||
TALER_EC_XXX,
|
||||
NULL);
|
||||
}
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
|
||||
qs = TEH_plugin->insert_wire_fee (
|
||||
TEH_plugin->cls,
|
||||
session,
|
||||
aws->wire_method,
|
||||
aws->start_time,
|
||||
aws->end_time,
|
||||
&aws->wire_fee,
|
||||
&aws->closing_fee,
|
||||
&aws->master_sig);
|
||||
if (qs < 0)
|
||||
{
|
||||
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
|
||||
return qs;
|
||||
GNUNET_break (0);
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_GENERIC_DB_STORE_FAILED,
|
||||
"insert fee");
|
||||
return qs;
|
||||
}
|
||||
return qs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle a POST "/management/wire-fees" request.
|
||||
*
|
||||
* @param connection the MHD connection to handle
|
||||
* @param root uploaded JSON data
|
||||
* @return MHD result code
|
||||
*/
|
||||
MHD_RESULT
|
||||
TEH_handler_management_post_wire_fees (
|
||||
struct MHD_Connection *connection,
|
||||
const json_t *root)
|
||||
{
|
||||
struct AddFeeContext afc;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("master_sig",
|
||||
&afc.master_sig),
|
||||
GNUNET_JSON_spec_string ("wire_method",
|
||||
&afc.wire_method),
|
||||
TALER_JSON_spec_time_abs ("fee_start",
|
||||
&afc.start_time),
|
||||
TALER_JSON_spec_time_abs ("fee_end",
|
||||
&afc.end_time),
|
||||
TALER_JSON_spec_amount ("closing_fee",
|
||||
&afc.closing_fee),
|
||||
TALER_JSON_spec_amount ("wire_fee",
|
||||
&afc.wire_fee),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
{
|
||||
enum GNUNET_GenericReturnValue res;
|
||||
|
||||
res = TALER_MHD_parse_json_data (connection,
|
||||
root,
|
||||
spec);
|
||||
if (GNUNET_SYSERR == res)
|
||||
return MHD_NO; /* hard failure */
|
||||
if (GNUNET_NO == res)
|
||||
return MHD_YES; /* failure */
|
||||
}
|
||||
|
||||
if (0 !=
|
||||
TALER_amount_cmp_currency (&afc.closing_fee,
|
||||
&afc.wire_fee))
|
||||
{
|
||||
/* currencies of the two fees must be identical */
|
||||
GNUNET_break_op (0);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_BAD_CURRENCY,
|
||||
NULL);
|
||||
}
|
||||
if (0 !=
|
||||
strcasecmp (afc.wire_fee.currency,
|
||||
TEH_currency))
|
||||
{
|
||||
/* currency does not match exchange's currency */
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_PRECONDITION_FAILED,
|
||||
TALER_EC_GENERIC_BAD_CURRENCY,
|
||||
TEH_currency);
|
||||
}
|
||||
|
||||
{
|
||||
struct TALER_MasterWireFeePS wf = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES),
|
||||
.purpose.size = htonl (wf),
|
||||
.start_date = GNUNET_TIME_absolute_hton (afc.start_date),
|
||||
.end_date = GNUNET_TIME_absolute_hton (afc.end_date),
|
||||
};
|
||||
|
||||
TALER_amount_hton (&kv.wire_fee,
|
||||
&afc.wire_fee);
|
||||
TALER_amount_hton (&kv.closing_fee,
|
||||
&afc.closing_fee);
|
||||
GNUNET_CRYPTO_hash (afc.wire_method,
|
||||
strlen (afc.wire_method) + 1,
|
||||
&wf.h_wire_method);
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (
|
||||
TALER_SIGNATURE_MASTER_WIRE_FEES,
|
||||
&wf,
|
||||
&afc.master_sig.eddsa_sig,
|
||||
&TEH_master_public_key.eddsa_pub))
|
||||
{
|
||||
/* signature invalid */
|
||||
GNUNET_break_op (0);
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_FORBIDDEN,
|
||||
TALER_EC_EXCHANGE_XXX,
|
||||
NULL);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
qs = TEH_DB_run_transaction (connection,
|
||||
"add wire fee",
|
||||
&res,
|
||||
&add_fee,
|
||||
&afc);
|
||||
if (qs < 0)
|
||||
return res;
|
||||
return TALER_MHD_reply_static (
|
||||
connection,
|
||||
MHD_HTTP_NO_CONTENT,
|
||||
NULL,
|
||||
NULL,
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
/* end of taler-exchange-httpd_management_wire_fees.c */
|
@ -3172,12 +3172,41 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
* @return transaction status code
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
(*insert_auditor_denom_sig)(void *cls,
|
||||
struct TALER_EXCHANGEDB_Session *session,
|
||||
const struct GNUNET_HashCode *h_denom_pub,
|
||||
const struct TALER_AuditorPublicKeyP *auditor_pub,
|
||||
const struct
|
||||
TALER_AuditorSignatureP *auditor_sig);
|
||||
(*insert_auditor_denom_sig)(
|
||||
void *cls,
|
||||
struct TALER_EXCHANGEDB_Session *session,
|
||||
const struct GNUNET_HashCode *h_denom_pub,
|
||||
const struct TALER_AuditorPublicKeyP *auditor_pub,
|
||||
const struct TALER_AuditorSignatureP *auditor_sig);
|
||||
|
||||
|
||||
/**
|
||||
* Lookup information about known wire fees.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param session a session
|
||||
* @param wire_method the wire method to lookup fees for
|
||||
* @param start_time starting time of fee
|
||||
* @param end_time end time of fee
|
||||
* @param[out] wire_fee wire fee for that time period; if
|
||||
* different wire fee exists within this time
|
||||
* period, an 'invalid' amount is returned.
|
||||
* @param[out] closing_fee wire fee for that time period; if
|
||||
* different wire fee exists within this time
|
||||
* period, an 'invalid' amount is returned.
|
||||
* @return transaction status code
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
(*lookup_wire_fee_by_time)(
|
||||
void *cls,
|
||||
struct TALER_EXCHANGEDB_Session *session,
|
||||
const char *wire_method,
|
||||
struct GNUNET_TIME_Absolute start_time,
|
||||
struct GNUNET_TIME_Absolute end_time,
|
||||
struct TALER_Amount *wire_fee,
|
||||
struct TALER_Amount *closing_fee);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* _TALER_EXCHANGE_DB_H */
|
||||
|
Loading…
Reference in New Issue
Block a user