From ab04b2ce37299a40d48adee29192648a7667d4d9 Mon Sep 17 00:00:00 2001 From: priscilla Date: Wed, 21 Dec 2022 06:20:06 -0500 Subject: POST using template --- .../taler-merchant-httpd_post-using-templates.c | 249 ++++++++++++++++----- .../taler-merchant-httpd_post-using-templates.h | 2 +- 2 files changed, 199 insertions(+), 52 deletions(-) (limited to 'src/backend') 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 +/** + * 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); -- cgit v1.2.3