gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 127/277: implement reserve deletion


From: gnunet
Subject: [taler-merchant] 127/277: implement reserve deletion
Date: Sun, 05 Jul 2020 20:50:40 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

commit 3d6cce7434847d925b51d1600f0eef79041c6591
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Wed May 20 17:20:40 2020 +0200

    implement reserve deletion
---
 src/backend/Makefile.am                            |   4 +
 src/backend/taler-merchant-httpd.c                 |  68 ++++-
 ...ler-merchant-httpd_private-delete-reserves-ID.c | 100 +++++++
 ...ler-merchant-httpd_private-delete-reserves-ID.h |  41 +++
 ...-httpd_private-post-reserves-ID-authorize-tip.c | 307 ++++++++-------------
 ...-httpd_private-post-reserves-ID-authorize-tip.h |  45 +--
 src/include/taler_merchantdb_plugin.h              |  63 ++---
 7 files changed, 371 insertions(+), 257 deletions(-)

diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index b493e3a..16b6ea6 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -31,6 +31,8 @@ taler_merchant_httpd_SOURCES = \
     taler-merchant-httpd_private-delete-products-ID.h \
   taler-merchant-httpd_private-delete-orders-ID.c \
     taler-merchant-httpd_private-delete-orders-ID.h \
+  taler-merchant-httpd_private-delete-reserves-ID.c \
+    taler-merchant-httpd_private-delete-reserves-ID.h \
   taler-merchant-httpd_private-get-instances.c \
     taler-merchant-httpd_private-get-instances.h \
   taler-merchant-httpd_private-get-instances-ID.c \
@@ -57,6 +59,8 @@ taler_merchant_httpd_SOURCES = \
     taler-merchant-httpd_private-post-products-ID-lock.h \
   taler-merchant-httpd_private-post-reserves.c \
     taler-merchant-httpd_private-post-reserves.h \
+  taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c \
+    taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h \
   taler-merchant-httpd_private-post-orders-ID-refund.c \
     taler-merchant-httpd_private-post-orders-ID-refund.h \
   taler-merchant-httpd_private-post-orders.c \
diff --git a/src/backend/taler-merchant-httpd.c 
b/src/backend/taler-merchant-httpd.c
index 32732bd..7f06390 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -32,6 +32,7 @@
 #include "taler-merchant-httpd_private-delete-instances-ID.h"
 #include "taler-merchant-httpd_private-delete-products-ID.h"
 #include "taler-merchant-httpd_private-delete-orders-ID.h"
+#include "taler-merchant-httpd_private-delete-reserves-ID.h"
 #include "taler-merchant-httpd_private-get-instances.h"
 #include "taler-merchant-httpd_private-get-instances-ID.h"
 #include "taler-merchant-httpd_private-get-products.h"
@@ -48,6 +49,7 @@
 #include "taler-merchant-httpd_private-post-products.h"
 #include "taler-merchant-httpd_private-post-products-ID-lock.h"
 #include "taler-merchant-httpd_private-post-reserves.h"
+#include "taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h"
 #include "taler-merchant-httpd_private-post-transfers.h"
 #include "taler-merchant-httpd_post-orders-ID-abort.h"
 #include "taler-merchant-httpd_post-orders-ID-claim.h"
@@ -841,6 +843,28 @@ url_handler (void *cls,
       .method = MHD_HTTP_METHOD_POST,
       .handler = &TMH_private_post_reserves
     },
+    /* DELETE /reserves/$ID: */
+    {
+      .url_prefix = "/reserves",
+      .have_id_segment = true,
+      .method = MHD_HTTP_METHOD_DELETE,
+      .handler = &TMH_private_delete_reserves_ID
+    },
+    /* POST /reserves/$ID/authorize-tip: */
+    {
+      .url_prefix = "/reserves",
+      .url_suffix = "authorize-tip",
+      .have_id_segment = true,
+      .method = MHD_HTTP_METHOD_POST,
+      .handler = &TMH_private_post_reserves_ID_authorize_tip
+    },
+    /* POST /reserves/authorize-tip: */
+    {
+      .url_prefix = "/reserves",
+      .url_suffix = "authorize-tip",
+      .method = MHD_HTTP_METHOD_POST,
+      .handler = &TMH_private_post_reserves_authorize_tip
+    },
     /* GET /reserves: */
     {
       .url_prefix = "/reserves",
@@ -1111,18 +1135,35 @@ url_handler (void *cls,
                            rh->url_prefix,
                            prefix_strlen)) )
           continue;
-        if ( (NULL == infix_url)
-             ^ (GNUNET_NO == rh->have_id_segment) )
-          continue; /* infix existence missmatch */
-        if ( ( (NULL == suffix_url)
-               ^ (NULL == rh->url_suffix) ) )
-          continue; /* suffix existence missmatch */
-        if ( (NULL != suffix_url) &&
-             ( (suffix_strlen != strlen (rh->url_suffix)) ||
-               (0 != memcmp (suffix_url,
-                             rh->url_suffix,
-                             suffix_strlen)) ) )
-          continue; /* suffix content missmatch */
+        if (GNUNET_NO == rh->have_id_segment)
+        {
+          if (NULL != suffix_url)
+            continue; /* too many segments to match */
+          if ( (NULL == infix_url)
+               ^ (NULL == rh->url_suffix) )
+            continue; /* suffix existence missmatch */
+          if ( (NULL != infix_url) &&
+               ( (infix_strlen != strlen (rh->url_suffix)) ||
+                 (0 != memcmp (infix_url,
+                               rh->url_suffix,
+                               infix_strlen)) ) )
+            continue; /* cannot use infix as suffix: content missmatch */
+        }
+        else
+        {
+          if ( (NULL == infix_url)
+               ^ (GNUNET_NO == rh->have_id_segment) )
+            continue; /* infix existence missmatch */
+          if ( ( (NULL == suffix_url)
+                 ^ (NULL == rh->url_suffix) ) )
+            continue; /* suffix existence missmatch */
+          if ( (NULL != suffix_url) &&
+               ( (suffix_strlen != strlen (rh->url_suffix)) ||
+                 (0 != memcmp (suffix_url,
+                               rh->url_suffix,
+                               suffix_strlen)) ) )
+            continue; /* suffix content missmatch */
+        }
         url_found = true;
         if (0 == strcasecmp (method,
                              MHD_HTTP_METHOD_OPTIONS))
@@ -1130,7 +1171,8 @@ url_handler (void *cls,
           return TALER_MHD_reply_cors_preflight (connection);
         }
         if ( (rh->method != NULL) &&
-             (0 != strcasecmp (method, rh->method)) )
+             (0 != strcasecmp (method,
+                               rh->method)) )
           continue;
         hc->rh = rh;
         break;
diff --git a/src/backend/taler-merchant-httpd_private-delete-reserves-ID.c 
b/src/backend/taler-merchant-httpd_private-delete-reserves-ID.c
new file mode 100644
index 0000000..ba2c08b
--- /dev/null
+++ b/src/backend/taler-merchant-httpd_private-delete-reserves-ID.c
@@ -0,0 +1,100 @@
+/*
+  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 <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file backend/taler-merchant-httpd_private-delete-reserves-ID.c
+ * @brief implement DELETE /reserves/$ID
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler-merchant-httpd_private-delete-reserves-ID.h"
+#include <taler/taler_json_lib.h>
+
+
+/**
+ * Handle a DELETE "/reserves/$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_reserves_ID (const struct TMH_RequestHandler *rh,
+                                struct MHD_Connection *connection,
+                                struct TMH_HandlerContext *hc)
+{
+  struct TMH_MerchantInstance *mi = hc->instance;
+  enum GNUNET_DB_QueryStatus qs;
+  struct TALER_ReservePublicKeyP reserve_pub;
+  const char *purge;
+
+  if (GNUNET_OK !=
+      GNUNET_STRINGS_string_to_data (hc->infix,
+                                     strlen (hc->infix),
+                                     &reserve_pub,
+                                     sizeof (reserve_pub)))
+  {
+    GNUNET_break_op (0);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       TALER_EC_RESERVES_INVALID_RESERVE_PUB,
+                                       "reserve public key malformed");
+  }
+  purge = MHD_lookup_connection_value (connection,
+                                       MHD_GET_ARGUMENT_KIND,
+                                       "purge");
+  GNUNET_assert (NULL != mi);
+  if ( (NULL != purge) &&
+       (0 == strcmp (purge,
+                     "yes")) )
+    qs = TMH_db->purge_reserve (TMH_db->cls,
+                                mi->settings.id,
+                                &reserve_pub);
+  else
+    qs = TMH_db->delete_reserve (TMH_db->cls,
+                                 mi->settings.id,
+                                 &reserve_pub);
+  switch (qs)
+  {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                       
TALER_EC_RESERVES_DELETE_DB_HARD_FAILURE,
+                                       "Transaction failed");
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    GNUNET_break (0);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                       TALER_EC_INTERNAL_INVARIANT_FAILURE,
+                                       "Serialization error for single SQL 
statement");
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       
TALER_EC_RESERVES_DELETE_NO_SUCH_RESERVE,
+                                       "Reserve unknown");
+  case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+    return TALER_MHD_reply_static (connection,
+                                   MHD_HTTP_NO_CONTENT,
+                                   NULL,
+                                   NULL,
+                                   0);
+  }
+  GNUNET_assert (0);
+  return MHD_NO;
+}
+
+
+/* end of taler-merchant-httpd_private-delete-reserves-ID.c */
diff --git a/src/backend/taler-merchant-httpd_private-delete-reserves-ID.h 
b/src/backend/taler-merchant-httpd_private-delete-reserves-ID.h
new file mode 100644
index 0000000..b961d0d
--- /dev/null
+++ b/src/backend/taler-merchant-httpd_private-delete-reserves-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 <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file backend/taler-merchant-httpd_private-delete-reserves-ID.h
+ * @brief implement DELETE /reserves/$ID/
+ * @author Christian Grothoff
+ */
+#ifndef TALER_MERCHANT_HTTPD_PRIVATE_DELETE_RESERVES_ID_H
+#define TALER_MERCHANT_HTTPD_PRIVATE_DELETE_RESERVES_ID_H
+
+#include "taler-merchant-httpd.h"
+
+
+/**
+ * Handle a DELETE "/reserves/$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_reserves_ID (const struct TMH_RequestHandler *rh,
+                                struct MHD_Connection *connection,
+                                struct TMH_HandlerContext *hc);
+
+/* end of taler-merchant-httpd_private-delete-reserves-ID.h */
+#endif
diff --git 
a/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c 
b/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c
index a0f2ec3..9193669 100644
--- a/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c
+++ b/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  (C) 2014-2017 Taler Systems SA
+  (C) 2014-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
@@ -14,7 +14,7 @@
   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
 /**
- * @file backend/taler-merchant-httpd_tip-authorize.c
+ * @file backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c
  * @brief implement API for authorizing tips to be paid to visitors
  * @author Christian Grothoff
  */
@@ -24,149 +24,41 @@
 #include <taler/taler_json_lib.h>
 #include "taler-merchant-httpd.h"
 #include "taler-merchant-httpd_mhd.h"
-#include "taler-merchant-httpd_exchanges.h"
-#include "taler-merchant-httpd_tip-authorize.h"
-#include "taler-merchant-httpd_tip-reserve-helper.h"
-
-
-struct TipAuthContext
-{
-  /**
-   * This field MUST be first for handle_mhd_completion_callback() to work
-   * when it treats this struct as a `struct TM_HandlerContext`.
-   */
-  struct TM_HandlerContext hc;
-
-  /**
-   * Placeholder for #TALER_MHD_parse_post_json() to keep its internal state.
-   */
-  void *json_parse_context;
-
-  /**
-   * Justification to use.
-   */
-  const char *justification;
-
-  /**
-   * JSON request received.
-   */
-  json_t *root;
-
-  /**
-   * Context for checking the tipping reserve's status.
-   */
-  struct TMH_CheckTipReserve ctr;
-
-  /**
-   * Tip amount requested.
-   */
-  struct TALER_Amount amount;
-
-  /**
-   * Flag set to #GNUNET_YES when we have tried /reserve/status of the
-   * tipping reserve already.
-   */
-  int checked_status;
-
-  /**
-   * Flag set to #GNUNET_YES when we have parsed the incoming JSON already.
-   */
-  int parsed_json;
-
-};
+#include "taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h"
 
 
 /**
- * Custom cleanup routine for a `struct TipAuthContext`.
- *
- * @param hc the `struct TMH_JsonParseContext` to clean up.
- */
-static void
-cleanup_tac (struct TM_HandlerContext *hc)
-{
-  struct TipAuthContext *tac = (struct TipAuthContext *) hc;
-
-  if (NULL != tac->root)
-  {
-    json_decref (tac->root);
-    tac->root = NULL;
-  }
-  TMH_check_tip_reserve_cleanup (&tac->ctr);
-  TALER_MHD_parse_post_cleanup_callback (tac->json_parse_context);
-  GNUNET_free (tac);
-}
-
-
-/**
- * Handle a "/tip-authorize" request.
+ * Handle a "tip-authorize" request.
  *
  * @param rh context of the handler
  * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @param mi merchant backend instance, never NULL
+ * @param[in,out] hc context with further information about the request
+ * @param reserve_pub reserve to use, or NULL for "any"
  * @return MHD result code
  */
-MHD_RESULT
-MH_handler_tip_authorize (struct TMH_RequestHandler *rh,
-                          struct MHD_Connection *connection,
-                          void **connection_cls,
-                          const char *upload_data,
-                          size_t *upload_data_size,
-                          struct MerchantInstance *mi)
+static MHD_RESULT
+authorize_tip (const struct TMH_RequestHandler *rh,
+               struct MHD_Connection *connection,
+               struct TMH_HandlerContext *hc,
+               const struct TALER_ReservePublicKeyP *reserve_pub)
 {
-  struct TipAuthContext *tac;
-  enum GNUNET_GenericReturnValue res;
   enum TALER_ErrorCode ec;
   struct GNUNET_TIME_Absolute expiration;
   struct GNUNET_HashCode tip_id;
-  json_t *extra;
-
-  if (NULL == *connection_cls)
-  {
-    tac = GNUNET_new (struct TipAuthContext);
-    tac->hc.cc = &cleanup_tac;
-    tac->ctr.connection = connection;
-    *connection_cls = tac;
-  }
-  else
-  {
-    tac = *connection_cls;
-  }
-  if (NULL != tac->ctr.response)
-  {
-    MHD_RESULT ret;
-
-    ret = MHD_queue_response (connection,
-                              tac->ctr.response_code,
-                              tac->ctr.response);
-    MHD_destroy_response (tac->ctr.response);
-    tac->ctr.response = NULL;
-    return ret;
-  }
-  if (GNUNET_NO == tac->parsed_json)
+  const char *justification;
+  const char *next_url;
+  struct TALER_Amount amount;
   {
     struct GNUNET_JSON_Specification spec[] = {
-      TALER_JSON_spec_amount ("amount", &tac->amount),
-      GNUNET_JSON_spec_string ("justification", &tac->justification),
+      TALER_JSON_spec_amount ("amount", &amount),
+      GNUNET_JSON_spec_string ("justification", &justification),
+      GNUNET_JSON_spec_string ("next_url", &next_url),
       GNUNET_JSON_spec_end ()
     };
-
-    res = TALER_MHD_parse_post_json (connection,
-                                     &tac->json_parse_context,
-                                     upload_data,
-                                     upload_data_size,
-                                     &tac->root);
-    if (GNUNET_SYSERR == res)
-      return MHD_NO;
-    /* the POST's body has to be further fetched */
-    if ( (GNUNET_NO == res) ||
-         (NULL == tac->root) )
-      return MHD_YES;
+    enum GNUNET_GenericReturnValue res;
 
     res = TALER_MHD_parse_json_data (connection,
-                                     tac->root,
+                                     hc->request_body,
                                      spec);
     if (GNUNET_YES != res)
     {
@@ -175,51 +67,17 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh,
              ? MHD_YES
              : MHD_NO;
     }
-    tac->parsed_json = GNUNET_YES;
-  }
-
-  if (NULL == mi->tip_exchange)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Instance `%s' not configured for tipping\n",
-                mi->id);
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_PRECONDITION_FAILED,
-                                       
TALER_EC_TIP_AUTHORIZE_INSTANCE_DOES_NOT_TIP,
-                                       "exchange for tipping not configured 
for the instance");
-  }
-  tac->ctr.reserve_priv = mi->tip_reserve;
-  extra = json_object_get (tac->root, "extra");
-  if (NULL == extra)
-    extra = json_object ();
-  else
-    json_incref (extra);
-
-
-  db->preflight (db->cls);
-  ec = db->authorize_tip_TR (db->cls,
-                             tac->justification,
-                             extra,
-                             &tac->amount,
-                             &mi->tip_reserve,
-                             mi->tip_exchange,
-                             &expiration,
-                             &tip_id);
-  json_decref (extra);
-  /* If we have insufficient funds according to OUR database,
-     check with exchange to see if the reserve has been topped up
-     in the meantime (or if tips were not withdrawn yet). */
-  if ( (TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS == ec) &&
-       (GNUNET_NO == tac->checked_status) )
-  {
-    tac->checked_status = GNUNET_YES;
-    tac->ctr.none_authorized = GNUNET_YES;
-    TMH_check_tip_reserve (&tac->ctr,
-                           mi->tip_exchange);
-    return MHD_YES;
   }
-
-  /* handle irrecoverable errors */
+  TMH_db->preflight (TMH_db->cls);
+  ec = TMH_db->authorize_tip (TMH_db->cls,
+                              hc->instance->settings.id,
+                              reserve_pub,
+                              &amount,
+                              justification,
+                              next_url,
+                              &tip_id,
+                              &expiration);
+  /* handle errors */
   if (TALER_EC_NONE != ec)
   {
     unsigned int rc;
@@ -233,7 +91,7 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh,
       break;
     case TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED:
       msg = "Failed to approve tip: merchant's tipping reserve expired";
-      rc = MHD_HTTP_PRECONDITION_FAILED;
+      rc = MHD_HTTP_GONE;
       break;
     case TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN:
       msg = "Failed to approve tip: merchant's tipping reserve does not exist";
@@ -257,21 +115,21 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh,
     const char *host;
     const char *forwarded_host;
     const char *uri_path;
-    const char *uri_instance_id;
     struct GNUNET_CRYPTO_HashAsciiEncoded hash_enc;
+    MHD_RESULT res;
 
-    host = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, "Host");
-    forwarded_host = MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
+    host = MHD_lookup_connection_value (connection,
+                                        MHD_HEADER_KIND,
+                                        "Host");
+    forwarded_host = MHD_lookup_connection_value (connection,
+                                                  MHD_HEADER_KIND,
                                                   "X-Forwarded-Host");
 
-    uri_path = MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
+    uri_path = MHD_lookup_connection_value (connection,
+                                            MHD_HEADER_KIND,
                                             "X-Forwarded-Prefix");
-    if (NULL == uri_path)
-      uri_path = "-";
-
     if (NULL != forwarded_host)
       host = forwarded_host;
-
     if (NULL == host)
     {
       /* Should never happen, at last the host header should be defined */
@@ -282,27 +140,84 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh,
                                          "unable to identify backend host");
     }
 
-    if (0 == strcmp (mi->id, "default"))
-      uri_instance_id = "-";
-    else
-      uri_instance_id = mi->id;
-
-    GNUNET_CRYPTO_hash_to_enc (&tip_id, &hash_enc);
-
+    GNUNET_CRYPTO_hash_to_enc (&tip_id,
+                               &hash_enc);
     GNUNET_assert (0 < GNUNET_asprintf (&taler_tip_uri,
-                                        "taler://tip/%s/%s/%s/%s",
+                                        "taler://tip/%s/%s%sinstances/%s/%s",
                                         host,
-                                        uri_path,
-                                        uri_instance_id,
+                                        (NULL == uri_path) ? "" : uri_path,
+                                        (NULL == uri_path) ? "" : "/",
+                                        hc->instance->settings.id,
                                         hash_enc.encoding));
+    res = TALER_MHD_reply_json_pack (connection,
+                                     MHD_HTTP_OK,
+                                     "{s:s, s:s, s:o}",
+                                     "tip_id",
+                                     hash_enc.encoding,
+                                     "tip_redirect_url",
+                                     taler_tip_uri,
+                                     "tip_expiration",
+                                     GNUNET_JSON_from_time_abs (expiration));
+    GNUNET_free (taler_tip_uri);
+    return res;
+  }
+}
+
 
-    return TALER_MHD_reply_json_pack (connection,
-                                      MHD_HTTP_OK,
-                                      "{s:s, s:s}",
-                                      "taler_tip_uri", taler_tip_uri,
-                                      "tip_id", hash_enc.encoding);
+/**
+ * Handle a "/reserves/$ID/tip-authorize" 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_post_reserves_ID_authorize_tip (const struct TMH_RequestHandler 
*rh,
+                                            struct MHD_Connection *connection,
+                                            struct TMH_HandlerContext *hc)
+{
+  struct TALER_ReservePublicKeyP reserve_pub;
+
+  if (GNUNET_OK !=
+      GNUNET_STRINGS_string_to_data (hc->infix,
+                                     strlen (hc->infix),
+                                     &reserve_pub,
+                                     sizeof (reserve_pub)))
+  {
+    GNUNET_break_op (0);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       TALER_EC_RESERVES_INVALID_RESERVE_PUB,
+                                       "reserve public key malformed");
   }
+  return authorize_tip (rh,
+                        connection,
+                        hc,
+                        &reserve_pub);
+}
+
+
+/**
+ * Handle a "/reserves/tip-authorize" request.
+ * Here the client does not specify the reserve public key, so we
+ * are free to pick "any" available reserve.
+ *
+ * @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_reserves_authorize_tip (const struct TMH_RequestHandler *rh,
+                                         struct MHD_Connection *connection,
+                                         struct TMH_HandlerContext *hc)
+{
+  return authorize_tip (rh,
+                        connection,
+                        hc,
+                        NULL);
 }
 
 
-/* end of taler-merchant-httpd_tip-authorize.c */
+/* end of taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c */
diff --git 
a/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h 
b/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h
index 1f7f44e..2df5529 100644
--- a/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h
+++ b/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  (C) 2017 Taler Systems SA
+  (C) 2017, 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
@@ -14,33 +14,44 @@
   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
 /**
- * @file backend/taler-merchant-httpd_tip-authorize.h
- * @brief headers for /tip-authorize handler
+ * @file backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.h
+ * @brief headers for /reserves/ID/tip-authorize
  * @author Christian Grothoff
  */
-#ifndef TALER_MERCHANT_HTTPD_TIP_AUTHORIZE_H
-#define TALER_MERCHANT_HTTPD_TIP_AUTHORIZE_H
+#ifndef TALER_MERCHANT_HTTPD_PRIVATE_POST_RESERVES_ID_AUTHORIZE_TIP_H
+#define TALER_MERCHANT_HTTPD_PRIVATE_POST_RESERVES_ID_AUTHORIZE_TIP_H
 #include <microhttpd.h>
 #include "taler-merchant-httpd.h"
 
+
 /**
- * Manages a /tip-authorize call, creating a TIP ID and storing the
- * authorization in our DB.
+ * Handle a "/reserves/$ID/tip-authorize" request.
  *
  * @param rh context of the handler
  * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @param mi merchant backend instance, never NULL
+ * @param[in,out] hc context with further information about the request
  * @return MHD result code
  */
 MHD_RESULT
-MH_handler_tip_authorize (struct TMH_RequestHandler *rh,
-                          struct MHD_Connection *connection,
-                          void **connection_cls,
-                          const char *upload_data,
-                          size_t *upload_data_size,
-                          struct MerchantInstance *mi);
+TMH_private_post_reserves_ID_authorize_tip (const struct TMH_RequestHandler 
*rh,
+                                            struct MHD_Connection *connection,
+                                            struct TMH_HandlerContext *hc);
+
+
+/**
+ * Handle a "/reserves/tip-authorize" request.
+ * Here the client does not specify the reserve public key, so we
+ * are free to pick "any" available reserve.
+ *
+ * @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_reserves_authorize_tip (const struct TMH_RequestHandler *rh,
+                                         struct MHD_Connection *connection,
+                                         struct TMH_HandlerContext *hc);
+
 
 #endif
diff --git a/src/include/taler_merchantdb_plugin.h 
b/src/include/taler_merchantdb_plugin.h
index b51fce8..0960fb9 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -1630,6 +1630,38 @@ struct TALER_MERCHANTDB_Plugin
                    const struct TALER_ReservePublicKeyP *reserve_pub);
 
 
+  /**
+   * Authorize a tip over @a amount from reserve @a reserve_pub.  Remember
+   * the authorization under @a tip_id for later, together with the
+   * @a justification.
+   *
+   * @param cls closure, typically a connection to the db
+   * @param instance_id which instance should generate the tip
+   * @param reserve_pub which reserve is debited, NULL to pick one in the DB
+   * @param amount how high is the tip (with fees)
+   * @param justification why was the tip approved
+   * @param next_url where to send the URL post tip pickup
+   * @param[out] tip_id set to the unique ID for the tip
+   * @param[out] expiration set to when the tip expires
+   * @return transaction status,
+   *      #TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED if the reserve is known but 
has expired
+   *      #TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN if the reserve is not known
+   *      #TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS if the reserve has 
insufficient funds left
+   *      #TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR on hard DB errors
+   *      #TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR on soft DB errors (client 
should retry)
+   *      #TALER_EC_NONE upon success
+   */
+  enum TALER_ErrorCode
+  (*authorize_tip)(void *cls,
+                   const char *instance_id,
+                   const struct TALER_ReservePublicKeyP *reserve_pub,
+                   const struct TALER_Amount *amount,
+                   const char *justification,
+                   const char *next_url,
+                   struct GNUNET_HashCode *tip_id,
+                   struct GNUNET_TIME_Absolute *expiration);
+
+
   /* ****************** OLD API ******************** */
 
 
@@ -1898,37 +1930,6 @@ struct TALER_MERCHANTDB_Plugin
                            struct GNUNET_TIME_Absolute expiration);
 
 
-  /**
-   * Authorize a tip over @a amount from reserve @a reserve_priv.  Remember
-   * the authorization under @a tip_id for later, together with the
-   * @a justification.
-   *
-   * @param cls closure, typically a connection to the db
-   * @param justification why was the tip approved
-   * @param extra extra data that will be given to the customer's wallet
-   * @param amount how high is the tip (with fees)
-   * @param reserve_priv which reserve is debited
-   * @param exchange_url which exchange manages the tip
-   * @param[out] expiration set to when the tip expires
-   * @param[out] tip_id set to the unique ID for the tip
-   * @return transaction status,
-   *      #TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED if the reserve is known but 
has expired
-   *      #TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN if the reserve is not known
-   *      #TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS if the reserve has 
insufficient funds left
-   *      #TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR on hard DB errors
-   *      #TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR on soft DB errors (client 
should retry)
-   *      #TALER_EC_NONE upon success
-   */
-  enum TALER_ErrorCode
-  (*authorize_tip_TR)(void *cls,
-                      const char *justification,
-                      const json_t *extra,
-                      const struct TALER_Amount *amount,
-                      const struct TALER_ReservePrivateKeyP *reserve_priv,
-                      const char *exchange_url,
-                      struct GNUNET_TIME_Absolute *expiration,
-                      struct GNUNET_HashCode *tip_id);
-
   /**
    * Get the total amount of authorized tips for a tipping reserve.
    *

-- 
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]