diff options
-rw-r--r-- | src/backend/Makefile.am | 4 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd.c | 68 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_private-delete-reserves-ID.c | 100 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_private-delete-reserves-ID.h | 41 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c | 307 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h | 45 | ||||
-rw-r--r-- | src/include/taler_merchantdb_plugin.h | 63 |
7 files changed, 371 insertions, 257 deletions
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index b493e3a1..16b6ea60 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -31,6 +31,8 @@ taler_merchant_httpd_SOURCES = \ taler-merchant-httpd_private-delete-products-ID.h \ taler-merchant-httpd_private-delete-orders-ID.c \ 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-get-instances.c \ taler-merchant-httpd_private-get-instances.h \ taler-merchant-httpd_private-get-instances-ID.c \ @@ -57,6 +59,8 @@ taler_merchant_httpd_SOURCES = \ taler-merchant-httpd_private-post-products-ID-lock.h \ taler-merchant-httpd_private-post-reserves.c \ taler-merchant-httpd_private-post-reserves.h \ + taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c \ + taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h \ taler-merchant-httpd_private-post-orders-ID-refund.c \ taler-merchant-httpd_private-post-orders-ID-refund.h \ taler-merchant-httpd_private-post-orders.c \ diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index 32732bd9..7f063909 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -32,6 +32,7 @@ #include "taler-merchant-httpd_private-delete-instances-ID.h" #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-get-instances.h" #include "taler-merchant-httpd_private-get-instances-ID.h" #include "taler-merchant-httpd_private-get-products.h" @@ -48,6 +49,7 @@ #include "taler-merchant-httpd_private-post-products.h" #include "taler-merchant-httpd_private-post-products-ID-lock.h" #include "taler-merchant-httpd_private-post-reserves.h" +#include "taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h" #include "taler-merchant-httpd_private-post-transfers.h" #include "taler-merchant-httpd_post-orders-ID-abort.h" #include "taler-merchant-httpd_post-orders-ID-claim.h" @@ -841,6 +843,28 @@ url_handler (void *cls, .method = MHD_HTTP_METHOD_POST, .handler = &TMH_private_post_reserves }, + /* DELETE /reserves/$ID: */ + { + .url_prefix = "/reserves", + .have_id_segment = true, + .method = MHD_HTTP_METHOD_DELETE, + .handler = &TMH_private_delete_reserves_ID + }, + /* POST /reserves/$ID/authorize-tip: */ + { + .url_prefix = "/reserves", + .url_suffix = "authorize-tip", + .have_id_segment = true, + .method = MHD_HTTP_METHOD_POST, + .handler = &TMH_private_post_reserves_ID_authorize_tip + }, + /* POST /reserves/authorize-tip: */ + { + .url_prefix = "/reserves", + .url_suffix = "authorize-tip", + .method = MHD_HTTP_METHOD_POST, + .handler = &TMH_private_post_reserves_authorize_tip + }, /* GET /reserves: */ { .url_prefix = "/reserves", @@ -1111,18 +1135,35 @@ url_handler (void *cls, rh->url_prefix, prefix_strlen)) ) continue; - if ( (NULL == infix_url) - ^ (GNUNET_NO == rh->have_id_segment) ) - continue; /* infix existence missmatch */ - if ( ( (NULL == suffix_url) - ^ (NULL == rh->url_suffix) ) ) - continue; /* suffix existence missmatch */ - if ( (NULL != suffix_url) && - ( (suffix_strlen != strlen (rh->url_suffix)) || - (0 != memcmp (suffix_url, - rh->url_suffix, - suffix_strlen)) ) ) - continue; /* suffix content missmatch */ + if (GNUNET_NO == rh->have_id_segment) + { + if (NULL != suffix_url) + continue; /* too many segments to match */ + if ( (NULL == infix_url) + ^ (NULL == rh->url_suffix) ) + continue; /* suffix existence missmatch */ + if ( (NULL != infix_url) && + ( (infix_strlen != strlen (rh->url_suffix)) || + (0 != memcmp (infix_url, + rh->url_suffix, + infix_strlen)) ) ) + continue; /* cannot use infix as suffix: content missmatch */ + } + else + { + if ( (NULL == infix_url) + ^ (GNUNET_NO == rh->have_id_segment) ) + continue; /* infix existence missmatch */ + if ( ( (NULL == suffix_url) + ^ (NULL == rh->url_suffix) ) ) + continue; /* suffix existence missmatch */ + if ( (NULL != suffix_url) && + ( (suffix_strlen != strlen (rh->url_suffix)) || + (0 != memcmp (suffix_url, + rh->url_suffix, + suffix_strlen)) ) ) + continue; /* suffix content missmatch */ + } url_found = true; if (0 == strcasecmp (method, MHD_HTTP_METHOD_OPTIONS)) @@ -1130,7 +1171,8 @@ url_handler (void *cls, return TALER_MHD_reply_cors_preflight (connection); } if ( (rh->method != NULL) && - (0 != strcasecmp (method, rh->method)) ) + (0 != strcasecmp (method, + rh->method)) ) continue; hc->rh = rh; break; diff --git a/src/backend/taler-merchant-httpd_private-delete-reserves-ID.c b/src/backend/taler-merchant-httpd_private-delete-reserves-ID.c new file mode 100644 index 00000000..ba2c08be --- /dev/null +++ b/src/backend/taler-merchant-httpd_private-delete-reserves-ID.c @@ -0,0 +1,100 @@ +/* + This file is part of TALER + (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 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_private-delete-reserves-ID.c + * @brief implement DELETE /reserves/$ID + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler-merchant-httpd_private-delete-reserves-ID.h" +#include <taler/taler_json_lib.h> + + +/** + * Handle a DELETE "/reserves/$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_reserves_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; + struct TALER_ReservePublicKeyP reserve_pub; + const char *purge; + + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (hc->infix, + strlen (hc->infix), + &reserve_pub, + sizeof (reserve_pub))) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_RESERVES_INVALID_RESERVE_PUB, + "reserve public key malformed"); + } + purge = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "purge"); + GNUNET_assert (NULL != mi); + if ( (NULL != purge) && + (0 == strcmp (purge, + "yes")) ) + qs = TMH_db->purge_reserve (TMH_db->cls, + mi->settings.id, + &reserve_pub); + else + qs = TMH_db->delete_reserve (TMH_db->cls, + mi->settings.id, + &reserve_pub); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_RESERVES_DELETE_DB_HARD_FAILURE, + "Transaction failed"); + case GNUNET_DB_STATUS_SOFT_ERROR: + GNUNET_break (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_INTERNAL_INVARIANT_FAILURE, + "Serialization error for single SQL statement"); + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_RESERVES_DELETE_NO_SUCH_RESERVE, + "Reserve unknown"); + 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-reserves-ID.c */ diff --git a/src/backend/taler-merchant-httpd_private-delete-reserves-ID.h b/src/backend/taler-merchant-httpd_private-delete-reserves-ID.h new file mode 100644 index 00000000..b961d0d7 --- /dev/null +++ b/src/backend/taler-merchant-httpd_private-delete-reserves-ID.h @@ -0,0 +1,41 @@ +/* + 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 backend/taler-merchant-httpd_private-delete-reserves-ID.h + * @brief implement DELETE /reserves/$ID/ + * @author Christian Grothoff + */ +#ifndef TALER_MERCHANT_HTTPD_PRIVATE_DELETE_RESERVES_ID_H +#define TALER_MERCHANT_HTTPD_PRIVATE_DELETE_RESERVES_ID_H + +#include "taler-merchant-httpd.h" + + +/** + * Handle a DELETE "/reserves/$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_reserves_ID (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc); + +/* end of taler-merchant-httpd_private-delete-reserves-ID.h */ +#endif diff --git a/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c b/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c index a0f2ec3f..91936699 100644 --- a/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c +++ b/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2014-2017 Taler Systems SA + (C) 2014-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 @@ -14,7 +14,7 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ /** - * @file backend/taler-merchant-httpd_tip-authorize.c + * @file backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c * @brief implement API for authorizing tips to be paid to visitors * @author Christian Grothoff */ @@ -24,149 +24,41 @@ #include <taler/taler_json_lib.h> #include "taler-merchant-httpd.h" #include "taler-merchant-httpd_mhd.h" -#include "taler-merchant-httpd_exchanges.h" -#include "taler-merchant-httpd_tip-authorize.h" -#include "taler-merchant-httpd_tip-reserve-helper.h" - - -struct TipAuthContext -{ - /** - * This field MUST be first for handle_mhd_completion_callback() to work - * when it treats this struct as a `struct TM_HandlerContext`. - */ - struct TM_HandlerContext hc; - - /** - * Placeholder for #TALER_MHD_parse_post_json() to keep its internal state. - */ - void *json_parse_context; - - /** - * Justification to use. - */ - const char *justification; - - /** - * JSON request received. - */ - json_t *root; - - /** - * Context for checking the tipping reserve's status. - */ - struct TMH_CheckTipReserve ctr; - - /** - * Tip amount requested. - */ - struct TALER_Amount amount; - - /** - * Flag set to #GNUNET_YES when we have tried /reserve/status of the - * tipping reserve already. - */ - int checked_status; - - /** - * Flag set to #GNUNET_YES when we have parsed the incoming JSON already. - */ - int parsed_json; - -}; +#include "taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h" /** - * Custom cleanup routine for a `struct TipAuthContext`. - * - * @param hc the `struct TMH_JsonParseContext` to clean up. - */ -static void -cleanup_tac (struct TM_HandlerContext *hc) -{ - struct TipAuthContext *tac = (struct TipAuthContext *) hc; - - if (NULL != tac->root) - { - json_decref (tac->root); - tac->root = NULL; - } - TMH_check_tip_reserve_cleanup (&tac->ctr); - TALER_MHD_parse_post_cleanup_callback (tac->json_parse_context); - GNUNET_free (tac); -} - - -/** - * Handle a "/tip-authorize" request. + * 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 - * @param mi merchant backend instance, never NULL + * @param[in,out] hc context with further information about the request + * @param reserve_pub reserve to use, or NULL for "any" * @return MHD result code */ -MHD_RESULT -MH_handler_tip_authorize (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - struct MerchantInstance *mi) +static MHD_RESULT +authorize_tip (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc, + const struct TALER_ReservePublicKeyP *reserve_pub) { - struct TipAuthContext *tac; - enum GNUNET_GenericReturnValue res; enum TALER_ErrorCode ec; struct GNUNET_TIME_Absolute expiration; struct GNUNET_HashCode tip_id; - json_t *extra; - - if (NULL == *connection_cls) - { - tac = GNUNET_new (struct TipAuthContext); - tac->hc.cc = &cleanup_tac; - tac->ctr.connection = connection; - *connection_cls = tac; - } - else - { - tac = *connection_cls; - } - if (NULL != tac->ctr.response) - { - MHD_RESULT ret; - - ret = MHD_queue_response (connection, - tac->ctr.response_code, - tac->ctr.response); - MHD_destroy_response (tac->ctr.response); - tac->ctr.response = NULL; - return ret; - } - if (GNUNET_NO == tac->parsed_json) + const char *justification; + const char *next_url; + struct TALER_Amount amount; { struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_amount ("amount", &tac->amount), - GNUNET_JSON_spec_string ("justification", &tac->justification), + TALER_JSON_spec_amount ("amount", &amount), + GNUNET_JSON_spec_string ("justification", &justification), + GNUNET_JSON_spec_string ("next_url", &next_url), GNUNET_JSON_spec_end () }; - - res = TALER_MHD_parse_post_json (connection, - &tac->json_parse_context, - upload_data, - upload_data_size, - &tac->root); - if (GNUNET_SYSERR == res) - return MHD_NO; - /* the POST's body has to be further fetched */ - if ( (GNUNET_NO == res) || - (NULL == tac->root) ) - return MHD_YES; + enum GNUNET_GenericReturnValue res; res = TALER_MHD_parse_json_data (connection, - tac->root, + hc->request_body, spec); if (GNUNET_YES != res) { @@ -175,51 +67,17 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh, ? MHD_YES : MHD_NO; } - tac->parsed_json = GNUNET_YES; - } - - if (NULL == mi->tip_exchange) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Instance `%s' not configured for tipping\n", - mi->id); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_PRECONDITION_FAILED, - TALER_EC_TIP_AUTHORIZE_INSTANCE_DOES_NOT_TIP, - "exchange for tipping not configured for the instance"); - } - tac->ctr.reserve_priv = mi->tip_reserve; - extra = json_object_get (tac->root, "extra"); - if (NULL == extra) - extra = json_object (); - else - json_incref (extra); - - - db->preflight (db->cls); - ec = db->authorize_tip_TR (db->cls, - tac->justification, - extra, - &tac->amount, - &mi->tip_reserve, - mi->tip_exchange, - &expiration, - &tip_id); - json_decref (extra); - /* If we have insufficient funds according to OUR database, - check with exchange to see if the reserve has been topped up - in the meantime (or if tips were not withdrawn yet). */ - if ( (TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS == ec) && - (GNUNET_NO == tac->checked_status) ) - { - tac->checked_status = GNUNET_YES; - tac->ctr.none_authorized = GNUNET_YES; - TMH_check_tip_reserve (&tac->ctr, - mi->tip_exchange); - return MHD_YES; } - - /* handle irrecoverable errors */ + TMH_db->preflight (TMH_db->cls); + ec = TMH_db->authorize_tip (TMH_db->cls, + hc->instance->settings.id, + reserve_pub, + &amount, + justification, + next_url, + &tip_id, + &expiration); + /* handle errors */ if (TALER_EC_NONE != ec) { unsigned int rc; @@ -233,7 +91,7 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh, break; case TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED: msg = "Failed to approve tip: merchant's tipping reserve expired"; - rc = MHD_HTTP_PRECONDITION_FAILED; + rc = MHD_HTTP_GONE; break; case TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN: msg = "Failed to approve tip: merchant's tipping reserve does not exist"; @@ -257,21 +115,21 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh, const char *host; const char *forwarded_host; const char *uri_path; - const char *uri_instance_id; struct GNUNET_CRYPTO_HashAsciiEncoded hash_enc; + MHD_RESULT res; - host = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, "Host"); - forwarded_host = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, + host = MHD_lookup_connection_value (connection, + MHD_HEADER_KIND, + "Host"); + forwarded_host = MHD_lookup_connection_value (connection, + MHD_HEADER_KIND, "X-Forwarded-Host"); - uri_path = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, + uri_path = MHD_lookup_connection_value (connection, + MHD_HEADER_KIND, "X-Forwarded-Prefix"); - if (NULL == uri_path) - uri_path = "-"; - if (NULL != forwarded_host) host = forwarded_host; - if (NULL == host) { /* Should never happen, at last the host header should be defined */ @@ -282,27 +140,84 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh, "unable to identify backend host"); } - if (0 == strcmp (mi->id, "default")) - uri_instance_id = "-"; - else - uri_instance_id = mi->id; - - GNUNET_CRYPTO_hash_to_enc (&tip_id, &hash_enc); - + GNUNET_CRYPTO_hash_to_enc (&tip_id, + &hash_enc); GNUNET_assert (0 < GNUNET_asprintf (&taler_tip_uri, - "taler://tip/%s/%s/%s/%s", + "taler://tip/%s/%s%sinstances/%s/%s", host, - uri_path, - uri_instance_id, + (NULL == uri_path) ? "" : uri_path, + (NULL == uri_path) ? "" : "/", + hc->instance->settings.id, hash_enc.encoding)); + res = TALER_MHD_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:s, s:s, s:o}", + "tip_id", + hash_enc.encoding, + "tip_redirect_url", + taler_tip_uri, + "tip_expiration", + GNUNET_JSON_from_time_abs (expiration)); + GNUNET_free (taler_tip_uri); + return res; + } +} + - return TALER_MHD_reply_json_pack (connection, - MHD_HTTP_OK, - "{s:s, s:s}", - "taler_tip_uri", taler_tip_uri, - "tip_id", hash_enc.encoding); +/** + * Handle a "/reserves/$ID/tip-authorize" 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_post_reserves_ID_authorize_tip (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + struct TALER_ReservePublicKeyP reserve_pub; + + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (hc->infix, + strlen (hc->infix), + &reserve_pub, + sizeof (reserve_pub))) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_RESERVES_INVALID_RESERVE_PUB, + "reserve public key malformed"); } + return authorize_tip (rh, + connection, + hc, + &reserve_pub); +} + + +/** + * Handle a "/reserves/tip-authorize" request. + * Here the client does not specify the reserve public key, so we + * are free to pick "any" available reserve. + * + * @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_post_reserves_authorize_tip (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + return authorize_tip (rh, + connection, + hc, + NULL); } -/* end of taler-merchant-httpd_tip-authorize.c */ +/* end of taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c */ diff --git a/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h b/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h index 1f7f44ea..2df55295 100644 --- a/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h +++ b/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2017 Taler Systems SA + (C) 2017, 2020 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 @@ -14,33 +14,44 @@ 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 + * @file backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h + * @brief headers for /reserves/ID/tip-authorize * @author Christian Grothoff */ -#ifndef TALER_MERCHANT_HTTPD_TIP_AUTHORIZE_H -#define TALER_MERCHANT_HTTPD_TIP_AUTHORIZE_H +#ifndef TALER_MERCHANT_HTTPD_PRIVATE_POST_RESERVES_ID_AUTHORIZE_TIP_H +#define TALER_MERCHANT_HTTPD_PRIVATE_POST_RESERVES_ID_AUTHORIZE_TIP_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. + * Handle a "/reserves/$ID/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 - * @param mi merchant backend instance, never NULL + * @param[in,out] hc context with further information about the request * @return MHD result code */ MHD_RESULT -MH_handler_tip_authorize (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size, - struct MerchantInstance *mi); +TMH_private_post_reserves_ID_authorize_tip (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc); + + +/** + * Handle a "/reserves/tip-authorize" request. + * Here the client does not specify the reserve public key, so we + * are free to pick "any" available reserve. + * + * @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_post_reserves_authorize_tip (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc); + #endif diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h index b51fce8d..0960fb93 100644 --- a/src/include/taler_merchantdb_plugin.h +++ b/src/include/taler_merchantdb_plugin.h @@ -1630,6 +1630,38 @@ struct TALER_MERCHANTDB_Plugin const struct TALER_ReservePublicKeyP *reserve_pub); + /** + * Authorize a tip over @a amount from reserve @a reserve_pub. Remember + * the authorization under @a tip_id for later, together with the + * @a justification. + * + * @param cls closure, typically a connection to the db + * @param instance_id which instance should generate the tip + * @param reserve_pub which reserve is debited, NULL to pick one in the DB + * @param amount how high is the tip (with fees) + * @param justification why was the tip approved + * @param next_url where to send the URL post tip pickup + * @param[out] tip_id set to the unique ID for the tip + * @param[out] expiration set to when the tip expires + * @return transaction status, + * #TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED if the reserve is known but has expired + * #TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN if the reserve is not known + * #TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS if the reserve has insufficient funds left + * #TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR on hard DB errors + * #TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR on soft DB errors (client should retry) + * #TALER_EC_NONE upon success + */ + enum TALER_ErrorCode + (*authorize_tip)(void *cls, + const char *instance_id, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_Amount *amount, + const char *justification, + const char *next_url, + struct GNUNET_HashCode *tip_id, + struct GNUNET_TIME_Absolute *expiration); + + /* ****************** OLD API ******************** */ @@ -1899,37 +1931,6 @@ struct TALER_MERCHANTDB_Plugin /** - * 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 extra extra data that will be given to the customer's wallet - * @param amount how high is the tip (with fees) - * @param reserve_priv which reserve is debited - * @param exchange_url which exchange manages the tip - * @param[out] expiration set to when the tip expires - * @param[out] tip_id set to the unique ID for the tip - * @return transaction status, - * #TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED if the reserve is known but has expired - * #TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN if the reserve is not known - * #TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS if the reserve has insufficient funds left - * #TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR on hard DB errors - * #TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR on soft DB errors (client should retry) - * #TALER_EC_NONE upon success - */ - enum TALER_ErrorCode - (*authorize_tip_TR)(void *cls, - const char *justification, - const json_t *extra, - const struct TALER_Amount *amount, - const struct TALER_ReservePrivateKeyP *reserve_priv, - const char *exchange_url, - struct GNUNET_TIME_Absolute *expiration, - struct GNUNET_HashCode *tip_id); - - /** * Get the total amount of authorized tips for a tipping reserve. * * @param cls closure, typically a connection to the db |