summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/Makefile.am4
-rw-r--r--src/backend/taler-merchant-httpd.c68
-rw-r--r--src/backend/taler-merchant-httpd_private-delete-reserves-ID.c100
-rw-r--r--src/backend/taler-merchant-httpd_private-delete-reserves-ID.h41
-rw-r--r--src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c307
-rw-r--r--src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h45
-rw-r--r--src/include/taler_merchantdb_plugin.h63
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