merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit 3e60ebd5c0e535a2dbfee765477f582e3a2b37e7
parent 38e0c53097a6df0033a35ba90f712b3c89571a98
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon, 17 May 2021 22:46:22 +0200

implement #6876

Diffstat:
Msrc/backend/Makefile.am | 2++
Msrc/backend/taler-merchant-httpd.c | 12++++++++++++
Asrc/backend/taler-merchant-httpd_private-delete-transfers-ID.c | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/backend/taler-merchant-httpd_private-delete-transfers-ID.h | 42++++++++++++++++++++++++++++++++++++++++++
Msrc/backenddb/plugin_merchantdb_postgres.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/include/taler_merchantdb_plugin.h | 32++++++++++++++++++++++++++++++++
6 files changed, 277 insertions(+), 0 deletions(-)

diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am @@ -40,6 +40,8 @@ taler_merchant_httpd_SOURCES = \ taler-merchant-httpd_private-delete-orders-ID.h \ taler-merchant-httpd_private-delete-reserves-ID.c \ taler-merchant-httpd_private-delete-reserves-ID.h \ + taler-merchant-httpd_private-delete-transfers-ID.c \ + taler-merchant-httpd_private-delete-transfers-ID.h \ taler-merchant-httpd_private-get-instances.c \ taler-merchant-httpd_private-get-instances.h \ taler-merchant-httpd_private-get-instances-ID.c \ diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c @@ -34,6 +34,7 @@ #include "taler-merchant-httpd_private-delete-products-ID.h" #include "taler-merchant-httpd_private-delete-orders-ID.h" #include "taler-merchant-httpd_private-delete-reserves-ID.h" +#include "taler-merchant-httpd_private-delete-transfers-ID.h" #include "taler-merchant-httpd_private-get-instances.h" #include "taler-merchant-httpd_private-get-instances-ID.h" #include "taler-merchant-httpd_private-get-products.h" @@ -1403,6 +1404,17 @@ url_handler (void *cls, to set a conservative bound for sane wallets */ .max_upload = 1024 * 1024 }, + /* DELETE /transfers/$ID: */ + { + .url_prefix = "/transfers", + .method = MHD_HTTP_METHOD_DELETE, + .allow_deleted_instance = true, + .handler = &TMH_private_delete_transfers_ID, + .have_id_segment = true, + /* the body should be pretty small, allow 1 MB of upload + to set a conservative bound for sane wallets */ + .max_upload = 1024 * 1024 + }, /* GET /transfers: */ { .url_prefix = "/transfers", diff --git a/src/backend/taler-merchant-httpd_private-delete-transfers-ID.c b/src/backend/taler-merchant-httpd_private-delete-transfers-ID.c @@ -0,0 +1,97 @@ +/* + This file is part of TALER + (C) 2021 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 General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file taler-merchant-httpd_private-delete-transfers-ID.c + * @brief implement DELETE /transfers/$ID + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler-merchant-httpd_private-delete-transfers-ID.h" +#include <taler/taler_json_lib.h> + + +/** + * Handle a DELETE "/transfers/$ID" request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] hc context with further information about the request + * @return MHD result code + */ +MHD_RESULT +TMH_private_delete_transfers_ID (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + struct TMH_MerchantInstance *mi = hc->instance; + enum GNUNET_DB_QueryStatus qs; + unsigned long long serial; + char dummy; + + GNUNET_assert (NULL != mi); + if (1 != + sscanf (hc->infix, + "%llu%c", + &serial, + &dummy)) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + hc->infix); + } + qs = TMH_db->delete_transfer (TMH_db->cls, + mi->settings.id, + serial); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_COMMIT_FAILED, + NULL); + case GNUNET_DB_STATUS_SOFT_ERROR: + GNUNET_break (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, + NULL); + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + qs = TMH_db->check_transfer_exists (TMH_db->cls, + mi->settings.id, + serial); + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_MERCHANT_GENERIC_TRANSFER_UNKNOWN, + hc->infix); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_CONFLICT, + TALER_EC_MERCHANT_PRIVATE_DELETE_TRANSFERS_ALREADY_CONFIRMED, + hc->infix); + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + return TALER_MHD_reply_static (connection, + MHD_HTTP_NO_CONTENT, + NULL, + NULL, + 0); + } + GNUNET_assert (0); + return MHD_NO; +} + + +/* end of taler-merchant-httpd_private-delete-transfers-ID.c */ diff --git a/src/backend/taler-merchant-httpd_private-delete-transfers-ID.h b/src/backend/taler-merchant-httpd_private-delete-transfers-ID.h @@ -0,0 +1,42 @@ +/* + This file is part of TALER + (C) 2019, 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 General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file taler-merchant-httpd_private-delete-transfers-ID.h + * @brief implement DELETE /transfers/$ID/ + * @author Christian Grothoff + */ +#ifndef TALER_MERCHANT_HTTPD_PRIVATE_DELETE_TRANSFERS_ID_H +#define TALER_MERCHANT_HTTPD_PRIVATE_DELETE_TRANSFERS_ID_H + +#include "taler-merchant-httpd.h" + + +/** + * Handle a DELETE "/transfers/$ID" request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] hc context with further information about the request + * @return MHD result code + */ +MHD_RESULT +TMH_private_delete_transfers_ID (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc); + +/* end of taler-merchant-httpd_private-delete-transfers-ID.h */ + +#endif diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c @@ -3420,6 +3420,68 @@ postgres_insert_transfer ( /** + * Delete information about a transfer. Note that transfers + * confirmed by the exchange cannot be deleted anymore. + * + * @param cls closure + * @param instance_id instance to delete transfer of + * @param transfer_serial_id transfer to delete + * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS + * if deletion is prohibited OR transfer is unknown + */ +static enum GNUNET_DB_QueryStatus +postgres_delete_transfer (void *cls, + const char *instance_id, + uint64_t transfer_serial_id) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_uint64 (&transfer_serial_id), + GNUNET_PQ_query_param_end + }; + + check_connection (pg); + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "delete_transfer", + params); +} + + +/** + * Check if information about a transfer exists with the + * backend. Returns no data, only the query status. + * + * @param cls closure + * @param instance_id instance to delete transfer of + * @param transfer_serial_id transfer to delete + * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT + * if the transfer record exists + */ +static enum GNUNET_DB_QueryStatus +postgres_check_transfer_exists (void *cls, + const char *instance_id, + uint64_t transfer_serial_id) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_uint64 (&transfer_serial_id), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_end + }; + + check_connection (pg); + return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "check_transfer_exists", + params, + rs); +} + + +/** * Lookup account serial by payto URI. * * @param cls closure @@ -7687,6 +7749,34 @@ postgres_connect (void *cls) " FROM merchant_instances" " WHERE merchant_id=$7)", 7), + /* for postgres_delete_transfer() */ + GNUNET_PQ_make_prepare ("delete_transfer", + "DELETE FROM merchant_transfers" + " WHERE" + " credit_serial=$2" + " AND account_serial IN " + " (SELECT account_serial " + " FROM merchant_accounts" + " WHERE merchant_serial=" + " (SELECT merchant_serial" + " FROM merchant_instances" + " WHERE merchant_id=$1))", + 2), + /* for postgres_check_transfer_exists() */ + GNUNET_PQ_make_prepare ("check_transfer_exists", + "SELECT" + " 1" + " FROM merchant_transfers" + " JOIN merchant_accounts" + " USING (account_serial)" + " WHERE" + " credit_serial=$2" + " AND" + " merchant_serial=" + " (SELECT merchant_serial" + " FROM merchant_instances" + " WHERE merchant_id=$1)", + 2), /* for postgres_lookup_account() */ GNUNET_PQ_make_prepare ("lookup_account", "SELECT" @@ -8616,6 +8706,8 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) plugin->lookup_refund_proof = &postgres_lookup_refund_proof; plugin->lookup_order_by_fulfillment = &postgres_lookup_order_by_fulfillment; plugin->insert_transfer = &postgres_insert_transfer; + plugin->delete_transfer = &postgres_delete_transfer; + plugin->check_transfer_exists = &postgres_check_transfer_exists; plugin->lookup_account = &postgres_lookup_account; plugin->insert_transfer_details = &postgres_insert_transfer_details; plugin->lookup_wire_fee = &postgres_lookup_wire_fee; diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h @@ -1553,6 +1553,38 @@ struct TALER_MERCHANTDB_Plugin /** + * Delete information about a transfer. Note that transfers + * confirmed by the exchange cannot be deleted anymore. + * + * @param cls closure + * @param instance_id instance to delete transfer of + * @param transfer_serial_id transfer to delete + * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS + * if deletion is prohibited OR transfer is unknown + */ + enum GNUNET_DB_QueryStatus + (*delete_transfer)(void *cls, + const char *instance_id, + uint64_t transfer_serial_id); + + + /** + * Check if information about a transfer exists with the + * backend. Returns no data, only the query status. + * + * @param cls closure + * @param instance_id instance to delete transfer of + * @param transfer_serial_id transfer to delete + * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT + * if the transfer record exists + */ + enum GNUNET_DB_QueryStatus + (*check_transfer_exists)(void *cls, + const char *instance_id, + uint64_t transfer_serial_id); + + + /** * Lookup account serial by payto URI. * * @param cls closure