summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorpriscilla <priscilla.huang@efrei.net>2022-12-21 06:20:06 -0500
committerpriscilla <priscilla.huang@efrei.net>2022-12-21 06:21:23 -0500
commitab04b2ce37299a40d48adee29192648a7667d4d9 (patch)
tree4be6bd53a51d5ff65d7b9ddce3cd6248f81a3f16 /src/backend
parent86323f313cb09a9665ecb035da8e9d560e7a5542 (diff)
downloadmerchant-ab04b2ce37299a40d48adee29192648a7667d4d9.tar.gz
merchant-ab04b2ce37299a40d48adee29192648a7667d4d9.tar.bz2
merchant-ab04b2ce37299a40d48adee29192648a7667d4d9.zip
POST using template
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/taler-merchant-httpd_post-using-templates.c249
-rw-r--r--src/backend/taler-merchant-httpd_post-using-templates.h2
2 files changed, 199 insertions, 52 deletions
diff --git a/src/backend/taler-merchant-httpd_post-using-templates.c b/src/backend/taler-merchant-httpd_post-using-templates.c
index 7e8a2a59..239549c0 100644
--- a/src/backend/taler-merchant-httpd_post-using-templates.c
+++ b/src/backend/taler-merchant-httpd_post-using-templates.c
@@ -28,64 +28,211 @@
#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
+
+
MHD_RESULT
-TMH_private_post_using_templates ( struct MHD_Connection *connection,
- struct TMH_HandlerContext *hc)
+TMH_post_using_templates_ID (struct MHD_Connection *connection,
+ struct TMH_HandlerContext *hc)
{
+ struct TMH_MerchantInstance *mi = hc->instance;
MHD_RESULT mret;
- struct TALER_MERCHANTDB_TemplateDetails tp = { 0 };
- const char *template_id = NULL;
- const char *subject = NULL;
- const char *taler_url = NULL;
+ const char *template_id = hc->infix;
+ const char *summary = NULL;
+ const char *fulfillment_url = NULL;
+ const char *fulfillment_message = NULL;
struct TALER_Amount amount;
+ bool no_amount;
+ json_t *fake_body;
+ bool no_summary;
+ struct TALER_MERCHANTDB_TemplateDetails etp;
- //template data + POST argument data to handler
- json_t *fake_body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("template_id",
- template_id),
- GNUNET_JSON_pack_string ("template_description",
- tp.template_description),
- GNUNET_JSON_pack_string ("image",
- tp.image),
- GNUNET_JSON_pack_object_incref ("template_contract",
- tp.template_contract),
- GNUNET_JSON_pack_allow_null (
- TALER_JSON_pack_amount ("amount",
- &amount)),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string ("subject",
- subject)),
- GNUNET_JSON_pack_string ("taler_url",
- taler_url)
- );
-
- //Verification that the variable have the right form
- if (NULL == tp.template_contract)
- tp.template_contract = json_object ();
-
-
- if (! TMH_template_contract_valid (tp.template_contract))
- {
- GNUNET_break_op (0);
- json_decref (fake_body);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "template_contract");
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_string ("summary",
+ &summary),
+ NULL),
+ GNUNET_JSON_spec_mark_optional (
+ TALER_JSON_spec_amount ("amount",
+ TMH_currency,
+ &amount),
+ &no_amount),
+ GNUNET_JSON_spec_end ()
+ };
+
+ {
+ 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;
+ }
}
-
-
- if (NULL == tp.image)
- tp.image = "";
- if (! TMH_image_data_url_valid (tp.image))
- {
- GNUNET_break_op (0);
- json_decref (fake_body);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "image");
+
+ {
+ enum GNUNET_DB_QueryStatus qs;
+
+ qs = TMH_db->lookup_template (TMH_db->cls,
+ mi->settings.id,
+ template_id,
+ &etp);
+ switch (qs)
+ {
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ /* Clean up and fail hard */
+ GNUNET_break (0);
+ 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:
+ /* this should be impossible (single select) */
+ GNUNET_break (0);
+ 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_SUCCESS_NO_RESULTS:
+ /* template not found! */
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_MERCHANT_GENERIC_TEMPLATE_UNKNOWN,
+ template_id);
+ case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+ /* all good */
+ break;
+ } /* End of the switch */
+ }
+
+ const char *tsummary;
+ uint32_t min_age;
+ struct GNUNET_TIME_Relative pay_duration;
+ struct TALER_Amount tamount;
+ bool no_tamount;
+
+ struct GNUNET_JSON_Specification tspec[] = {
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_string ("summary",
+ &tsummary),
+ NULL),
+ GNUNET_JSON_spec_mark_optional (
+ TALER_JSON_spec_amount ("amount",
+ TMH_currency,
+ &tamount),
+ &no_tamount),
+ GNUNET_JSON_spec_uint32 ("minimum_age",
+ &min_age),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_relative_time ("pay_duration",
+ &pay_duration),
+ NULL),
+ GNUNET_JSON_spec_end ()
+ };
+
+ {
+ enum GNUNET_GenericReturnValue res;
+ const char *err_name;
+ unsigned int err_line;
+
+ res = GNUNET_JSON_parse (etp.template_contract,
+ tspec,
+ &err_name,
+ &err_line);
+ if (GNUNET_OK != res)
+ {
+ GNUNET_break (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ err_name);
+ }
}
+
+ // if amount given in template AND request
+ if ((!no_amount) && (!no_tamount))
+ {
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_CONFLICT,
+ TALER_EC_MERCHANT_POST_USING_TEMPLATES_AMOUNT_CONFLICT_TEMPLATES_CONTRACT_AMOUNT,
+ NULL);
+ }
+
+ // if there is no amount in template and request
+ if (no_amount && no_tamount)
+ {
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_CONFLICT,
+ TALER_EC_MERCHANT_POST_USING_TEMPLATES_NO_AMOUNT,
+ NULL);
+ }
+
+ // if subject given in both
+ if ( (NULL!=summary) && (NULL != tsummary))
+ {
+
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_CONFLICT,
+ TALER_EC_MERCHANT_POST_USING_TEMPLATES_SUMMARY_CONFLICT_TEMPLATES_CONTRACT_SUBJECT,
+ NULL);
+ }
+
+ //if there is no summary in template and request
+ if ( (NULL == summary) && (NULL == tsummary) )
+ {
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_CONFLICT,
+ TALER_EC_MERCHANT_POST_USING_TEMPLATES_NO_SUMMARY,
+ NULL);
+ }
+
+ else
+ {
+ if ( (NULL == summary) )
+ {
+ no_summary = true;
+ }
+ else
+ {
+ no_summary = false;
+ }
+ }
+
+ fake_body = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_object_steal ("order",
+ GNUNET_JSON_PACK (
+ TALER_JSON_pack_amount ("amount",
+ no_amount ? &tamount : &amount),
+ GNUNET_JSON_pack_string ("summary",
+ no_summary ? tsummary : summary),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("fulfillment_url",
+ fulfillment_url)),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("fulfillment_message",
+ fulfillment_message))
+ ))
+ );
+
+
+ TALER_MERCHANTDB_template_details_free (&etp);
+
struct TMH_HandlerContext fake_hc = {
.request_body = fake_body,
.instance = hc->instance
diff --git a/src/backend/taler-merchant-httpd_post-using-templates.h b/src/backend/taler-merchant-httpd_post-using-templates.h
index db9d48e3..57ca6aa8 100644
--- a/src/backend/taler-merchant-httpd_post-using-templates.h
+++ b/src/backend/taler-merchant-httpd_post-using-templates.h
@@ -31,7 +31,7 @@
* @return MHD result code
*/
MHD_RESULT
-TMH_private_post_using_templates (struct MHD_Connection *connection,
+TMH_post_using_templates_ID (struct MHD_Connection *connection,
struct TMH_HandlerContext *hc);