diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-10-22 19:07:20 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-10-22 19:07:20 +0200 |
commit | 431db2d2beecf0487ace376cba9d5f0bbf18bb08 (patch) | |
tree | 6ef942bb10a324b824a80b86fd619c624833e586 | |
parent | 019f6fd33e3c538881841dc6939b105e4601d038 (diff) | |
download | merchant-431db2d2beecf0487ace376cba9d5f0bbf18bb08.tar.gz merchant-431db2d2beecf0487ace376cba9d5f0bbf18bb08.tar.bz2 merchant-431db2d2beecf0487ace376cba9d5f0bbf18bb08.zip |
first (incomplete) skeleton for tipping API
-rw-r--r-- | src/backend/Makefile.am | 3 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd.c | 21 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd.h | 12 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_pay.c | 2 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_responses.c | 24 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_responses.h | 19 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_tip-authorize.c | 180 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_tip-authorize.h | 44 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_tip-enable.c | 157 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_tip-enable.h | 44 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_tip-pickup.c | 44 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_tip-pickup.h | 44 | ||||
-rw-r--r-- | src/include/taler_merchantdb_plugin.h | 81 |
13 files changed, 668 insertions, 7 deletions
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index 63add5ac..28212db4 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -22,6 +22,9 @@ taler_merchant_httpd_SOURCES = \ taler-merchant-httpd_proposal.c taler-merchant-httpd_proposal.h \ taler-merchant-httpd_pay.c taler-merchant-httpd_pay.h \ taler-merchant-httpd_history.c taler-merchant-httpd_history.h \ + taler-merchant-httpd_tip-authorize.c taler-merchant-httpd_tip-authorize.h \ + taler-merchant-httpd_tip-enable.c taler-merchant-httpd_tip-enable.h \ + taler-merchant-httpd_tip-pickup.c taler-merchant-httpd_tip-pickup.h \ taler-merchant-httpd_track-transaction.c taler-merchant-httpd_track-transaction.h \ taler-merchant-httpd_track-transfer.c taler-merchant-httpd_track-transfer.h \ taler-merchant-httpd_refund.c taler-merchant-httpd_refund.h diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index 15086cc2..9c95b8b9 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -39,6 +39,9 @@ #include "taler-merchant-httpd_pay.h" #include "taler-merchant-httpd_track-transaction.h" #include "taler-merchant-httpd_track-transfer.h" +#include "taler-merchant-httpd_tip-authorize.h" +#include "taler-merchant-httpd_tip-enable.h" +#include "taler-merchant-httpd_tip-pickup.h" #include "taler-merchant-httpd_history.h" #include "taler-merchant-httpd_refund.h" @@ -220,6 +223,24 @@ url_handler (void *cls, { "/refund", NULL, "application/json", "Only POST/GET are allowed", 0, &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED}, + { "/tip-authorize", MHD_HTTP_METHOD_POST, "text/plain", + NULL, 0, + &MH_handler_tip_authorize, MHD_HTTP_OK}, + { "/tip-authorize", NULL, "application/json", + "Only POST is allowed", 0, + &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED}, + { "/tip-pickup", MHD_HTTP_METHOD_POST, "text/plain", + NULL, 0, + &MH_handler_tip_pickup, MHD_HTTP_OK}, + { "/tip-pickup", NULL, "application/json", + "Only POST is allowed", 0, + &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED}, + { "/tip-enable", MHD_HTTP_METHOD_POST, "text/plain", + NULL, 0, + &MH_handler_tip_enable, MHD_HTTP_OK}, + { "/tip-enable", NULL, "application/json", + "Only POST is allowed", 0, + &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED}, {NULL, NULL, NULL, NULL, 0, 0 } }; static struct TMH_RequestHandler h404 = diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h index c67a9713..83e9c07f 100644 --- a/src/backend/taler-merchant-httpd.h +++ b/src/backend/taler-merchant-httpd.h @@ -119,6 +119,18 @@ struct MerchantInstance */ struct TALER_MerchantPublicKeyP pubkey; + /** + * Exchange this instance uses for tipping, NULL if tipping + * is not supported. + */ + const char *tip_exchange; + + /** + * What is the private key of the reserve used for signing tips by this exchange? + * Only valid if @e tip_exchange is non-null. + */ + struct TALER_ReservePrivateKeyP tip_reserve; + }; diff --git a/src/backend/taler-merchant-httpd_pay.c b/src/backend/taler-merchant-httpd_pay.c index 7769ef2f..34d676ac 100644 --- a/src/backend/taler-merchant-httpd_pay.c +++ b/src/backend/taler-merchant-httpd_pay.c @@ -1452,7 +1452,7 @@ parse_pay (struct MHD_Connection *connection, if (GNUNET_YES != res) { GNUNET_JSON_parse_free (spec); - GNUNET_break (0); + GNUNET_break_op (0); return (GNUNET_NO == res) ? MHD_YES : MHD_NO; } diff --git a/src/backend/taler-merchant-httpd_responses.c b/src/backend/taler-merchant-httpd_responses.c index f5f994e8..1417fa24 100644 --- a/src/backend/taler-merchant-httpd_responses.c +++ b/src/backend/taler-merchant-httpd_responses.c @@ -239,6 +239,30 @@ TMH_RESPONSE_reply_request_too_large (struct MHD_Connection *connection) /** + * Send a response indicating that we did not find the @a object + * needed for the reply. + * + * @param connection the MHD connection to use + * @param response_code response code to use + * @param ec error code to return + * @param msg human-readable diagnostic + * @return a MHD result code + */ +int +TMH_RESPONSE_reply_rc (struct MHD_Connection *connection, + unsigned int response_code, + enum TALER_ErrorCode ec, + const char *msg) +{ + return TMH_RESPONSE_reply_json_pack (connection, + response_code, + "{s:I, s:s}", + "code", (json_int_t) ec, + "error", msg); +} + + +/** * Send a response indicating that the JSON was malformed. * * @param connection the MHD connection to use diff --git a/src/backend/taler-merchant-httpd_responses.h b/src/backend/taler-merchant-httpd_responses.h index ea290c5f..a96b696d 100644 --- a/src/backend/taler-merchant-httpd_responses.h +++ b/src/backend/taler-merchant-httpd_responses.h @@ -101,6 +101,23 @@ TMH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection); * needed for the reply. * * @param connection the MHD connection to use + * @param response_code response code to use + * @param ec error code to return + * @param msg human-readable diagnostic + * @return a MHD result code + */ +int +TMH_RESPONSE_reply_rc (struct MHD_Connection *connection, + unsigned int response_code, + enum TALER_ErrorCode ec, + const char *msg); + + +/** + * Send a response indicating that we did not find the @a object + * needed for the reply. + * + * @param connection the MHD connection to use * @param ec error code to return * @param object name of the object we did not find * @return a MHD result code @@ -149,7 +166,7 @@ TMH_RESPONSE_reply_internal_error (struct MHD_Connection *connection, struct MHD_Response * TMH_RESPONSE_make_internal_error (enum TALER_ErrorCode ec, const char *hint); - + /** * Send a response indicating an external error. diff --git a/src/backend/taler-merchant-httpd_tip-authorize.c b/src/backend/taler-merchant-httpd_tip-authorize.c new file mode 100644 index 00000000..415352a0 --- /dev/null +++ b/src/backend/taler-merchant-httpd_tip-authorize.c @@ -0,0 +1,180 @@ +/* + This file is part of TALER + (C) 2014-2017 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 backend/taler-merchant-httpd_tip-authorize.c + * @brief implement API for authorizing tips to be paid to visitors + * @author Christian Grothoff + */ +#include "platform.h" +#include <jansson.h> +#include <taler/taler_json_lib.h> +#include "taler-merchant-httpd.h" +#include "taler-merchant-httpd_mhd.h" +#include "taler-merchant-httpd_parsing.h" +#include "taler-merchant-httpd_exchanges.h" +#include "taler-merchant-httpd_responses.h" +#include "taler-merchant-httpd_tip-authorize.h" + + +/** + * Information we keep for individual calls + * to requests that parse JSON, but keep no other state. + */ +struct TMH_JsonParseContext +{ + + /** + * This field MUST be first. + * FIXME: Explain why! + */ + struct TM_HandlerContext hc; + + /** + * Placeholder for #TMH_PARSE_post_json() to keep its internal state. + */ + void *json_parse_context; +}; + + +/** + * Custom cleanup routine for a `struct TMH_JsonParseContext`. + * + * @param hc the `struct TMH_JsonParseContext` to clean up. + */ +static void +json_parse_cleanup (struct TM_HandlerContext *hc) +{ + struct TMH_JsonParseContext *jpc = (struct TMH_JsonParseContext *) hc; + + TMH_PARSE_post_cleanup_callback (jpc->json_parse_context); + GNUNET_free (jpc); +} + + +/** + * Handle a "/tip-authorize" request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] connection_cls the connection's closure (can be updated) + * @param upload_data upload data + * @param[in,out] upload_data_size number of bytes (left) in @a upload_data + * @return MHD result code + */ +int +MH_handler_tip_authorize (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size) +{ + enum GNUNET_DB_QueryStatus qs; + struct MerchantInstance *mi; + int res; + struct TALER_Amount amount; + const char *instance; + const char *justification; + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_amount ("amount", &amount), + GNUNET_JSON_spec_string ("instance", &instance), + GNUNET_JSON_spec_string ("justification", &justification), + GNUNET_JSON_spec_end() + }; + json_t *root; + struct GNUNET_TIME_Absolute expiration; + struct GNUNET_HashCode tip_id; + struct TMH_JsonParseContext *ctx; + + if (NULL == *connection_cls) + { + ctx = GNUNET_new (struct TMH_JsonParseContext); + ctx->hc.cc = &json_parse_cleanup; + *connection_cls = ctx; + } + else + { + ctx = *connection_cls; + } + res = TMH_PARSE_post_json (connection, + &ctx->json_parse_context, + upload_data, + upload_data_size, + &root); + if (GNUNET_SYSERR == res) + return MHD_NO; + /* the POST's body has to be further fetched */ + if ( (GNUNET_NO == res) || + (NULL == root) ) + return MHD_YES; + + res = TMH_PARSE_json_data (connection, + root, + spec); + json_decref (root); + if (GNUNET_YES != res) + { + GNUNET_break_op (0); + return (GNUNET_NO == res) ? MHD_YES : MHD_NO; + } + + mi = TMH_lookup_instance (instance); + if (NULL == mi) + return TMH_RESPONSE_reply_not_found (connection, + TALER_EC_TIP_AUTHORIZE_INSTANCE_UNKNOWN, + "unknown instance"); + if (NULL == mi->tip_exchange) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Instance `%s' not configured for tipping\n", + instance); + return TMH_RESPONSE_reply_not_found (connection, + TALER_EC_TIP_AUTHORIZE_INSTANCE_DOES_NOT_TIP, + "exchange for tipping not configured for the instance"); + } + qs = db->authorize_tip (db->cls, + justification, + &amount, + &mi->tip_reserve, + &expiration, + &tip_id); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); + return TMH_RESPONSE_reply_internal_error (connection, + TALER_EC_TIP_AUTHORIZE_DB_TRANSACTION_ERROR, + "Database error approving tip"); + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Insufficient funds to authorize tip over `%s' at instance `%s'\n", + TALER_amount2s (&amount), + instance); + return TMH_RESPONSE_reply_rc (connection, + MHD_HTTP_PRECONDITION_FAILED, + TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS, + "Insufficient funds for tip"); + } + + return TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:o, s:o, s:s}", + "tip_id", GNUNET_JSON_from_data_auto (&tip_id), + "tip_expiration", GNUNET_JSON_from_time_abs (expiration), + "exchange_uri", mi->tip_exchange); +} + +/* end of taler-merchant-httpd_tip-authorize.c */ diff --git a/src/backend/taler-merchant-httpd_tip-authorize.h b/src/backend/taler-merchant-httpd_tip-authorize.h new file mode 100644 index 00000000..b7c3b9a1 --- /dev/null +++ b/src/backend/taler-merchant-httpd_tip-authorize.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + (C) 2017 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU 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 backend/taler-merchant-httpd_tip-authorize.h + * @brief headers for /tip-authorize handler + * @author Christian Grothoff + */ +#ifndef TALER_MERCHANT_HTTPD_TIP_AUTHORIZE_H +#define TALER_MERCHANT_HTTPD_TIP_AUTHORIZE_H +#include <microhttpd.h> +#include "taler-merchant-httpd.h" + +/** + * Manages a /tip-authorize call, creating a TIP ID and storing the + * authorization in our DB. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] connection_cls the connection's closure (can be updated) + * @param upload_data upload data + * @param[in,out] upload_data_size number of bytes (left) in @a upload_data + * @return MHD result code + */ +int +MH_handler_tip_authorize (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size); + +#endif diff --git a/src/backend/taler-merchant-httpd_tip-enable.c b/src/backend/taler-merchant-httpd_tip-enable.c new file mode 100644 index 00000000..a96613e0 --- /dev/null +++ b/src/backend/taler-merchant-httpd_tip-enable.c @@ -0,0 +1,157 @@ +/* + This file is part of TALER + (C) 2014-2017 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 backend/taler-merchant-httpd_tip-enable.c + * @brief implement API for authorizing tips to be paid to visitors + * @author Christian Grothoff + */ +#include "platform.h" +#include <jansson.h> +#include <taler/taler_json_lib.h> +#include "taler-merchant-httpd.h" +#include "taler-merchant-httpd_mhd.h" +#include "taler-merchant-httpd_parsing.h" +#include "taler-merchant-httpd_exchanges.h" +#include "taler-merchant-httpd_responses.h" +#include "taler-merchant-httpd_tip-enable.h" + + +/** + * Information we keep for individual calls + * to requests that parse JSON, but keep no other state. + */ +struct TMH_JsonParseContext +{ + + /** + * This field MUST be first. + * FIXME: Explain why! + */ + struct TM_HandlerContext hc; + + /** + * Placeholder for #TMH_PARSE_post_json() to keep its internal state. + */ + void *json_parse_context; +}; + + +/** + * Custom cleanup routine for a `struct TMH_JsonParseContext`. + * + * @param hc the `struct TMH_JsonParseContext` to clean up. + */ +static void +json_parse_cleanup (struct TM_HandlerContext *hc) +{ + struct TMH_JsonParseContext *jpc = (struct TMH_JsonParseContext *) hc; + + TMH_PARSE_post_cleanup_callback (jpc->json_parse_context); + GNUNET_free (jpc); +} + + +/** + * Handle a "/tip-enable" request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] connection_cls the connection's closure (can be updated) + * @param upload_data upload data + * @param[in,out] upload_data_size number of bytes (left) in @a upload_data + * @return MHD result code + */ +int +MH_handler_tip_enable (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size) +{ + enum GNUNET_DB_QueryStatus qs; + int res; + struct TALER_Amount credit; + struct GNUNET_TIME_Absolute expiration; + struct TALER_ReservePrivateKeyP reserve_priv; + struct GNUNET_HashCode credit_uuid; + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_amount ("credit", &credit), + GNUNET_JSON_spec_absolute_time ("expiration", &expiration), + GNUNET_JSON_spec_fixed_auto ("reserve_priv", &reserve_priv), + GNUNET_JSON_spec_fixed_auto ("credit_uuid", &credit_uuid), + GNUNET_JSON_spec_end() + }; + struct TMH_JsonParseContext *ctx; + json_t *root; + + if (NULL == *connection_cls) + { + ctx = GNUNET_new (struct TMH_JsonParseContext); + ctx->hc.cc = &json_parse_cleanup; + *connection_cls = ctx; + } + else + { + ctx = *connection_cls; + } + res = TMH_PARSE_post_json (connection, + &ctx->json_parse_context, + upload_data, + upload_data_size, + &root); + if (GNUNET_SYSERR == res) + return MHD_NO; + /* the POST's body has to be further fetched */ + if ( (GNUNET_NO == res) || + (NULL == root) ) + return MHD_YES; + + res = TMH_PARSE_json_data (connection, + root, + spec); + json_decref (root); + if (GNUNET_YES != res) + { + GNUNET_break_op (0); + return (GNUNET_NO == res) ? MHD_YES : MHD_NO; + } + + qs = db->enable_tip_reserve (db->cls, + &reserve_priv, + &credit_uuid, + &credit, + expiration); + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); + return TMH_RESPONSE_reply_internal_error (connection, + TALER_EC_TIP_ENABLE_DB_TRANSACTION_ERROR, + "Database error approving tip"); + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + return TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:s}", + "status", "duplicate submission"); + } + return TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:s}", + "status", "ok"); +} + +/* end of taler-merchant-httpd_tip-enable.c */ diff --git a/src/backend/taler-merchant-httpd_tip-enable.h b/src/backend/taler-merchant-httpd_tip-enable.h new file mode 100644 index 00000000..2981ef4f --- /dev/null +++ b/src/backend/taler-merchant-httpd_tip-enable.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + (C) 2017 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU 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 backend/taler-merchant-httpd_tip-enable.h + * @brief headers for /tip-enable handler + * @author Christian Grothoff + */ +#ifndef TALER_MERCHANT_HTTPD_TIP_ENABLE_H +#define TALER_MERCHANT_HTTPD_TIP_ENABLE_H +#include <microhttpd.h> +#include "taler-merchant-httpd.h" + +/** + * Manages a /tip-enable call, storing information about the + * reserve. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] connection_cls the connection's closure (can be updated) + * @param upload_data upload data + * @param[in,out] upload_data_size number of bytes (left) in @a upload_data + * @return MHD result code + */ +int +MH_handler_tip_enable (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size); + +#endif diff --git a/src/backend/taler-merchant-httpd_tip-pickup.c b/src/backend/taler-merchant-httpd_tip-pickup.c new file mode 100644 index 00000000..982ec1f0 --- /dev/null +++ b/src/backend/taler-merchant-httpd_tip-pickup.c @@ -0,0 +1,44 @@ +/* + This file is part of TALER + (C) 2017 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU 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 backend/taler-merchant-httpd_tip-pickup.c + * @brief implementation of /tip-pickup handler + * @author Christian Grothoff + */ +#include <microhttpd.h> +#include "taler-merchant-httpd.h" + +/** + * Manages a /tip-pickup call, checking that the tip is authorized, + * and if so, returning the withdrawal permissions. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] connection_cls the connection's closure (can be updated) + * @param upload_data upload data + * @param[in,out] upload_data_size number of bytes (left) in @a upload_data + * @return MHD result code + */ +int +MH_handler_tip_pickup (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size) +{ + GNUNET_break (0); /* #5099: not implemented */ + return MHD_NO; +} diff --git a/src/backend/taler-merchant-httpd_tip-pickup.h b/src/backend/taler-merchant-httpd_tip-pickup.h new file mode 100644 index 00000000..da42eaa6 --- /dev/null +++ b/src/backend/taler-merchant-httpd_tip-pickup.h @@ -0,0 +1,44 @@ +/* + This file is part of TALER + (C) 2017 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU 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 backend/taler-merchant-httpd_tip-pickup.h + * @brief headers for /tip-pickup handler + * @author Christian Grothoff + */ +#ifndef TALER_MERCHANT_HTTPD_TIP_PICKUP_H +#define TALER_MERCHANT_HTTPD_TIP_PICKUP_H +#include <microhttpd.h> +#include "taler-merchant-httpd.h" + +/** + * Manages a /tip-pickup call, checking that the tip is authorized, + * and if so, returning the withdrawal permissions. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] connection_cls the connection's closure (can be updated) + * @param upload_data upload data + * @param[in,out] upload_data_size number of bytes (left) in @a upload_data + * @return MHD result code + */ +int +MH_handler_tip_pickup (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size); + +#endif diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h index a5e91f5f..072a00ec 100644 --- a/src/include/taler_merchantdb_plugin.h +++ b/src/include/taler_merchantdb_plugin.h @@ -427,7 +427,7 @@ struct TALER_MERCHANTDB_Plugin struct GNUNET_TIME_Absolute start_date, struct GNUNET_TIME_Absolute end_date, const struct TALER_MasterSignatureP *exchange_sig); - + /** * Find information about a transaction. @@ -443,7 +443,7 @@ struct TALER_MERCHANTDB_Plugin struct GNUNET_TIME_Absolute date, TALER_MERCHANTDB_TransactionCallback cb, void *cb_cls); - + /** * Find information about a transaction. @@ -480,7 +480,7 @@ struct TALER_MERCHANTDB_Plugin const struct TALER_MerchantPublicKeyP *merchant_pub, TALER_MERCHANTDB_CoinDepositCallback cb, void *cb_cls); - + /** * Lookup information about coin payments by h_contract_terms and coin. @@ -555,7 +555,7 @@ struct TALER_MERCHANTDB_Plugin const struct TALER_WireTransferIdentifierRawP *wtid, TALER_MERCHANTDB_ProofCallback cb, void *cb_cls); - + /** * Obtain information about wire fees charged by an exchange, @@ -584,7 +584,7 @@ struct TALER_MERCHANTDB_Plugin struct GNUNET_TIME_Absolute *end_date, struct TALER_MasterSignatureP *exchange_sig); - + /** * Function called when some backoffice staff decides to award or * increase the refund on an existing contract. @@ -624,6 +624,77 @@ struct TALER_MERCHANTDB_Plugin void *rc_cls); /** + * Add @a credit to a reserve to be used for tipping. Note that + * this function does not actually perform any wire transfers to + * credit the reserve, it merely tells the merchant backend that + * a reserve was topped up. This has to happen before tips can be + * authorized. + * + * @param cls closure, typically a connection to the db + * @param reserve_priv which reserve is topped up or created + * @param credit_uuid unique identifier for the credit operation + * @param credit how much money was added to the reserve + * @param expiration when does the reserve expire? + * @return transaction status, usually + * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT for success + * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if @a credit_uuid already known + */ + enum GNUNET_DB_QueryStatus + (*enable_tip_reserve)(void *cls, + const struct TALER_ReservePrivateKeyP *reserve_priv, + const struct GNUNET_HashCode *credit_uuid, + const struct TALER_Amount *credit, + struct GNUNET_TIME_Absolute expiration); + + + /** + * Authorize a tip over @a amount from reserve @a reserve_priv. Remember + * the authorization under @a tip_id for later, together with the + * @a justification. + * + * @param cls closure, typically a connection to the db + * @param justification why was the tip approved + * @param amount how high is the tip (with fees) + * @param reserve_priv which reserve is debited + * @param[out] expiration set to when the tip expires + * @param[out] tip_id set to the unique ID for the tip + * @return transaction status, + * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if reserve has insufficient funds, + * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT upon success + */ + enum GNUNET_DB_QueryStatus + (*authorize_tip)(void *cls, + const char *justification, + const struct TALER_Amount *amount, + const struct TALER_ReservePrivateKeyP *reserve_priv, + struct GNUNET_TIME_Absolute *expiration, + struct GNUNET_HashCode *tip_id); + + + /** + * Pickup a tip over @a amount using pickup id @a pickup_id. + * + * @param cls closure, typically a connection to the db + * @param amount how high is the amount picked up (with fees) + * @param tip_id the unique ID from the tip authorization + * @param pickup_id the unique ID identifying the pick up operation + * (to allow replays, hash over the coin envelope and denomination key) + * @param[out] reserve_priv which reserve key to use to sign + * @return taler error code + * #TALER_EC_TIP_PICKUP_ID_UNKNOWN if @a tip_id is unknown + * #TALER_EC_TIP_PICKUP_NO_FUNDS if @a tip_id has insufficient funds left + * #TALER_EC_TIP_PICKUP_DB_ERROR on database errors + * #TALER_EC_NONE upon success (@a reserve_priv was set) + */ + enum TALER_ErrorCode + (*pickup_tip)(void *cls, + const struct TALER_Amount *amount, + const struct GNUNET_HashCode *tip_id, + const struct GNUNET_HashCode *pickup_id, + struct TALER_ReservePrivateKeyP *reserve_priv); + + + /** * Roll back the current transaction of a database connection. * * @param cls the `struct PostgresClosure` with the plugin-specific state |