gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant] branch master updated: -misc backend changes from works


From: gnunet
Subject: [taler-merchant] branch master updated: -misc backend changes from workshop
Date: Fri, 23 Jul 2021 17:07:53 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 590bb2c6 -misc backend changes from workshop
590bb2c6 is described below

commit 590bb2c6d181bd703ff4b1c528662898f28eab79
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Fri Jul 23 17:07:51 2021 +0200

    -misc backend changes from workshop
---
 src/backend/taler-merchant-httpd.c                 |   1 +
 src/backend/taler-merchant-httpd_get-orders-ID.c   | 313 ++++++++++++---------
 src/backend/taler-merchant-httpd_get-orders-ID.h   |   7 +
 .../taler-merchant-httpd_private-get-orders-ID.c   |  11 +
 4 files changed, 194 insertions(+), 138 deletions(-)

diff --git a/src/backend/taler-merchant-httpd.c 
b/src/backend/taler-merchant-httpd.c
index 277f7480..ac223a5b 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -703,6 +703,7 @@ do_shutdown (void *cls)
   TMH_force_rc_resume ();
   TMH_force_post_transfers_resume ();
   TMH_force_tip_pickup_resume ();
+  TMH_force_wallet_get_order_resume ();
   TMH_force_wallet_refund_order_resume ();
   if (NULL != mhd_task)
   {
diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.c 
b/src/backend/taler-merchant-httpd_get-orders-ID.c
index 110333fc..b061ff43 100644
--- a/src/backend/taler-merchant-httpd_get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_get-orders-ID.c
@@ -119,7 +119,8 @@ struct GetOrderData
   enum TALER_ErrorCode ec;
 
   /**
-   * Did we suspend @a connection?
+   * Did we suspend @a connection and are thus in
+   * the #god_head DLL?
    */
   bool suspended;
 
@@ -161,9 +162,6 @@ static struct GetOrderData *god_head;
 static struct GetOrderData *god_tail;
 
 
-/**
- * Force resuming all suspended order lookups, needed during shutdown.
- */
 void
 TMH_force_wallet_get_order_resume (void)
 {
@@ -192,6 +190,11 @@ suspend_god (struct GetOrderData *god)
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Suspending GET /orders/%s\n",
               god->order_id);
+  GNUNET_assert (! god->suspended);
+  god->suspended = true;
+  GNUNET_CONTAINER_DLL_insert (god_head,
+                               god_tail,
+                               god);
   TMH_long_poll_suspend (god->order_id,
                          god->session_id,
                          god->fulfillment_url,
@@ -231,7 +234,6 @@ make_taler_refund_uri (const char *merchant_base_url,
     return NULL;
   }
   GNUNET_assert (NULL != order_id);
-
   GNUNET_buffer_write_str (&buf,
                            "taler");
   if (0 == strcasecmp ("http",
@@ -275,23 +277,25 @@ TMH_make_order_status_url (struct MHD_Connection *con,
 
   host = MHD_lookup_connection_value (con,
                                       MHD_HEADER_KIND,
-                                      "Host");
+                                      MHD_HTTP_HEADER_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;
   }
-
+  if (NULL != strchr (host, '/'))
+  {
+    GNUNET_break_op (0);
+    return NULL;
+  }
   GNUNET_assert (NULL != instance_id);
   GNUNET_assert (NULL != order_id);
 
@@ -301,7 +305,6 @@ TMH_make_order_status_url (struct MHD_Connection *con,
   else
     GNUNET_buffer_write_str (&buf,
                              "https://";);
-
   GNUNET_buffer_write_str (&buf,
                            host);
   if (NULL != uri_path)
@@ -322,6 +325,7 @@ TMH_make_order_status_url (struct MHD_Connection *con,
   if ((NULL != claim_token) &&
       (GNUNET_NO == GNUNET_is_zero (claim_token)))
   {
+    /* 'token=' for human readability */
     GNUNET_buffer_write_str (&buf,
                              "?token=");
     GNUNET_buffer_write_data_encoded (&buf,
@@ -374,26 +378,27 @@ TMH_make_taler_pay_uri (struct MHD_Connection *con,
 
   host = MHD_lookup_connection_value (con,
                                       MHD_HEADER_KIND,
-                                      "Host");
+                                      MHD_HTTP_HEADER_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;
   }
-
+  if (NULL != strchr (host, '/'))
+  {
+    GNUNET_break_op (0);
+    return NULL;
+  }
   GNUNET_assert (NULL != instance_id);
   GNUNET_assert (NULL != order_id);
-
   GNUNET_buffer_write_str (&buf,
                            "taler");
   if (GNUNET_NO == TALER_mhd_is_https (con))
@@ -421,6 +426,8 @@ TMH_make_taler_pay_uri (struct MHD_Connection *con,
   if ((NULL != claim_token) &&
       (GNUNET_NO == GNUNET_is_zero (claim_token)))
   {
+    /* Just 'c=' because this goes into QR
+       codes, so this is more compact. */
     GNUNET_buffer_write_str (&buf,
                              "?c=");
     GNUNET_buffer_write_data_encoded (&buf,
@@ -437,10 +444,10 @@ TMH_make_taler_pay_uri (struct MHD_Connection *con,
  * preferred language of the HTTP client.
  *
  * @param god order to extract summary from
- * @return NULL if no summary was provided in the contract
+ * @return dummy error message summary if no summary was provided in the 
contract
  */
 static const char *
-get_order_summary (struct GetOrderData *god)
+get_order_summary (const struct GetOrderData *god)
 {
   const char *language_pattern;
   const char *ret;
@@ -455,8 +462,10 @@ get_order_summary (struct GetOrderData *god)
                                                     "summary"));
   if (NULL == ret)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "No order summary found!\n");
+    /* Upon order creation (and insertion into the database), the presence
+       of a summary should have been checked. So if we get here, someone
+       did something fishy to our database... */
+    GNUNET_break (0);
     ret = "<bug: no summary>";
   }
   return ret;
@@ -483,8 +492,7 @@ send_pay_request (struct GetOrderData *god,
 
   remaining = GNUNET_TIME_absolute_get_remaining (god->sc.long_poll_timeout);
   if ( (0 != remaining.rel_value_us) &&
-       ( (NULL == already_paid_order_id) ||
-         (NULL == god->fulfillment_url) ) )
+       (NULL == already_paid_order_id) )
   {
     /* long polling: do not queue a response, suspend connection instead */
     suspend_god (god);
@@ -507,19 +515,28 @@ send_pay_request (struct GetOrderData *god,
                                                 god->hc->instance->settings.id,
                                                 &god->claim_token,
                                                 NULL);
+  if ( (NULL == taler_pay_uri) ||
+       (NULL == order_status_url) )
+  {
+    GNUNET_break_op (0);
+    GNUNET_free (taler_pay_uri);
+    GNUNET_free (order_status_url);
+    return TALER_MHD_reply_with_error (god->sc.con,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       TALER_EC_GENERIC_HTTP_HEADERS_MALFORMED,
+                                       "host");
+  }
   if (god->generate_html)
   {
-    char *qr;
-
-    if ( (NULL != already_paid_order_id) &&
-         (NULL != god->fulfillment_url) )
+    if (NULL != already_paid_order_id)
     {
       struct MHD_Response *reply;
-      MHD_RESULT ret;
 
+      GNUNET_assert (NULL != god->fulfillment_url);
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "Redirecting to already paid order %s\n",
-                  already_paid_order_id);
+                  "Redirecting to already paid order %s via fulfillment URL 
%s\n",
+                  already_paid_order_id,
+                  god->fulfillment_url);
       reply = MHD_create_response_from_buffer (0,
                                                NULL,
                                                MHD_RESPMEM_PERSISTENT);
@@ -532,50 +549,61 @@ send_pay_request (struct GetOrderData *god,
                     MHD_add_response_header (reply,
                                              MHD_HTTP_HEADER_LOCATION,
                                              god->fulfillment_url));
-      ret = MHD_queue_response (god->sc.con,
-                                MHD_HTTP_FOUND,
-                                reply);
-      MHD_destroy_response (reply);
-      return ret;
-    }
+      {
+        MHD_RESULT ret;
 
-    qr = TMH_create_qrcode (taler_pay_uri);
-    if (NULL == qr)
-    {
-      GNUNET_break (0);
-      return MHD_NO;
+        ret = MHD_queue_response (god->sc.con,
+                                  MHD_HTTP_FOUND,
+                                  reply);
+        MHD_destroy_response (reply);
+        return ret;
+      }
     }
+
     {
-      enum GNUNET_GenericReturnValue res;
-      json_t *context;
+      char *qr;
 
-      context = json_pack ("{s:s, s:s, s:s, s:s}",
-                           "taler_pay_uri",
-                           taler_pay_uri,
-                           "order_status_url",
-                           order_status_url,
-                           "taler_pay_qrcode_svg",
-                           qr,
-                           "order_summary",
-                           get_order_summary (god));
-      GNUNET_assert (NULL != context);
-      res = TMH_return_from_template (god->sc.con,
-                                      MHD_HTTP_PAYMENT_REQUIRED,
-                                      "request_payment",
-                                      god->hc->instance->settings.id,
-                                      taler_pay_uri,
-                                      context);
-      if (GNUNET_SYSERR == res)
+      qr = TMH_create_qrcode (taler_pay_uri);
+      if (NULL == qr)
       {
         GNUNET_break (0);
-        ret = MHD_NO;
+        return MHD_NO;
       }
-      ret = MHD_YES;
-      json_decref (context);
+      {
+        enum GNUNET_GenericReturnValue res;
+        json_t *context;
+
+        context = json_pack ("{s:s, s:s, s:s, s:s}",
+                             "taler_pay_uri",
+                             taler_pay_uri,
+                             "order_status_url",
+                             order_status_url,
+                             "taler_pay_qrcode_svg",
+                             qr,
+                             "order_summary",
+                             get_order_summary (god));
+        GNUNET_assert (NULL != context);
+        res = TMH_return_from_template (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);
+          ret = MHD_NO;
+        }
+        else
+        {
+          ret = MHD_YES;
+        }
+        json_decref (context);
+      }
+      GNUNET_free (qr);
     }
-    GNUNET_free (qr);
   }
-  else
+  else /* end of 'generate HTML' */
   {
     ret = TALER_MHD_reply_json_pack (god->sc.con,
                                      MHD_HTTP_PAYMENT_REQUIRED,
@@ -586,7 +614,6 @@ send_pay_request (struct GetOrderData *god,
                                      god->fulfillment_url,
                                      "already_paid_order_id",
                                      already_paid_order_id);
-
   }
   GNUNET_free (taler_pay_uri);
   GNUNET_free (order_status_url);
@@ -626,6 +653,7 @@ process_refunds_cb (void *cls,
               TALER_amount2s (refund_amount),
               TALER_B2S (coin_pub),
               reason);
+  god->refund_available |= pending;
   if (god->refunded)
   {
     GNUNET_assert (0 <=
@@ -636,7 +664,6 @@ process_refunds_cb (void *cls,
   }
   god->refund_amount = *refund_amount;
   god->refunded = true;
-  god->refund_available |= pending;
 }
 
 
@@ -794,6 +821,14 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
     }
   } /* end of first-time initialization / sanity checks */
 
+  if (god->suspended)
+  {
+    god->suspended = false;
+    GNUNET_CONTAINER_DLL_remove (god_head,
+                                 god_tail,
+                                 god);
+  }
+
   /* Convert order_id to h_contract_terms */
   TMH_db->preflight (TMH_db->cls);
   if (NULL == god->contract_terms)
@@ -1006,7 +1041,14 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
   if ( (NULL != god->session_id) &&
        (NULL != god->fulfillment_url) )
   {
-    /* Check if paid within a session. */
+    /* Check if client paid for this fulfillment article
+       already within this session, but using a different
+       order ID. If so, redirect the client to the order
+       it already paid.  Allows, for example, the case
+       where a mobile phone pays for a browser's session,
+       where the mobile phone has a different order
+       ID (because it purchased the article earlier)
+       than the one that the browser is waiting for. */
     char *already_paid_order_id = NULL;
 
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1045,7 +1087,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
       GNUNET_free (already_paid_order_id);
       return ret;
     }
-    GNUNET_break (1 == qs);
+    GNUNET_break (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs);
     GNUNET_free (already_paid_order_id);
   }
 
@@ -1066,7 +1108,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_GENERIC_DB_FETCH_FAILED,
-                                         "order status");
+                                         "lookup_order_status");
     }
     GNUNET_break (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs);
     if (! paid)
@@ -1095,7 +1137,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        TALER_EC_GENERIC_DB_FETCH_FAILED,
-                                       "refunds, detailed");
+                                       "lookup_refunds_detailed");
   }
 
   if ( ((god->sc.awaiting_refund) &&
@@ -1126,99 +1168,94 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
   }
 
   /* All operations done, build final response */
+  if (god->generate_html)
   {
-    if (god->generate_html)
+    enum GNUNET_GenericReturnValue res;
+
+    if (god->refund_available)
     {
-      enum GNUNET_GenericReturnValue res;
+      char *qr;
+      char *uri;
 
-      if (god->refund_available)
+      GNUNET_assert (NULL != god->contract_terms);
+      uri = make_taler_refund_uri (merchant_base_url,
+                                   order_id);
+      if (NULL == uri)
       {
-        char *qr;
-        char *uri;
-
-        GNUNET_assert (NULL != god->contract_terms);
-        uri = make_taler_refund_uri (merchant_base_url,
-                                     order_id);
-        if (NULL == uri)
-        {
-          GNUNET_break (0);
-          return TALER_MHD_reply_with_error (god->sc.con,
-                                             MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                             
TALER_EC_GENERIC_ALLOCATION_FAILURE,
-                                             "refund URI");
-        }
-        qr = TMH_create_qrcode (uri);
-        if (NULL == qr)
-        {
-          GNUNET_break (0);
-          GNUNET_free (uri);
-          return TALER_MHD_reply_with_error (god->sc.con,
-                                             MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                             
TALER_EC_GENERIC_ALLOCATION_FAILURE,
-                                             "qr code");
-        }
-        {
-          json_t *context;
-
-          context = json_pack ("{s:s, s:s, s:s, s:s}",
-                               "order_summary",
-                               get_order_summary (god),
-                               "refund_amount",
-                               TALER_amount2s (&god->refund_amount),
-                               "taler_refund_uri",
-                               uri,
-                               "taler_refund_qrcode_svg",
-                               qr);
-          GNUNET_assert (NULL != context);
-          res = TMH_return_from_template (god->sc.con,
-                                          MHD_HTTP_OK,
-                                          "offer_refund",
-                                          hc->instance->settings.id,
-                                          uri,
-                                          context);
-          json_decref (context);
-        }
+        GNUNET_break (0);
+        return TALER_MHD_reply_with_error (god->sc.con,
+                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                           TALER_EC_GENERIC_ALLOCATION_FAILURE,
+                                           "refund URI");
+      }
+      qr = TMH_create_qrcode (uri);
+      if (NULL == qr)
+      {
+        GNUNET_break (0);
         GNUNET_free (uri);
-        GNUNET_free (qr);
+        return TALER_MHD_reply_with_error (god->sc.con,
+                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                           TALER_EC_GENERIC_ALLOCATION_FAILURE,
+                                           "qr code");
       }
-      else
       {
         json_t *context;
 
-        context = json_pack ("{s:O, s:s, s:s}",
-                             "contract_terms",
-                             god->contract_terms,
+        context = json_pack ("{s:s, s:s, s:s, s:s}",
                              "order_summary",
                              get_order_summary (god),
                              "refund_amount",
-                             TALER_amount2s (&god->refund_amount));
+                             TALER_amount2s (&god->refund_amount),
+                             "taler_refund_uri",
+                             uri,
+                             "taler_refund_qrcode_svg",
+                             qr);
         GNUNET_assert (NULL != context);
         res = TMH_return_from_template (god->sc.con,
                                         MHD_HTTP_OK,
-                                        "show_order_details",
+                                        "offer_refund",
                                         hc->instance->settings.id,
-                                        NULL,
+                                        uri,
                                         context);
         json_decref (context);
       }
-      if (GNUNET_SYSERR == res)
-      {
-        GNUNET_break (0);
-        return MHD_NO;
-      }
-      return MHD_YES;
+      GNUNET_free (uri);
+      GNUNET_free (qr);
     }
     else
     {
-      return TALER_MHD_reply_json_pack (
-        connection,
-        MHD_HTTP_OK,
-        "{s:b, s:b, s:o}",
-        "refunded", god->refunded,
-        "refund_pending", god->refund_available,
-        "refund_amount", TALER_JSON_from_amount (&god->refund_amount));
+      json_t *context;
+
+      context = json_pack ("{s:O, s:s, s:s}",
+                           "contract_terms",
+                           god->contract_terms,
+                           "order_summary",
+                           get_order_summary (god),
+                           "refund_amount",
+                           TALER_amount2s (&god->refund_amount));
+      GNUNET_assert (NULL != context);
+      res = TMH_return_from_template (god->sc.con,
+                                      MHD_HTTP_OK,
+                                      "show_order_details",
+                                      hc->instance->settings.id,
+                                      NULL,
+                                      context);
+      json_decref (context);
+    }
+    if (GNUNET_SYSERR == res)
+    {
+      GNUNET_break (0);
+      return MHD_NO;
     }
+    return MHD_YES;
   }
+  return TALER_MHD_reply_json_pack (
+    connection,
+    MHD_HTTP_OK,
+    "{s:b, s:b, s:o}",
+    "refunded", god->refunded,
+    "refund_pending", god->refund_available,
+    "refund_amount", TALER_JSON_from_amount (&god->refund_amount));
 }
 
 
diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.h 
b/src/backend/taler-merchant-httpd_get-orders-ID.h
index b75e794f..67dd2a1a 100644
--- a/src/backend/taler-merchant-httpd_get-orders-ID.h
+++ b/src/backend/taler-merchant-httpd_get-orders-ID.h
@@ -24,6 +24,13 @@
 #include "taler-merchant-httpd.h"
 
 
+/**
+ * Force resuming all suspended order lookups, needed during shutdown.
+ */
+void
+TMH_force_wallet_get_order_resume (void);
+
+
 /**
  * Create a taler://pay/ URI for the given @a con and @a order_id
  * and @a session_id and @a instance_id.
diff --git a/src/backend/taler-merchant-httpd_private-get-orders-ID.c 
b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
index ed276b42..bf5e2f65 100644
--- a/src/backend/taler-merchant-httpd_private-get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
@@ -1045,6 +1045,17 @@ TMH_private_get_orders_ID (const struct 
TMH_RequestHandler *rh,
                                                     hc->instance->settings.id,
                                                     &claim_token,
                                                     NULL);
+      if ( (NULL == taler_pay_uri) ||
+           (NULL == order_status_url) )
+      {
+        GNUNET_break_op (0);
+        GNUNET_free (taler_pay_uri);
+        GNUNET_free (order_status_url);
+        return TALER_MHD_reply_with_error (connection,
+                                           MHD_HTTP_BAD_REQUEST,
+                                           
TALER_EC_GENERIC_HTTP_HEADERS_MALFORMED,
+                                           "host");
+      }
       ret = TALER_MHD_reply_json_pack (connection,
                                        MHD_HTTP_OK,
                                        "{s:s, s:s, s:s, s:s, s:s"

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]