summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-08-16 14:06:46 +0200
committerChristian Grothoff <christian@grothoff.org>2022-08-16 14:06:46 +0200
commitc1d0a7d2e64fd7c6bd041a5259cf212b3aabd414 (patch)
tree8b5c4d05187336048f13c1e500501f6e6bbda727 /src/backend
parent19010a2f6d658e78ded8abb02995d9154d22bbf3 (diff)
downloadmerchant-c1d0a7d2e64fd7c6bd041a5259cf212b3aabd414.tar.gz
merchant-c1d0a7d2e64fd7c6bd041a5259cf212b3aabd414.tar.bz2
merchant-c1d0a7d2e64fd7c6bd041a5259cf212b3aabd414.zip
-move templating logic to libtalertemplating of exchange
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/Makefile.am6
-rw-r--r--src/backend/taler-merchant-httpd.c20
-rw-r--r--src/backend/taler-merchant-httpd_get-orders-ID.c38
-rw-r--r--src/backend/taler-merchant-httpd_get-tips-ID.c19
-rw-r--r--src/backend/taler-merchant-httpd_statics.c2
-rw-r--r--src/backend/taler-merchant-httpd_templating.c452
-rw-r--r--src/backend/taler-merchant-httpd_templating.h56
7 files changed, 43 insertions, 550 deletions
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index 073fff5e..2bd25251 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -107,12 +107,11 @@ taler_merchant_httpd_SOURCES = \
taler-merchant-httpd_spa.c \
taler-merchant-httpd_spa.h \
taler-merchant-httpd_statics.c \
- taler-merchant-httpd_statics.h \
- taler-merchant-httpd_templating.c \
- taler-merchant-httpd_templating.h
+ taler-merchant-httpd_statics.h
taler_merchant_httpd_LDADD = \
$(top_builddir)/src/backenddb/libtalermerchantdb.la \
-ltalerexchange \
+ -ltalertemplating \
-ltalermhd \
-ltalerbank \
-ltalerjson \
@@ -123,7 +122,6 @@ taler_merchant_httpd_LDADD = \
-lgnunetcurl \
-lgnunetjson \
-lgnunetutil \
- $(top_builddir)/src/mustach/libmustach.a \
@QR_LIBS@ \
$(XLIB)
taler_merchant_httpd_CFLAGS = \
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index d5bc19d6..d95dafdc 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -25,6 +25,7 @@
#include <taler/taler_dbevents.h>
#include <taler/taler_bank_service.h>
#include <taler/taler_mhd_lib.h>
+#include <taler/taler_templating_lib.h>
#include <taler/taler_exchange_service.h>
#include "taler-merchant-httpd_auditors.h"
#include "taler-merchant-httpd_config.h"
@@ -70,7 +71,7 @@
#include "taler-merchant-httpd_reserves.h"
#include "taler-merchant-httpd_spa.h"
#include "taler-merchant-httpd_statics.h"
-#include "taler-merchant-httpd_templating.h"
+
/**
* Fixme: document.
@@ -306,6 +307,7 @@ do_shutdown (void *cls)
GNUNET_CONTAINER_multihashmap_destroy (TMH_by_id_map);
TMH_by_id_map = NULL;
}
+ TALER_TEMPLATING_done ();
}
@@ -1140,7 +1142,7 @@ url_handler (void *cls,
MHD_HTTP_METHOD_HEAD))
method = MHD_HTTP_METHOD_GET; /* MHD will deal with the rest */
-
+
/* Find out the merchant backend instance for the request.
* If there is an instance, remove the instance specification
* from the beginning of the request URL. */
@@ -1443,12 +1445,12 @@ url_handler (void *cls,
&hc->instance->auth.auth_salt,
&hc->instance->auth.auth_hash));
else /* Are the credentials provided OK for CLI override? */
- auth_ok |= ( use_default &&
- (NULL != TMH_default_auth) &&
- (NULL != auth) &&
- (! auth_malformed) &&
- (0 == strcmp (auth,
- TMH_default_auth)) );
+ auth_ok |= (use_default &&
+ (NULL != TMH_default_auth) &&
+ (NULL != auth) &&
+ (! auth_malformed) &&
+ (0 == strcmp (auth,
+ TMH_default_auth)) );
if (! auth_ok)
{
if (auth_malformed)
@@ -1778,7 +1780,7 @@ run (void *cls,
"merchant",
"FORCE_AUDIT"))
TMH_force_audit = GNUNET_YES;
- TMH_templating_init ();
+ TALER_TEMPLATING_init ("merchant");
if (GNUNET_OK !=
TMH_spa_init ())
{
diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.c b/src/backend/taler-merchant-httpd_get-orders-ID.c
index 53260f67..5d229fc2 100644
--- a/src/backend/taler-merchant-httpd_get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_get-orders-ID.c
@@ -25,12 +25,12 @@
#include <taler/taler_signatures.h>
#include <taler/taler_dbevents.h>
#include <taler/taler_json_lib.h>
+#include <taler/taler_templating_lib.h>
#include <taler/taler_exchange_service.h>
#include "taler-merchant-httpd_exchanges.h"
#include "taler-merchant-httpd_get-orders-ID.h"
#include "taler-merchant-httpd_mhd.h"
#include "taler-merchant-httpd_qr.h"
-#include "taler-merchant-httpd_templating.h"
/**
* How often do we retry DB transactions on serialization failures?
@@ -691,12 +691,12 @@ send_pay_request (struct GetOrderData *god,
qr),
GNUNET_JSON_pack_string ("order_summary",
get_order_summary (god)));
- res = TMH_return_from_template (god->sc.con,
- MHD_HTTP_PAYMENT_REQUIRED,
- "request_payment",
- god->hc->instance->settings.id,
- taler_pay_uri,
- context);
+ res = TALER_TEMPLATING_reply (god->sc.con,
+ MHD_HTTP_PAYMENT_REQUIRED,
+ "request_payment",
+ god->hc->instance->settings.id,
+ taler_pay_uri,
+ context);
if (GNUNET_SYSERR == res)
{
GNUNET_break (0);
@@ -1460,12 +1460,12 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
uri),
GNUNET_JSON_pack_string ("taler_refund_qrcode_svg",
qr));
- res = TMH_return_from_template (god->sc.con,
- MHD_HTTP_OK,
- "offer_refund",
- hc->instance->settings.id,
- uri,
- context);
+ res = TALER_TEMPLATING_reply (god->sc.con,
+ MHD_HTTP_OK,
+ "offer_refund",
+ hc->instance->settings.id,
+ uri,
+ context);
json_decref (context);
}
GNUNET_free (uri);
@@ -1484,12 +1484,12 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
&god->refund_amount),
TALER_JSON_pack_amount ("refund_taken",
&god->refund_taken));
- res = TMH_return_from_template (god->sc.con,
- MHD_HTTP_OK,
- "show_order_details",
- hc->instance->settings.id,
- NULL,
- context);
+ res = TALER_TEMPLATING_reply (god->sc.con,
+ MHD_HTTP_OK,
+ "show_order_details",
+ hc->instance->settings.id,
+ NULL,
+ context);
json_decref (context);
}
if (GNUNET_SYSERR == res)
diff --git a/src/backend/taler-merchant-httpd_get-tips-ID.c b/src/backend/taler-merchant-httpd_get-tips-ID.c
index f427b168..0486de3e 100644
--- a/src/backend/taler-merchant-httpd_get-tips-ID.c
+++ b/src/backend/taler-merchant-httpd_get-tips-ID.c
@@ -23,10 +23,11 @@
#include <jansson.h>
#include <taler/taler_signatures.h>
#include <taler/taler_json_lib.h>
+#include <taler/taler_templating_lib.h>
#include "taler-merchant-httpd_get-tips-ID.h"
#include "taler-merchant-httpd_mhd.h"
#include "taler-merchant-httpd_qr.h"
-#include "taler-merchant-httpd_templating.h"
+
char *
TMH_make_taler_tip_uri (struct MHD_Connection *con,
@@ -249,18 +250,18 @@ TMH_get_tips_ID (const struct TMH_RequestHandler *rh,
uri),
GNUNET_JSON_pack_string ("taler_tip_qrcode_svg",
qr));
- ret = TMH_return_from_template (connection,
- ( (0 == remaining.value) &&
- (0 == remaining.fraction) )
+ ret = TALER_TEMPLATING_reply (connection,
+ ( (0 == remaining.value) &&
+ (0 == remaining.fraction) )
? MHD_HTTP_GONE
: MHD_HTTP_OK,
- ( (0 == remaining.value) &&
- (0 == remaining.fraction) )
+ ( (0 == remaining.value) &&
+ (0 == remaining.fraction) )
? "depleted_tip"
: "offer_tip",
- hc->instance->settings.id,
- uri,
- context);
+ hc->instance->settings.id,
+ uri,
+ context);
json_decref (context);
}
GNUNET_free (tip_status_url);
diff --git a/src/backend/taler-merchant-httpd_statics.c b/src/backend/taler-merchant-httpd_statics.c
index 69331087..0cf54713 100644
--- a/src/backend/taler-merchant-httpd_statics.c
+++ b/src/backend/taler-merchant-httpd_statics.c
@@ -22,8 +22,8 @@
#include <gnunet/gnunet_util_lib.h>
#include <taler/taler_util.h>
#include <taler/taler_mhd_lib.h>
+#include <taler/taler_templating_lib.h>
#include "taler-merchant-httpd_statics.h"
-#include "../mustach/mustach.h"
#include <gnunet/gnunet_mhd_compat.h>
diff --git a/src/backend/taler-merchant-httpd_templating.c b/src/backend/taler-merchant-httpd_templating.c
deleted file mode 100644
index 9d7766b9..00000000
--- a/src/backend/taler-merchant-httpd_templating.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 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
- 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_templating.c
- * @brief logic to load and complete HTML templates
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <taler/taler_util.h>
-#include <taler/taler_mhd_lib.h>
-#include "taler-merchant-httpd_templating.h"
-#include "../mustach/mustach.h"
-#include "../mustach/mustach-jansson.h"
-#include <gnunet/gnunet_mhd_compat.h>
-
-
-/**
- * Entry in a key-value array we use to cache templates.
- */
-struct TVE
-{
- /**
- * A name, used as the key. NULL for the last entry.
- */
- char *name;
-
- /**
- * Language the template is in.
- */
- char *lang;
-
- /**
- * 0-terminated (!) file data to return for @e name and @e lang.
- */
- char *value;
-
-};
-
-
-/**
- * Array of templates loaded into RAM.
- */
-static struct TVE *loaded;
-
-/**
- * Length of the #loaded array.
- */
-static unsigned int loaded_length;
-
-
-/**
- * Load Mustach template into memory. Note that we intentionally cache
- * failures, that is if we ever failed to load a template, we will never try
- * again.
- *
- * @param connection the connection we act upon
- * @param name name of the template file to load
- * (MUST be a 'static' string in memory!)
- * @return NULL on error, otherwise the template
- */
-static const char *
-lookup_template (struct MHD_Connection *connection,
- const char *name)
-{
- struct TVE *best = NULL;
- const char *lang;
-
- lang = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_ACCEPT_LANGUAGE);
- if (NULL == lang)
- lang = "en";
- /* find best match by language */
- for (unsigned int i = 0; i<loaded_length; i++)
- {
- if (0 != strcmp (loaded[i].name,
- name))
- continue; /* does not match by name */
- if ( (NULL == best) ||
- (TALER_language_matches (lang,
- loaded[i].lang) >
- TALER_language_matches (lang,
- best->lang) ) )
- best = &loaded[i];
- }
- if (NULL == best)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "No templates found in `%s'\n",
- name);
- return NULL;
- }
- return best->value;
-}
-
-/**
- * Get the base URL for static resources.
- *
- * @param con the MHD connection
- * @param instance_id the instance ID
- * @returns the static files base URL, guaranteed
- * to have a trailing slash.
- */
-static char *
-make_static_url (struct MHD_Connection *con,
- const char *instance_id)
-{
- const char *host;
- const char *forwarded_host;
- const char *uri_path;
- struct GNUNET_Buffer buf = { 0 };
-
- host = MHD_lookup_connection_value (con,
- MHD_HEADER_KIND,
- "Host");
- forwarded_host = MHD_lookup_connection_value (con,
- MHD_HEADER_KIND,
- "X-Forwarded-Host");
-
- uri_path = MHD_lookup_connection_value (con,
- MHD_HEADER_KIND,
- "X-Forwarded-Prefix");
- if (NULL != forwarded_host)
- host = forwarded_host;
-
- if (NULL == host)
- {
- GNUNET_break (0);
- return NULL;
- }
-
- GNUNET_assert (NULL != instance_id);
-
- if (GNUNET_NO == TALER_mhd_is_https (con))
- GNUNET_buffer_write_str (&buf,
- "http://");
- else
- GNUNET_buffer_write_str (&buf,
- "https://");
- GNUNET_buffer_write_str (&buf,
- host);
- if (NULL != uri_path)
- GNUNET_buffer_write_path (&buf,
- uri_path);
- if (0 != strcmp ("default",
- instance_id))
- {
- GNUNET_buffer_write_path (&buf,
- "instances");
- GNUNET_buffer_write_path (&buf,
- instance_id);
- }
- GNUNET_buffer_write_path (&buf,
- "static/");
- return GNUNET_buffer_reap_str (&buf);
-}
-
-
-
-
-/**
- * Load a @a template and substitute using @a root, returning
- * the result to the @a connection with the given
- * @a http_status code.
- *
- * @param connection the connection we act upon
- * @param http_status code to use on success
- * @param template basename of the template to load
- * @param instance_id instance ID, used to compute static files URL
- * @param taler_uri value for "Taler:" header to set, or NULL
- * @param root JSON object to pass as the root context
- * @return #GNUNET_OK on success (reply queued), #GNUNET_NO if an error was queued,
- * #GNUNET_SYSERR on failure (to queue an error)
- */
-enum GNUNET_GenericReturnValue
-TMH_return_from_template (struct MHD_Connection *connection,
- unsigned int http_status,
- const char *template,
- const char *instance_id,
- const char *taler_uri,
- json_t *root)
-{
- struct MHD_Response *reply;
- char *body;
- size_t body_size;
-
- {
- const char *tmpl;
- int eno;
-
- tmpl = lookup_template (connection,
- template);
- if (NULL == tmpl)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to load template `%s'\n",
- template);
- if (MHD_YES !=
- TALER_MHD_reply_with_error (connection,
- MHD_HTTP_NOT_ACCEPTABLE,
- TALER_EC_MERCHANT_GENERIC_FAILED_TO_LOAD_TEMPLATE,
- template))
- return GNUNET_SYSERR;
- return GNUNET_NO;
- }
- /* Add default values to the context */
- {
- char *static_url = make_static_url (connection,
- instance_id);
- json_object_set (root,
- "static_url",
- json_string (static_url));
- GNUNET_free (static_url);
- }
- if (0 !=
- (eno = mustach_jansson (tmpl,
- root,
- &body,
- &body_size)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "mustach failed on template `%s' with error %d\n",
- template,
- eno);
- if (MHD_YES !=
- TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_MERCHANT_GENERIC_FAILED_TO_EXPAND_TEMPLATE,
- template))
- return GNUNET_SYSERR;
- return GNUNET_NO;
- }
- }
-
- /* try to compress reply if client allows it */
- {
- bool compressed = false;
-
- if (MHD_YES ==
- TALER_MHD_can_compress (connection))
- {
- compressed = TALER_MHD_body_compress ((void **) &body,
- &body_size);
- }
- reply = MHD_create_response_from_buffer (body_size,
- body,
- MHD_RESPMEM_MUST_FREE);
- if (NULL == reply)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- if (compressed)
- {
- if (MHD_NO ==
- MHD_add_response_header (reply,
- MHD_HTTP_HEADER_CONTENT_ENCODING,
- "deflate"))
- {
- GNUNET_break (0);
- MHD_destroy_response (reply);
- return GNUNET_SYSERR;
- }
- }
- }
-
- /* Add standard headers */
- if (NULL != taler_uri)
- GNUNET_break (MHD_NO !=
- MHD_add_response_header (reply,
- "Taler",
- taler_uri));
- GNUNET_break (MHD_NO !=
- MHD_add_response_header (reply,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- "text/html"));
-
- /* Actually return reply */
- {
- MHD_RESULT ret;
-
- ret = MHD_queue_response (connection,
- http_status,
- reply);
- MHD_destroy_response (reply);
- if (MHD_NO == ret)
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Function called with a template's filename.
- *
- * @param cls closure
- * @param filename complete filename (absolute path)
- * @return #GNUNET_OK to continue to iterate,
- * #GNUNET_NO to stop iteration with no error,
- * #GNUNET_SYSERR to abort iteration with error!
- */
-static int
-load_template (void *cls,
- const char *filename)
-{
- char *lang;
- char *end;
- int fd;
- struct stat sb;
- char *map;
- const char *name;
-
- if ('.' == filename[0])
- return GNUNET_OK;
-
- name = strrchr (filename,
- '/');
- if (NULL == name)
- name = filename;
- else
- name++;
- lang = strchr (name,
- '.');
- if (NULL == lang)
- return GNUNET_OK; /* name must include .$LANG */
- lang++;
- end = strchr (lang,
- '.');
- if ( (NULL == end) ||
- (0 != strcmp (end,
- ".must")) )
- return GNUNET_OK; /* name must end with '.must' */
-
- /* finally open template */
- fd = open (filename,
- O_RDONLY);
- if (-1 == fd)
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "open",
- filename);
-
- return GNUNET_SYSERR;
- }
- if (0 !=
- fstat (fd,
- &sb))
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "open",
- filename);
- GNUNET_break (0 == close (fd));
- return GNUNET_OK;
- }
- map = GNUNET_malloc_large (sb.st_size + 1);
- if (NULL == map)
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
- "malloc");
- GNUNET_break (0 == close (fd));
- return GNUNET_SYSERR;
- }
- if (sb.st_size !=
- read (fd,
- map,
- sb.st_size))
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "read",
- filename);
- GNUNET_break (0 == close (fd));
- return GNUNET_OK;
- }
- GNUNET_break (0 == close (fd));
- GNUNET_array_grow (loaded,
- loaded_length,
- loaded_length + 1);
- loaded[loaded_length - 1].name = GNUNET_strndup (name,
- (lang - 1) - name);
- loaded[loaded_length - 1].lang = GNUNET_strndup (lang,
- end - lang);
- loaded[loaded_length - 1].value = map;
- return GNUNET_OK;
-}
-
-
-/**
- * Preload templates.
- */
-int
-TMH_templating_init ()
-{
- char *dn;
- int ret;
-
- {
- char *path;
-
- path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
- if (NULL == path)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- GNUNET_asprintf (&dn,
- "%s/merchant/templates/",
- path);
- GNUNET_free (path);
- }
- ret = GNUNET_DISK_directory_scan (dn,
- &load_template,
- NULL);
- GNUNET_free (dn);
- if (-1 == ret)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Nicely shut down.
- */
-void __attribute__ ((destructor))
-templating_fini ()
-{
- for (unsigned int i = 0; i<loaded_length; i++)
- {
- GNUNET_free (loaded[i].name);
- GNUNET_free (loaded[i].lang);
- GNUNET_free (loaded[i].value);
- }
- GNUNET_array_grow (loaded,
- loaded_length,
- 0);
-}
diff --git a/src/backend/taler-merchant-httpd_templating.h b/src/backend/taler-merchant-httpd_templating.h
deleted file mode 100644
index a1c2e05a..00000000
--- a/src/backend/taler-merchant-httpd_templating.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 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
- 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_templating.h
- * @brief logic to load and complete HTML templates
- * @author Christian Grothoff
- */
-#ifndef TALER_MERCHANT_HTTPD_TEMPLATING_H
-#define TALER_MERCHANT_HTTPD_TEMPLATING_H
-
-#include <microhttpd.h>
-
-
-/**
- * Load a @a template and substitute using @a root, returning
- * the result to the @a connection with the given
- * @a http_status code.
- *
- * @param connection the connection we act upon
- * @param http_status code to use on success
- * @param template basename of the template to load
- * @param instance_id instance ID, used to compute static files URL
- * @param taler_uri value for "Taler:" header to set, or NULL
- * @param root JSON object to pass as the root context
- * @return #GNUNET_OK on success (reply queued), #GNUNET_NO if an error was queued,
- * #GNUNET_SYSERR on failure (to queue an error)
- */
-enum GNUNET_GenericReturnValue
-TMH_return_from_template (struct MHD_Connection *connection,
- unsigned int http_status,
- const char *template,
- const char *instance_id,
- const char *taler_uri,
- json_t *root);
-
-/**
- * Preload templates.
- */
-int
-TMH_templating_init (void);
-
-
-#endif