aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpriscilla <priscilla.huang@efrei.net>2023-01-23 08:25:49 -0500
committerpriscilla <priscilla.huang@efrei.net>2023-01-23 08:25:49 -0500
commit4ba9ffaaeef83a05964bee764c419d9006a6767d (patch)
tree3f8c3e4936d7391bbdfd99b909bcb9983d1e50f3
parent03ce25438c251820ff556c66f11b22659f7a896f (diff)
backend pending webhook
-rw-r--r--src/backend/#taler-merchant-httpd_private-post-webhooks.h#43
-rw-r--r--src/backend/taler-merchant-httpd_helper.c124
-rw-r--r--src/backend/taler-merchant-httpd_helper.h18
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-pay.c56
-rw-r--r--src/backend/taler-merchant-httpd_private-delete-pending-webhooks-ID.h41
-rw-r--r--src/backend/taler-merchant-httpd_private-get-pending-webhooks-ID.c91
-rw-r--r--src/backend/taler-merchant-httpd_private-get-pending-webhooks-ID.h41
-rw-r--r--src/backend/taler-merchant-httpd_private-patch-pending-webhooks-ID.c174
-rw-r--r--src/backend/taler-merchant-httpd_private-patch-pending-webhooks-ID.h43
-rw-r--r--src/backend/taler-merchant-httpd_private-post-pending-webhooks.c207
-rw-r--r--src/backend/taler-merchant-httpd_private-post-pending-webhooks.h43
-rw-r--r--src/backend/taler-merchant-httpd_private-post-templates.c4
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c12
-rw-r--r--src/backenddb/test_merchantdb.c2
-rw-r--r--src/include/taler_merchantdb_plugin.h5
-rw-r--r--src/testing/testing_api_cmd_post_using_templates.c3
16 files changed, 205 insertions, 702 deletions
diff --git a/src/backend/#taler-merchant-httpd_private-post-webhooks.h# b/src/backend/#taler-merchant-httpd_private-post-webhooks.h#
deleted file mode 100644
index fd73c9e7..00000000
--- a/src/backend/#taler-merchant-httpd_private-post-webhooks.h#
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- This file is part of TALER
- (C) 2022 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-post-webhooks.h
- * @brief implementing POST /webhooks request handling
- * @author Priscilla HUANG
- */
-#ifndef TALER_MERCHANT_HTTPD_PRIVATE_POST_WEBHOOKS_H
-#define TALER_MERCHANT_HTTPD_PRIVATE_POST_WEBHOOKS_H
-#include "taler-merchant-httpd.h"
-
-
-/**
- * Generate a webhook entry.
- *
- * @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_webhooks (const struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- struct TMH_HandlerContext *hc);
-
-#endif
diff --git a/src/backend/taler-merchant-httpd_helper.c b/src/backend/taler-merchant-httpd_helper.c
index 86ff37c3..4f117154 100644
--- a/src/backend/taler-merchant-httpd_helper.c
+++ b/src/backend/taler-merchant-httpd_helper.c
@@ -23,6 +23,8 @@
#include <taler/taler_util.h>
#include <taler/taler_json_lib.h>
#include "taler-merchant-httpd_helper.h"
+#include "../exchange/src/include/taler_templating_lib.h"
+
/**
* check @a payto_uris for well-formedness
@@ -496,3 +498,125 @@ TMH_uuid_from_string (const char *uuids,
&hc,
sizeof (*uuid));
}
+
+
+/**
+ * Closure for #trigger_webhook_cb.
+ *
+ * @param instance which is the instance we work with
+ * @param root JSON data to fill into the template
+ * @param rv, query of the TALER_TEMPLATEING_fill
+ */
+struct Trigger
+{
+ const char *instance;
+
+ const json_t *root;
+
+ enum GNUNET_DB_QueryStatus rv;
+
+};
+
+/**
+ * Typically called by `TMH_trigger_webhook`.
+ *
+ * @param[in,out] cls a `struct Trigger` with information about the webhook
+ * @param webhook_serial reference to the configured webhook template.
+ * @param event_type is the event/action of the webhook
+ * @param url to make request to
+ * @param http_method use for the webhook
+ * @param header_template of the webhook
+ * @param body_template of the webhook
+ */
+static void
+trigger_webhook_cb (void *cls,
+ uint64_t webhook_serial,
+ const char *event_type,
+ const char *url,
+ const char *http_method,
+ const char *header_template,
+ const char *body_template)
+{
+ struct Trigger *t = cls;
+ void *header = NULL;
+ void *body = NULL;
+ size_t header_size;
+ size_t body_size;
+
+ if (NULL != header_template)
+ {
+ int ret;
+
+ ret = TALER_TEMPLATING_fill (header_template,
+ t->root,
+ &header,
+ &header_size);
+ if (0 != ret)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Failed to expand webhook header template for webhook %llu (%d)\n",
+ (unsigned long long) webhook_serial,
+ ret);
+ t->rv = GNUNET_DB_STATUS_HARD_ERROR;
+ return;
+ }
+ GNUNET_assert ('\0' == ((const char *) header)[header_size-1]);
+ }
+ if (NULL != body_template)
+ {
+ int ret;
+ ret = TALER_TEMPLATING_fill (body_template,
+ t->root,
+ &body,
+ &body_size);
+ if (0 != ret)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Failed to expand webhook header template for webhook %llu (%d)\n",
+ (unsigned long long) webhook_serial,
+ ret);
+ t->rv = GNUNET_DB_STATUS_HARD_ERROR;
+ return;
+ }
+ GNUNET_assert ('\0' == ((const char *) body)[body_size-1]);
+ }
+ t->rv = TMH_db->insert_pending_webhook (TMH_db->cls,
+ t->instance,
+ webhook_serial,
+ url,
+ http_method,
+ header,
+ body);
+ free (header);
+ free (body);
+}
+
+
+/**
+ * TMH_trigger_webhook is a function that need to be use when someone
+ * pay. Merchant need to have a notification.
+ *
+ * @param instance that we need to send the webhook as a notification
+ * @param event of the webhook
+ * @param args argument of the function
+ */
+enum GNUNET_DB_QueryStatus
+TMH_trigger_webhook (const char *instance,
+ const char *event,
+ const json_t *args)
+{
+ struct Trigger t = {
+ .instance = instance,
+ .root = args
+ };
+ enum GNUNET_DB_QueryStatus qs;
+
+ qs = TMH_db->lookup_webhook_by_event (TMH_db->cls,
+ instance,
+ event,
+ &trigger_webhook_cb,
+ &t);
+ if (qs < 0)
+ return qs;
+ return t.rv;
+}
diff --git a/src/backend/taler-merchant-httpd_helper.h b/src/backend/taler-merchant-httpd_helper.h
index dae9caaf..5cee97cc 100644
--- a/src/backend/taler-merchant-httpd_helper.h
+++ b/src/backend/taler-merchant-httpd_helper.h
@@ -111,6 +111,7 @@ TMH_setup_wire_account (const char *payto_uri);
/**
* FIXME: document
*/
+
enum GNUNET_GenericReturnValue
TMH_check_auth_config (struct MHD_Connection *connection,
const json_t *jauth,
@@ -142,4 +143,21 @@ TMH_uuid_from_string (const char *uuids,
GNUNET_JSON_pack_allow_null ( \
GNUNET_JSON_pack_object_incref ("exchange_reply", (json_t *) (hr)->reply))
+
+
+/**
+ * TMH_trigger_webhook is a function that need to be use when someone
+ * pay. Merchant need to have a notification.
+ *
+ * @param instance that we need to send the webhook as a notification
+ * @param event of the webhook
+ * @param args argument of the function
+ */
+enum GNUNET_DB_QueryStatus
+TMH_trigger_webhook (const char *instance,
+ const char *action,
+ const json_t *args);
+
+
+
#endif
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
index ee748470..162ee97a 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -251,6 +251,11 @@ struct PayContext
struct MHD_Response *response;
/**
+ * Our contract (or NULL if not available).
+ */
+ json_t *contract_terms;
+
+ /**
* Placeholder for #TALER_MHD_parse_post_json() to keep its internal state.
*/
void *json_parse_context;
@@ -678,6 +683,11 @@ pay_context_cleanup (void *cls)
GNUNET_SCHEDULER_cancel (pc->timeout_task);
pc->timeout_task = NULL;
}
+ if (NULL != pc->contract_terms)
+ {
+ json_decref (pc->contract_terms);
+ pc->contract_terms = NULL;
+ }
abort_active_deposits (pc);
for (unsigned int i = 0; i<pc->coins_cnt; i++)
{
@@ -1035,7 +1045,7 @@ handle_batch_deposit_ok (struct ExchangeGroup *eg,
{
resume_pay_with_error (pc,
MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_SOFT_FAILURE,
+ TALER_EC_GENERIC_DB_SOFT_FAILURE,
"insert_deposit");
return;
}
@@ -1871,7 +1881,7 @@ check_payment_sufficient (struct PayContext *pc)
*
* @param pc context to trigger notification for
*/
-static void
+static enum GNUNET_DB_QueryStatus
trigger_payment_notification (struct PayContext *pc)
{
{
@@ -1916,6 +1926,9 @@ trigger_payment_notification (struct PayContext *pc)
NULL,
0);
}
+ return TMH_trigger_webhook (pc->hc->instance->settings.id,
+ "pay",
+ pc->contract_terms);
}
@@ -2101,7 +2114,26 @@ execute_pay_transaction (struct PayContext *pc)
TMH_OSF_CLAIMED | TMH_OSF_PAID,
pc->timestamp,
pc->order_serial);
-
+ {
+ enum GNUNET_DB_QueryStatus qs;
+
+ qs = trigger_payment_notification (pc);
+ if (qs < 0)
+ {
+ TMH_db->rollback (TMH_db->cls);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ {
+ execute_pay_transaction (pc);
+ return;
+ }
+ GNUNET_break (0);
+ resume_pay_with_error (pc,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_STORE_FAILED,
+ "failed to trigger webhooks");
+ return;
+ }
+ }
{
enum GNUNET_DB_QueryStatus qs;
@@ -2123,7 +2155,6 @@ execute_pay_transaction (struct PayContext *pc)
NULL);
return;
}
- trigger_payment_notification (pc);
}
generate_success_response (pc);
}
@@ -2509,13 +2540,17 @@ check_contract (struct PayContext *pc)
{
/* obtain contract terms */
enum GNUNET_DB_QueryStatus qs;
- json_t *contract_terms = NULL;
bool paid = false;
+ if (NULL != pc->contract_terms)
+ {
+ json_decref (pc->contract_terms);
+ pc->contract_terms = NULL;
+ }
qs = TMH_db->lookup_contract_terms (TMH_db->cls,
pc->hc->instance->settings.id,
pc->order_id,
- &contract_terms,
+ &pc->contract_terms,
&pc->order_serial,
&paid,
NULL);
@@ -2546,11 +2581,10 @@ check_contract (struct PayContext *pc)
}
/* hash contract (needed later) */
if (GNUNET_OK !=
- TALER_JSON_contract_hash (contract_terms,
+ TALER_JSON_contract_hash (pc->contract_terms,
&pc->h_contract_terms))
{
GNUNET_break (0);
- json_decref (contract_terms);
return (MHD_YES ==
TALER_MHD_reply_with_error (pc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
@@ -2572,12 +2606,11 @@ check_contract (struct PayContext *pc)
GNUNET_h2s (&pc->h_contract_terms.hash));
/* basic sanity check on the contract */
- if (NULL == json_object_get (contract_terms,
+ if (NULL == json_object_get (pc->contract_terms,
"merchant"))
{
/* invalid contract */
GNUNET_break (0);
- json_decref (contract_terms);
return (MHD_YES ==
TALER_MHD_reply_with_error (pc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
@@ -2626,11 +2659,10 @@ check_contract (struct PayContext *pc)
pc->minimum_age = 0;
res = TALER_MHD_parse_internal_json_data (pc->connection,
- contract_terms,
+ pc->contract_terms,
espec);
if (NULL != fulfillment_url)
pc->fulfillment_url = GNUNET_strdup (fulfillment_url);
- json_decref (contract_terms);
if (GNUNET_YES != res)
{
GNUNET_break (0);
diff --git a/src/backend/taler-merchant-httpd_private-delete-pending-webhooks-ID.h b/src/backend/taler-merchant-httpd_private-delete-pending-webhooks-ID.h
deleted file mode 100644
index f558ce4d..00000000
--- a/src/backend/taler-merchant-httpd_private-delete-pending-webhooks-ID.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- This file is part of TALER
- (C) 2023 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-pending-webhooks-ID.h
- * @brief implement DELETE /pending webhooks/$ID/
- * @author Priscilla HUANG
- */
-#ifndef TALER_MERCHANT_HTTPD_PRIVATE_DELETE_PENDING_WEBHOOKS_ID_H
-#define TALER_MERCHANT_HTTPD_PRIVATE_DELETE_PENDING_WEBHOOKS_ID_H
-
-#include "taler-merchant-httpd.h"
-
-
-/**
- * Handle a DELETE "/pending webhooks/$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_pending_webhooks_ID (const struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- struct TMH_HandlerContext *hc);
-
-/* end of taler-merchant-httpd_private-delete-pending-webhooks-ID.h */
-#endif
diff --git a/src/backend/taler-merchant-httpd_private-get-pending-webhooks-ID.c b/src/backend/taler-merchant-httpd_private-get-pending-webhooks-ID.c
deleted file mode 100644
index 7536b2f2..00000000
--- a/src/backend/taler-merchant-httpd_private-get-pending-webhooks-ID.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- This file is part of TALER
- (C) 2023 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-get-pending-webhooks-ID.c
- * @brief implement GET /pending webhooks/$ID
- * @author Priscilla HUANG
- */
-#include "platform.h"
-#include "taler-merchant-httpd_private-get-pending-webhooks-ID.h"
-#include <taler/taler_json_lib.h>
-
-
-/**
- * Handle a GET "/pending webhooks/$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_get_pending_webhooks_ID (const struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- struct TMH_HandlerContext *hc)
-{
- struct TMH_MerchantInstance *mi = hc->instance;
- struct TALER_MERCHANTDB_PendingWebhookDetails pwb = { 0 };
- enum GNUNET_DB_QueryStatus qs;
-
- GNUNET_assert (NULL != mi);
- qs = TMH_db->lookup_pending_webhook (TMH_db->cls,
- mi->settings.id,
- hc->infix,
- &pwb);
- if (0 > qs)
- {
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "lookup_pending_webhook");
- }
- if (0 == qs)
- {
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_MERCHANT_GENERIC_PENDING_WEBHOOK_UNKNOWN,
- hc->infix);
- }
- {
- MHD_RESULT ret;
-
- ret = TALER_MHD_REPLY_JSON_PACK (
- connection,
- MHD_HTTP_OK,
- GNUNET_JSON_pack_absolute ("next_attempt",
- pwb.next_attempt),
- GNUNET_JSON_pack_uint32 ("retries",
- pwb.retries),
- GNUNET_JSON_pack_string ("url",
- pwb.url),
- GNUNET_JSON_pack_string ("http_method",
- pwb.http_method),
- GNUNET_JSON_pack_string ("header",
- pwb.header),
- GNUNET_JSON_pack_string ("body"
- pwb.body));
- GNUNET_free (pwb.url);
- GNUNET_free (pwb.http_method);
- GNUNET_free (pwb.header_template);
- GNUNET_free (pwb.body_template);
-
- return ret;
- }
-}
-
-
-/* end of taler-merchant-httpd_private-get-webhooks-ID.c */
diff --git a/src/backend/taler-merchant-httpd_private-get-pending-webhooks-ID.h b/src/backend/taler-merchant-httpd_private-get-pending-webhooks-ID.h
deleted file mode 100644
index 6edd709e..00000000
--- a/src/backend/taler-merchant-httpd_private-get-pending-webhooks-ID.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- This file is part of TALER
- (C) 2023 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-get-pending-webhooks-ID.h
- * @brief implement GET /pending webhooks/$ID/
- * @author Priscilla HUANG
- */
-#ifndef TALER_MERCHANT_HTTPD_PRIVATE_GET_PENDING_WEBHOOKS_ID_H
-#define TALER_MERCHANT_HTTPD_PRIVATE_GET_PENDING_WEBHOOKS_ID_H
-
-#include "taler-merchant-httpd.h"
-
-
-/**
- * Handle a GET "/pending webhooks/$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_get_pending_webhooks_ID (const struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- struct TMH_HandlerContext *hc);
-
-/* end of taler-merchant-httpd_private-get-pending-webhooks-ID.h */
-#endif
diff --git a/src/backend/taler-merchant-httpd_private-patch-pending-webhooks-ID.c b/src/backend/taler-merchant-httpd_private-patch-pending-webhooks-ID.c
deleted file mode 100644
index 1a09c259..00000000
--- a/src/backend/taler-merchant-httpd_private-patch-pending-webhooks-ID.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- This file is part of TALER
- (C) 2023 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-patch-pending-webhooks-ID.c
- * @brief implementing PATCH /pending webhooks/$ID request handling
- * @author Priscilla HUANG
- */
-#include "platform.h"
-#include "taler-merchant-httpd_private-patch-pending-webhooks-ID.h"
-#include "taler-merchant-httpd_helper.h"
-#include <taler/taler_json_lib.h>
-
-/**
- * How often do we retry the simple INSERT database transaction?
- */
-#define MAX_RETRIES 3
-
-
-/**
- * Determine the cause of the PATCH failure in more detail and report.
- *
- * @param connection connection to report on
- * @param instance_id instance we are processing
- * @param webhook_serial ID of the pending webhook to patch
- * @param pwb webhook details we failed to set
- */
-static MHD_RESULT
-determine_cause (struct MHD_Connection *connection,
- const char *instance_id,
- uint64_t *webhook_serial,
- const struct TALER_MERCHANTDB_PendingWebhookDetails *pwb)
-{
- struct TALER_MERCHANTDB_PendingWebhookDetails wpx;
- enum GNUNET_DB_QueryStatus qs;
-
- qs = TMH_db->lookup_pending_webhook (TMH_db->cls,
- instance_id,
- webhook_serial,
- &wpx);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_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,
- "unexpected serialization problem");
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_MERCHANT_GENERIC_PENDING_WEBHOOK_UNKNOWN,
- webhook_id);
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- break; /* do below */
- }
-
- {
- enum TALER_ErrorCode ec;
-
- ec = TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
- TALER_MERCHANTDB_pending_webhook_details_free (&wpx);
- GNUNET_break (TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE != ec);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_CONFLICT,
- ec,
- NULL);
- }
-}
-
-/**
- * PATCH configuration of an existing instance, given its configuration.
- *
- * @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_patch_pending_webhooks_ID (const struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- struct TMH_HandlerContext *hc)
-{
- struct TMH_MerchantInstance *mi = hc->instance;
- uint64_t *webhook_serial = hc->infix;
- struct TALER_MERCHANTDB_PendingWebhookDetails pwb = {0};
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_absolute ("next_attempt",
- (&pwb.next_attempt),
- GNUNET_JSON_spec_end ()
- };
-
- GNUNET_assert (NULL != mi);
- GNUNET_assert (NULL != webhook_serial);
- {
- enum GNUNET_GenericReturnValue res;
-
- res = TALER_MHD_parse_json_data (connection,
- hc->request_body,
- spec);
- if (GNUNET_OK != res)
- return (GNUNET_NO == res)
- ? MHD_YES
- : MHD_NO;
- }
-
-
- qs = TMH_db->update_pending_webhook (TMH_db->cls,
- mi->settings.id,
- webhook_serial,
- &pwb);
- {
- MHD_RESULT ret = MHD_NO;
-
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_STORE_FAILED,
- NULL);
- break;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- GNUNET_break (0);
- ret = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
- "unexpected serialization problem");
- break;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- ret = determine_cause (connection,
- mi->settings.id,
- webhook_serial,
- &pwb);
- break;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- ret = TALER_MHD_reply_static (connection,
- MHD_HTTP_NO_CONTENT,
- NULL,
- NULL,
- 0);
- break;
- }
- GNUNET_JSON_parse_free (spec);
- return ret;
- }
-}
-
-
- /* end of taler-merchant-httpd_private-patch-pending-webhooks-ID.c */
diff --git a/src/backend/taler-merchant-httpd_private-patch-pending-webhooks-ID.h b/src/backend/taler-merchant-httpd_private-patch-pending-webhooks-ID.h
deleted file mode 100644
index 409fec9b..00000000
--- a/src/backend/taler-merchant-httpd_private-patch-pending-webhooks-ID.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- This file is part of TALER
- (C) 2023 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-patch-pending-webhooks-ID.h
- * @brief implementing PATCH /pending webhooks request handling
- * @author Priscilla HUANG
- */
-#ifndef TALER_MERCHANT_HTTPD_PRIVATE_PATCH_PENDING_WEBHOOKS_ID_H
-#define TALER_MERCHANT_HTTPD_PRIVATE_PATCH_PENDING_WEBHOOKS_ID_H
-#include "taler-merchant-httpd.h"
-
-
-/**
- * PATCH configuration of an existing instance, given its configuration.
- *
- * @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_patch_pending_webhooks_ID (const struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- struct TMH_HandlerContext *hc);
-
-#endif
diff --git a/src/backend/taler-merchant-httpd_private-post-pending-webhooks.c b/src/backend/taler-merchant-httpd_private-post-pending-webhooks.c
deleted file mode 100644
index 6115124f..00000000
--- a/src/backend/taler-merchant-httpd_private-post-pending-webhooks.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- This file is part of TALER
- (C) 2023 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-post-pending-webhooks.c
- * @brief implementing POST /pending webhooks request handling
- * @author Priscilla HUANG
- */
-#include "platform.h"
-#include "taler-merchant-httpd_private-post-webhooks.h"
-#include "taler-merchant-httpd_helper.h"
-#include <taler/taler_json_lib.h>
-
-/**
- * How often do we retry the simple INSERT database transaction?
- */
-#define MAX_RETRIES 3
-
-
-/**
- * Check if the two pending webhooks are identical.
- *
- * @param pw1 pending webhook to compare
- * @param pw2 other pending webhook to compare
- * @return true if they are 'equal', false if not or of payto_uris is not an array
- */
-static bool
-pending_webhooks_equal (const struct TALER_MERCHANTDB_PendingWebhookDetails *pw1,
- const struct TALER_MERCHANTDB_PendingWebhookDetails *pw2)
-{
- return ( (GNUNET_TIME_absolute_cmp (pw1->next_attempt,
- ==,
- pw2->next_attempt)) &&
- (pw1->retries == pw2->retries) &&
- (0 == strcmp (pw1->url,
- pw2->url)) &&
- (0 == strcmp (pw1->http_method,
- pw2->http_method)) &&
- (0 == strcmp (pw1->header,
- pw2->heade)) &&
- (0 == strcmp (pw1->body,
- pw2->body)));
-}
-
-
-MHD_RESULT
-TMH_private_post_pending_webhooks (const struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- struct TMH_HandlerContext *hc)
-{
- struct TMH_MerchantInstance *mi = hc->instance;
- struct TALER_MERCHANTDB_PendingWebhookDetails pwb = { 0 };
- uint64_t *webhook_serial;
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_uint64 ("webhook_serial",
- &webhook_serial),
- GNUNET_JSON_spec_absolute ("next_attempt",
- &pwb.next_attempt),
- GNUNET_JSON_spec_uint64 ("retries",
- &pwb.retries),
- GNUNET_JSON_spec_string ("url",
- (const char **) &wb.url),
- GNUNET_JSON_spec_string ("http_method",
- (const char **) &wb.http_method),
- GNUNET_JSON_spec_string ("header",
- (const char **) &wb.header),
- GNUNET_JSON_spec_string ("body",
- (const char **) &wb.body),
- GNUNET_JSON_spec_end ()
- };
-
- GNUNET_assert (NULL != mi);
- {
- enum GNUNET_GenericReturnValue res;
-
- res = TALER_MHD_parse_json_data (connection,
- hc->request_body,
- spec);
- if (GNUNET_OK != res)
- {
- GNUNET_break_op (0);
- return (GNUNET_NO == res)
- ? MHD_YES
- : MHD_NO;
- }
- }
-
-
-
- /* finally, interact with DB until no serialization error */
- for (unsigned int i = 0; i<MAX_RETRIES; i++)
- {
- /* Test if a pending webhook of this id is known */
- struct TALER_MERCHANTDB_PendingWebhooksDetails epwb;
-
- if (GNUNET_OK !=
- TMH_db->start (TMH_db->cls,
- "/post pending webhooks"))
- {
- GNUNET_break (0);
- GNUNET_JSON_parse_free (spec);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_START_FAILED,
- NULL);
- }
- qs = TMH_db->lookup_pending_webhook (TMH_db->cls,
- mi->settings.id,
- webhook_serial,
- &ewb);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- /* Clean up and fail hard */
- GNUNET_break (0);
- TMH_db->rollback (TMH_db->cls);
- GNUNET_JSON_parse_free (spec);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- NULL);
- case GNUNET_DB_STATUS_SOFT_ERROR:
- /* restart transaction */
- goto retry;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- /* Good, we can proceed! */
- break;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- /* idempotency check: is ewb == wb? */
- {
- bool eq;
-
- eq = pending_webhooks_equal (&pwb,
- &epwb);
- TALER_MERCHANTDB_pending_webhook_details_free(&epwb);
- TMH_db->rollback (TMH_db->cls);
- GNUNET_JSON_parse_free (spec);
- return eq
- ? TALER_MHD_reply_static (connection,
- MHD_HTTP_NO_CONTENT,
- NULL,
- NULL,
- 0)
- : TALER_MHD_reply_with_error (connection,
- MHD_HTTP_CONFLICT,
- TALER_EC_MERCHANT_PRIVATE_POST_PENDING_WEBHOOKS_CONFLICT_PENDING_WEBHOOKS_EXISTS,
- webhook_serial
- }
- } /* end switch (qs) */
-
- qs = TMH_db->insert_pending_webhook (TMH_db->cls,
- mi->settings.id,
- webhook_serial,
- &pwb);
- if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- {
- TMH_db->rollback (TMH_db->cls);
- break;
- }
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
- {
- qs = TMH_db->commit (TMH_db->cls);
- if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
- break;
- }
-retry:
- GNUNET_assert (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- TMH_db->rollback (TMH_db->cls);
- } /* for RETRIES loop */
- GNUNET_JSON_parse_free (spec);
- if (qs < 0)
- {
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (
- connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- (GNUNET_DB_STATUS_SOFT_ERROR == qs)
- ? TALER_EC_GENERIC_DB_SOFT_FAILURE
- : TALER_EC_GENERIC_DB_COMMIT_FAILED,
- NULL);
- }
- return TALER_MHD_reply_static (connection,
- MHD_HTTP_NO_CONTENT,
- NULL,
- NULL,
- 0);
-}
-
-
- /* end of taler-merchant-httpd_private-post-pending-webhooks.c */
diff --git a/src/backend/taler-merchant-httpd_private-post-pending-webhooks.h b/src/backend/taler-merchant-httpd_private-post-pending-webhooks.h
deleted file mode 100644
index 0bf317b7..00000000
--- a/src/backend/taler-merchant-httpd_private-post-pending-webhooks.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- This file is part of TALER
- (C) 2023 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-post-pending-webhooks.h
- * @brief implementing POST /pending webhooks request handling
- * @author Priscilla HUANG
- */
-#ifndef TALER_MERCHANT_HTTPD_PRIVATE_POST_PENDING_WEBHOOKS_H
-#define TALER_MERCHANT_HTTPD_PRIVATE_POST_PENDING_WEBHOOKS_H
-#include "taler-merchant-httpd.h"
-
-
-/**
- * Generate a pending webhook entry.
- *
- * @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_pending_webhooks (const struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- struct TMH_HandlerContext *hc);
-
-#endif
diff --git a/src/backend/taler-merchant-httpd_private-post-templates.c b/src/backend/taler-merchant-httpd_private-post-templates.c
index 8377b034..1dd324e4 100644
--- a/src/backend/taler-merchant-httpd_private-post-templates.c
+++ b/src/backend/taler-merchant-httpd_private-post-templates.c
@@ -194,8 +194,8 @@ TMH_private_post_templates (const struct TMH_RequestHandler *rh,
if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
break;
}
-retry:
- GNUNET_assert (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+retry:
+ GNUNET_assert (GNUNET_DB_STATUS_SOFT_ERROR == qs);
TMH_db->rollback (TMH_db->cls);
} /* for RETRIES loop */
GNUNET_JSON_parse_free (spec);
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index 230417e7..e87021ea 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -7773,7 +7773,7 @@ postgres_lookup_all_webhooks (void *cls,
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_string (instance_id),
GNUNET_PQ_query_param_uint64 (&min_row),
- GNUNET_PQ_query_param_uint64 (&max_results64),
+ GNUNET_PQ_query_param_uint64 (&max_results64),
GNUNET_PQ_query_param_end
};
@@ -7800,16 +7800,24 @@ postgres_lookup_all_webhooks (void *cls,
* @param next_attempt when we should make the next request to the webhook
* @return database result code
*/
+<<<<<<< HEAD
static enum GNUNET_DB_QueryStatus
postgres_update_pending_webhook (void *cls,
uint64_t webhook_serial,
struct GNUNET_TIME_Absolute next_attempt)
// maybe add: http status of failure?
+=======
+ static enum GNUNET_DB_QueryStatus
+ postgres_update_pending_webhook(void *cls,
+ uint64_t webhook_serial,
+ const struct TALER_MERCHANTDB_PendingWebhookDetails *pwb)
+ // maybe add: http status of failure?
+>>>>>>> ee56051c (backend for pending webhook)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_uint64 (&webhook_serial),
- GNUNET_PQ_query_param_absolute_time (&next_attempt),
+ GNUNET_PQ_query_param_absolute_time (&pwb->next_attempt),
GNUNET_PQ_query_param_end
};
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
index 69a376aa..cbf4e4b6 100644
--- a/src/backenddb/test_merchantdb.c
+++ b/src/backenddb/test_merchantdb.c
@@ -7909,7 +7909,7 @@ test_update_pending_webhook (const struct InstanceData *instance,
TEST_COND_RET_ON_FAIL (expected_result ==
plugin->update_pending_webhook (plugin->cls,
pwebhook->webhook_serial,
- pwebhook->pwebhook.next_attempt),
+ &pwebhook->pwebhook),
"Update pending webhook failed\n");
return 0;
}
diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h
index 707cf2d9..54432e52 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -2828,8 +2828,13 @@ struct TALER_MERCHANTDB_Plugin
enum GNUNET_DB_QueryStatus
(*update_pending_webhook)(void *cls,
uint64_t webhook_serial,
+<<<<<<< HEAD
struct GNUNET_TIME_Absolute next_attempt);
// maybe add: http status of failure?
+=======
+ const struct TALER_MERCHANTDB_PendingWebhookDetails *pwb);
+ // maybe add: http status of failure?
+>>>>>>> ee56051c (backend for pending webhook)
/**
diff --git a/src/testing/testing_api_cmd_post_using_templates.c b/src/testing/testing_api_cmd_post_using_templates.c
index 137c7df1..956a421a 100644
--- a/src/testing/testing_api_cmd_post_using_templates.c
+++ b/src/testing/testing_api_cmd_post_using_templates.c
@@ -209,8 +209,7 @@ TALER_TESTING_cmd_merchant_post_using_templates (
const char *template_ref,
const char *merchant_url,
const char *summary,
- const char *amount,
- unsigned int http_status)
+ const char *amount, unsigned int http_status)
{
struct PostUsingTemplatesState *tis;