From 0fa22bbcb5cb52edf6bcb75c70a2d1f9356f6b9c Mon Sep 17 00:00:00 2001 From: priscilla Date: Mon, 21 Nov 2022 07:18:48 -0500 Subject: templates --- src/backend/taler-merchant-httpd.h | 4 +- ...er-merchant-httpd_private-delete-templates-ID.h | 41 ++++ ...taler-merchant-httpd_private-get-templates-ID.h | 41 ++++ .../taler-merchant-httpd_private-get-templates.c | 76 +++++++ .../taler-merchant-httpd_private-get-templates.h | 41 ++++ ...ler-merchant-httpd_private-patch-templates-ID.h | 43 ++++ .../taler-merchant-httpd_private-post-templates.c | 226 +++++++++++++++++++++ .../taler-merchant-httpd_private-post-templates.h | 43 ++++ 8 files changed, 513 insertions(+), 2 deletions(-) create mode 100644 src/backend/taler-merchant-httpd_private-delete-templates-ID.h create mode 100644 src/backend/taler-merchant-httpd_private-get-templates-ID.h create mode 100644 src/backend/taler-merchant-httpd_private-get-templates.c create mode 100644 src/backend/taler-merchant-httpd_private-get-templates.h create mode 100644 src/backend/taler-merchant-httpd_private-patch-templates-ID.h create mode 100644 src/backend/taler-merchant-httpd_private-post-templates.c create mode 100644 src/backend/taler-merchant-httpd_private-post-templates.h diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h index 2e9f89fa..5dbb0c94 100644 --- a/src/backend/taler-merchant-httpd.h +++ b/src/backend/taler-merchant-httpd.h @@ -381,7 +381,7 @@ struct TMH_RequestHandler /** * URL prefix the handler is for, includes the '/', - * so "/orders" or "/products". Does *not* include + * so "/orders", "/templates" or "/products". Does *not* include * "/private", that is controlled by the array in which * the handler is defined. Must not contain any * '/' except for the leading '/'. @@ -390,7 +390,7 @@ struct TMH_RequestHandler /** * Does this request include an identifier segment - * (product_id, reserve_pub, order_id, tip_id) in the + * (product_id, reserve_pub, order_id, tip_id, template_id) in the * second segment? */ bool have_id_segment; diff --git a/src/backend/taler-merchant-httpd_private-delete-templates-ID.h b/src/backend/taler-merchant-httpd_private-delete-templates-ID.h new file mode 100644 index 00000000..db164fe7 --- /dev/null +++ b/src/backend/taler-merchant-httpd_private-delete-templates-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 +*/ +/** + * @file taler-merchant-httpd_private-delete-templates-ID.h + * @brief implement DELETE /templates/$ID/ + * @author Christian Grothoff + */ +#ifndef TALER_MERCHANT_HTTPD_PRIVATE_DELETE_TEMPLATES_ID_H +#define TALER_MERCHANT_HTTPD_PRIVATE_DELETE_TEMPLATES_ID_H + +#include "taler-merchant-httpd.h" + + +/** + * Handle a DELETE "/templates/$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_templates_ID (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc); + +/* end of taler-merchant-httpd_private-delete-templates-ID.h */ +#endif diff --git a/src/backend/taler-merchant-httpd_private-get-templates-ID.h b/src/backend/taler-merchant-httpd_private-get-templates-ID.h new file mode 100644 index 00000000..05c6e460 --- /dev/null +++ b/src/backend/taler-merchant-httpd_private-get-templates-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 +*/ +/** + * @file taler-merchant-httpd_private-get-templates-ID.h + * @brief implement GET /templates/$ID/ + * @author Christian Grothoff + */ +#ifndef TALER_MERCHANT_HTTPD_PRIVATE_GET_TEMPLATES_ID_H +#define TALER_MERCHANT_HTTPD_PRIVATE_GET_TEMPLATES_ID_H + +#include "taler-merchant-httpd.h" + + +/** + * Handle a GET "/templates/$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_templates_ID (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc); + +/* end of taler-merchant-httpd_private-get-templates-ID.h */ +#endif diff --git a/src/backend/taler-merchant-httpd_private-get-templates.c b/src/backend/taler-merchant-httpd_private-get-templates.c new file mode 100644 index 00000000..20cd0cdc --- /dev/null +++ b/src/backend/taler-merchant-httpd_private-get-templates.c @@ -0,0 +1,76 @@ +/* + This file is part of TALER + (C) 2019, 2020, 2021 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 +*/ +/** + * @file taler-merchant-httpd_private-get-templates.c + * @brief implement GET /templates + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler-merchant-httpd_private-get-templates.h" + + +/** + * Add template details to our JSON array. + * + * @param cls a `json_t *` JSON array to build + * @param template_id ID of the template + */ +static void +add_template (void *cls, + const char *template_id) +{ + json_t *pa = cls; + + GNUNET_assert (0 == + json_array_append_new ( + pa, + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("template_id", + template_id)))); +} + + +MHD_RESULT +TMH_private_get_templates (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + json_t *pa; + enum GNUNET_DB_QueryStatus qs; + + pa = json_array (); + GNUNET_assert (NULL != pa); + qs = TMH_db->lookup_templates (TMH_db->cls, + hc->instance->settings.id, + &add_template, + pa); + if (0 > qs) + { + GNUNET_break (0); + json_decref (pa); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + NULL); + } + return TALER_MHD_REPLY_JSON_PACK (connection, + MHD_HTTP_OK, + GNUNET_JSON_pack_array_steal ("templates", + pa)); +} + + +/* end of taler-merchant-httpd_private-get-templates.c */ diff --git a/src/backend/taler-merchant-httpd_private-get-templates.h b/src/backend/taler-merchant-httpd_private-get-templates.h new file mode 100644 index 00000000..ca7cf2c6 --- /dev/null +++ b/src/backend/taler-merchant-httpd_private-get-templates.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 +*/ +/** + * @file taler-merchant-httpd_private-get-templates.h + * @brief implement GET /templates + * @author Christian Grothoff + */ +#ifndef TALER_MERCHANT_HTTPD_PRIVATE_GET_TEMPLATES_H +#define TALER_MERCHANT_HTTPD_PRIVATE_GET_TEMPLATES_H + +#include "taler-merchant-httpd.h" + + +/** + * Handle a GET "/templates" 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_templates (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc); + +/* end of taler-merchant-httpd_private-get-templates.h */ +#endif diff --git a/src/backend/taler-merchant-httpd_private-patch-templates-ID.h b/src/backend/taler-merchant-httpd_private-patch-templates-ID.h new file mode 100644 index 00000000..ce1c57a9 --- /dev/null +++ b/src/backend/taler-merchant-httpd_private-patch-templates-ID.h @@ -0,0 +1,43 @@ +/* + 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 +*/ + +/** + * @file taler-merchant-httpd_private-patch-templates-ID.h + * @brief implementing PATCH /templates request handling + * @author Christian Grothoff + */ +#ifndef TALER_MERCHANT_HTTPD_PRIVATE_PATCH_TEMPLATES_ID_H +#define TALER_MERCHANT_HTTPD_PRIVATE_PATCH_TEMPLATES_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_templates_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-templates.c b/src/backend/taler-merchant-httpd_private-post-templates.c new file mode 100644 index 00000000..5122e2e2 --- /dev/null +++ b/src/backend/taler-merchant-httpd_private-post-templates.c @@ -0,0 +1,226 @@ +/* + 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 +*/ + +/** + * @file taler-merchant-httpd_private-post-templates.c + * @brief implementing POST /templates request handling + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler-merchant-httpd_private-post-templates.h" +#include "taler-merchant-httpd_helper.h" +#include + + +/** + * How often do we retry the simple INSERT database transaction? + */ +#define MAX_RETRIES 3 + + +/** + * Check if the two templates are identical. + * + * @param t1 template to compare + * @param t2 other template to compare + * @return true if they are 'equal', false if not or of payto_uris is not an array + */ +static bool +templates_equal (const struct TALER_MERCHANTDB_TemplateDetails *t1, + const struct TALER_MERCHANTDB_TemplateDetails *t2) +{ + return ( (0 == strcmp (t1->template_description, + t2->tempate_description)) && + (0 == strcmp (t1->image, + t2->image)) && + (1 == json_equal (p1->template_contract, + p2->template_contract)); +} + + +MHD_RESULT +TMH_private_post_templates (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + struct TMH_MerchantInstance *mi = hc->instance; + struct TALER_MERCHANTDB_TemplateDetails tp = { 0 }; + const char *template_id; + enum GNUNET_DB_QueryStatus qs; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ("template_id", + &template_id), + GNUNET_JSON_spec_string ("template_description", + (const char **) &tp.template_description), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("image", + (const char **) &tp.image), + NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_json ("template_contract", + &tp.template_contract), + NULL), + 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; + } + } + + + if (NULL == tp.template_contract) + tp.template_contract = json_object ();; + + + if (! TMH_template_contract_valid (tp.template_contract)) + { + GNUNET_break_op (0); + GNUNET_JSON_parse_free (spec); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "template_contract"); + } + + + if (NULL == tp.image) + tp.image = ""; + if (! TMH_image_data_url_valid (tp.image)) + { + GNUNET_break_op (0); + GNUNET_JSON_parse_free (spec); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "image"); + } + + /* finally, interact with DB until no serialization error */ + for (unsigned int i = 0; istart (TMH_db->cls, + "/post templates")) + { + 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_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); + 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 etp == tp? */ + { + bool eq; + + eq = products_equal (&tp, + &etp); + TALER_MERCHANTDB_product_details_free (&etp); + 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_PRODUCTS_CONFLICT_PRODUCT_EXISTS, + template_id); + } + } /* end switch (qs) */ + + qs = TMH_db->insert_template (TMH_db->cls, + mi->settings.id, + template_id, + &tp); + 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-templates.c */ diff --git a/src/backend/taler-merchant-httpd_private-post-templates.h b/src/backend/taler-merchant-httpd_private-post-templates.h new file mode 100644 index 00000000..0492a3ab --- /dev/null +++ b/src/backend/taler-merchant-httpd_private-post-templates.h @@ -0,0 +1,43 @@ +/* + 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 +*/ + +/** + * @file taler-merchant-httpd_private-post-templates.h + * @brief implementing POST /templates request handling + * @author Christian Grothoff + */ +#ifndef TALER_MERCHANT_HTTPD_PRIVATE_POST_TEMPLATES_H +#define TALER_MERCHANT_HTTPD_PRIVATE_POST_TEMPLATES_H +#include "taler-merchant-httpd.h" + + +/** + * Generate a template 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_templates (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc); + +#endif -- cgit v1.2.3