gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 118/277: implement POST /reserves


From: gnunet
Subject: [taler-merchant] 118/277: implement POST /reserves
Date: Sun, 05 Jul 2020 20:50:31 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

commit 49bb51daf5486817c3adc8a63137de1ec9d98589
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Mon May 18 19:11:08 2020 +0200

    implement POST /reserves
---
 src/backend/Makefile.am                            |   2 +
 src/backend/taler-merchant-httpd.c                 |  11 +-
 src/backend/taler-merchant-httpd_auditors.c        |   6 +-
 src/backend/taler-merchant-httpd_auditors.h        |   4 +-
 src/backend/taler-merchant-httpd_exchanges.c       | 111 ++++----
 src/backend/taler-merchant-httpd_exchanges.h       |   6 +-
 src/backend/taler-merchant-httpd_get-orders-ID.c   |   7 +-
 .../taler-merchant-httpd_post-orders-ID-abort.c    |   8 +-
 .../taler-merchant-httpd_post-orders-ID-pay.c      |   7 +-
 .../taler-merchant-httpd_private-post-reserves.c   | 288 +++++++++++++++++++++
 .../taler-merchant-httpd_private-post-reserves.h   |  50 ++++
 .../taler-merchant-httpd_private-post-transfers.c  |   6 +-
 src/include/taler_merchantdb_plugin.h              |  26 ++
 13 files changed, 465 insertions(+), 67 deletions(-)

diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index 3127ab2..bba5088 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -53,6 +53,8 @@ taler_merchant_httpd_SOURCES = \
     taler-merchant-httpd_private-post-products.h \
   taler-merchant-httpd_private-post-products-ID-lock.c \
     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-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 b280386..92334bb 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -42,10 +42,11 @@
 #include "taler-merchant-httpd_private-patch-instances-ID.h"
 #include "taler-merchant-httpd_private-patch-products-ID.h"
 #include "taler-merchant-httpd_private-post-instances.h"
-#include "taler-merchant-httpd_private-post-products.h"
-#include "taler-merchant-httpd_private-post-products-ID-lock.h"
 #include "taler-merchant-httpd_private-post-orders.h"
 #include "taler-merchant-httpd_private-post-orders-ID-refund.h"
+#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-transfers.h"
 #include "taler-merchant-httpd_post-orders-ID-abort.h"
 #include "taler-merchant-httpd_post-orders-ID-claim.h"
@@ -833,6 +834,12 @@ url_handler (void *cls,
       .have_id_segment = true,
       .handler = &TMH_private_post_orders_ID_refund
     },
+    /* POST /reserves: */
+    {
+      .url_prefix = "/reserves",
+      .method = MHD_HTTP_METHOD_POST,
+      .handler = &TMH_private_post_reserves
+    },
     /* POST /transfers: */
     {
       .url_prefix = "/transfers",
diff --git a/src/backend/taler-merchant-httpd_auditors.c 
b/src/backend/taler-merchant-httpd_auditors.c
index 225fa15..05690a9 100644
--- a/src/backend/taler-merchant-httpd_auditors.c
+++ b/src/backend/taler-merchant-httpd_auditors.c
@@ -69,7 +69,7 @@ json_t *j_auditors;
  *
  * @param mh exchange issuing @a dk
  * @param dk a denomination issued by @a mh
- * @param exchange_trusted #GNUNET_YES if the exchange of @a dk is trusted by 
config
+ * @param exchange_trusted true if the exchange of @a dk is trusted by config
  * @param[out] hc HTTP status code to return (on error)
  * @param[out] ec Taler error code to return (on error)
  * @return #GNUNET_OK
@@ -77,7 +77,7 @@ json_t *j_auditors;
 int
 TMH_AUDITORS_check_dk (struct TALER_EXCHANGE_Handle *mh,
                        const struct TALER_EXCHANGE_DenomPublicKey *dk,
-                       int exchange_trusted,
+                       bool exchange_trusted,
                        unsigned int *hc,
                        enum TALER_ErrorCode *ec)
 {
@@ -92,7 +92,7 @@ TMH_AUDITORS_check_dk (struct TALER_EXCHANGE_Handle *mh,
     *ec = TALER_EC_PAY_DENOMINATION_DEPOSIT_EXPIRED;
     return GNUNET_SYSERR; /* expired */
   }
-  if (GNUNET_YES == exchange_trusted)
+  if (exchange_trusted)
   {
     *ec = TALER_EC_NONE;
     *hc = MHD_HTTP_OK;
diff --git a/src/backend/taler-merchant-httpd_auditors.h 
b/src/backend/taler-merchant-httpd_auditors.h
index 4a1a0b6..4786b80 100644
--- a/src/backend/taler-merchant-httpd_auditors.h
+++ b/src/backend/taler-merchant-httpd_auditors.h
@@ -53,7 +53,7 @@ TMH_AUDITORS_init (const struct GNUNET_CONFIGURATION_Handle 
*cfg);
  *
  * @param mh exchange issuing @a dk
  * @param dk a denomination issued by @a mh
- * @param exchange_trusted #GNUNET_YES if the exchange of @a dk is trusted by 
config
+ * @param exchange_trusted true if the exchange of @a dk is trusted by config
  * @param[out] hc set to the HTTP status code to return
  * @param[out] ec set to the Taler error code to return
  * @return #GNUNET_OK on success
@@ -61,7 +61,7 @@ TMH_AUDITORS_init (const struct GNUNET_CONFIGURATION_Handle 
*cfg);
 int
 TMH_AUDITORS_check_dk (struct TALER_EXCHANGE_Handle *mh,
                        const struct TALER_EXCHANGE_DenomPublicKey *dk,
-                       int exchange_trusted,
+                       bool exchange_trusted,
                        unsigned int *hc,
                        enum TALER_ErrorCode *ec);
 
diff --git a/src/backend/taler-merchant-httpd_exchanges.c 
b/src/backend/taler-merchant-httpd_exchanges.c
index fe4085d..24b5202 100644
--- a/src/backend/taler-merchant-httpd_exchanges.c
+++ b/src/backend/taler-merchant-httpd_exchanges.c
@@ -129,6 +129,11 @@ struct FeesByWireMethod
    */
   char *wire_method;
 
+  /**
+   * Full payto URI of the exchange.
+   */
+  char *payto_uri;
+
   /**
    * Applicable fees, NULL if unknown/error.
    */
@@ -220,18 +225,18 @@ struct Exchange
   struct GNUNET_SCHEDULER_Task *retry_task;
 
   /**
-   * #GNUNET_YES to indicate that there is an ongoing
+   * true to indicate that there is an ongoing
    * transfer we are waiting for,
-   * #GNUNET_NO to indicate that key data is up-to-date.
+   * false to indicate that key data is up-to-date.
    */
-  int pending;
+  bool pending;
 
   /**
-   * #GNUNET_YES if this exchange is from our configuration and
-   * explicitly trusted, #GNUNET_NO if we need to check each
+   * true if this exchange is from our configuration and
+   * explicitly trusted, false if we need to check each
    * key to be sure it is trusted.
    */
-  int trusted;
+  bool trusted;
 
 };
 
@@ -322,10 +327,12 @@ retry_exchange (void *cls)
 /**
  * Function called with information about the wire fees
  * for each wire method.  Stores the wire fees with the
- * exchange for laster use.
+ * exchange for later use.
  *
  * @param cls closure
- * @param wire_method name of the wire method (i.e. "sepa")
+ * @param master_pub public key of the exchange
+ * @param wire_method name of the wire method (i.e. "iban")
+ * @param payto_uri full payto URI of the exchange
  * @param fees fee structure for this method
  * @return #TALER_EC_NONE on success
  */
@@ -333,6 +340,7 @@ static enum TALER_ErrorCode
 process_wire_fees (struct Exchange *exchange,
                    const struct TALER_MasterPublicKeyP *master_pub,
                    const char *wire_method,
+                   const char *payto_uri,
                    const struct TALER_EXCHANGE_WireAggregateFees *fees)
 {
   struct FeesByWireMethod *f;
@@ -347,6 +355,7 @@ process_wire_fees (struct Exchange *exchange,
   {
     f = GNUNET_new (struct FeesByWireMethod);
     f->wire_method = GNUNET_strdup (wire_method);
+    f->payto_uri = GNUNET_strdup (payto_uri);
     GNUNET_CONTAINER_DLL_insert (exchange->wire_fees_head,
                                  exchange->wire_fees_tail,
                                  f);
@@ -443,7 +452,7 @@ process_wire_fees (struct Exchange *exchange,
 
 /**
  * Function called with information about the wire accounts
- * of the exchanage.  Stores the wire fees with the
+ * of the exchange.  Stores the wire fees with the
  * exchange for laster use.
  *
  * @param exchange the exchange
@@ -473,6 +482,7 @@ process_wire_accounts (struct Exchange *exchange,
     ec = process_wire_fees (exchange,
                             master_pub,
                             method,
+                            accounts[i].payto_uri,
                             accounts[i].fees);
     GNUNET_free (method);
     if (TALER_EC_NONE != ec)
@@ -490,7 +500,7 @@ process_wire_accounts (struct Exchange *exchange,
  * @param wire_method the wire method we want the fees for
  * @return NULL if we do not have fees for this method yet
  */
-static struct TALER_EXCHANGE_WireAggregateFees *
+static struct FeesByWireMethod *
 get_wire_fees (struct Exchange *exchange,
                struct GNUNET_TIME_Absolute now,
                const char *wire_method)
@@ -511,7 +521,7 @@ get_wire_fees (struct Exchange *exchange,
         fbw->af = af->next;
         GNUNET_free (af);
       }
-      return af;
+      return fbw;
     }
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "Exchange supports `%s' as a wire method (but we do not use 
that one)\n",
@@ -527,57 +537,55 @@ get_wire_fees (struct Exchange *exchange,
  * the callback.
  *
  * @param exchange the exchange to check for pending find operations
- * @return #GNUNET_YES if we need /wire data from @a exchange
+ * @return true if we need /wire data from @a exchange
  */
-static int
+static bool
 process_find_operations (struct Exchange *exchange)
 {
   struct TMH_EXCHANGES_FindOperation *fn;
   struct GNUNET_TIME_Absolute now;
-  int need_wire;
+  bool need_wire;
 
   now = GNUNET_TIME_absolute_get ();
-  need_wire = GNUNET_NO;
+  need_wire = false;
   for (struct TMH_EXCHANGES_FindOperation *fo = exchange->fo_head;
        NULL != fo;
        fo = fn)
   {
-    const struct TALER_Amount *wire_fee;
+    struct FeesByWireMethod *fbw;
 
     fn = fo->next;
     if (NULL != fo->wire_method)
     {
-      struct TALER_EXCHANGE_WireAggregateFees *af;
-
       /* Find fee structure for our wire method */
-      af = get_wire_fees (exchange,
-                          now,
-                          fo->wire_method);
-      if (NULL == af)
+      fbw = get_wire_fees (exchange,
+                           now,
+                           fo->wire_method);
+      if (NULL == fbw)
       {
-        need_wire = GNUNET_YES;
+        need_wire = true;
         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                     "Exchange does not support `%s' wire method (will retry 
later)\n",
                     fo->wire_method);
+        fbw = NULL;
         continue;
       }
-      if (af->start_date.abs_value_us > now.abs_value_us)
+      if (fbw->af->start_date.abs_value_us > now.abs_value_us)
       {
         /* Disagreement on the current time */
         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                     "Exchange's earliest fee is %s adhead of our time. Clock 
skew issue?\n",
                     GNUNET_STRINGS_relative_time_to_string (
-                      GNUNET_TIME_absolute_get_remaining (af->start_date),
+                      GNUNET_TIME_absolute_get_remaining (fbw->af->start_date),
                       GNUNET_YES));
+        fbw = NULL;
         continue;
       }
-      /* found fee, great! */
-      wire_fee = &af->wire_fee;
     }
     else
     {
       /* no wire transfer method given, so we yield no fee */
-      wire_fee = NULL;
+      fbw = NULL;
     }
     {
       struct TALER_EXCHANGE_HttpResponse hr = {
@@ -587,7 +595,8 @@ process_find_operations (struct Exchange *exchange)
       fo->fc (fo->fc_cls,
               &hr,
               exchange->conn,
-              wire_fee,
+              (NULL != fbw) ? fbw->payto_uri : NULL,
+              (NULL != fbw) ? &fbw->af->wire_fee : NULL,
               exchange->trusted);
     }
     TMH_EXCHANGES_find_exchange_cancel (fo);
@@ -649,6 +658,7 @@ handle_wire_data (void *cls,
               hr,
               NULL,
               NULL,
+              NULL,
               GNUNET_NO);
       TMH_EXCHANGES_find_exchange_cancel (fo);
     }
@@ -677,13 +687,13 @@ handle_wire_data (void *cls,
               &hrx,
               NULL,
               NULL,
+              NULL,
               GNUNET_NO);
       TMH_EXCHANGES_find_exchange_cancel (fo);
     }
     return;
   }
-  if ( (GNUNET_YES ==
-        process_find_operations (exchange)) &&
+  if ( (process_find_operations (exchange)) &&
        (NULL == exchange->wire_task) &&
        (NULL == exchange->wire_request) )
   {
@@ -725,9 +735,8 @@ wire_task_cb (void *cls)
   struct Exchange *exchange = cls;
 
   exchange->wire_task = NULL;
-  GNUNET_assert (GNUNET_NO == exchange->pending);
-  if (GNUNET_YES !=
-      process_find_operations (exchange))
+  GNUNET_assert (! exchange->pending);
+  if (! process_find_operations (exchange))
     return; /* no more need */
   GNUNET_assert (NULL == exchange->wire_request);
   exchange->wire_request = TALER_EXCHANGE_wire (exchange->conn,
@@ -751,7 +760,7 @@ fail_and_retry (struct Exchange *exchange,
 {
   struct TMH_EXCHANGES_FindOperation *fo;
 
-  exchange->pending = GNUNET_YES;
+  exchange->pending = true;
   if (NULL != exchange->wire_request)
   {
     TALER_EXCHANGE_wire_cancel (exchange->wire_request);
@@ -768,6 +777,7 @@ fail_and_retry (struct Exchange *exchange,
             hr,
             NULL,
             NULL,
+            NULL,
             GNUNET_NO);
     TMH_EXCHANGES_find_exchange_cancel (fo);
   }
@@ -833,7 +843,7 @@ keys_mgmt_cb (void *cls,
                     compat);
     return;
   }
-  if ( (GNUNET_YES == exchange->trusted) &&
+  if ( (exchange->trusted) &&
        (0 != GNUNET_memcmp (&exchange->master_pub,
                             &keys->master_pub)) )
   {
@@ -841,9 +851,9 @@ keys_mgmt_cb (void *cls,
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Master public key of exchange `%s' differs from our 
configuration. Not trusting exchange.\n",
                 exchange->url);
-    exchange->trusted = GNUNET_NO;
+    exchange->trusted = false;
   }
-  if (GNUNET_NO == exchange->trusted)
+  if (! exchange->trusted)
     exchange->master_pub = keys->master_pub;
 
   if (0 != (TALER_EXCHANGE_VC_NEWER & compat))
@@ -900,9 +910,8 @@ keys_mgmt_cb (void *cls,
     = GNUNET_SCHEDULER_add_delayed (delay,
                                     &retry_exchange,
                                     exchange);
-  exchange->pending = GNUNET_NO;
-  if ( (GNUNET_YES ==
-        process_find_operations (exchange)) &&
+  exchange->pending = false;
+  if ( (process_find_operations (exchange)) &&
        (NULL == exchange->wire_request) &&
        (NULL == exchange->wire_task) )
   {
@@ -927,10 +936,9 @@ return_result (void *cls)
   struct Exchange *exchange = fo->my_exchange;
 
   fo->at = NULL;
-  if ( (GNUNET_YES ==
-        process_find_operations (exchange)) &&
+  if ( (process_find_operations (exchange)) &&
        (NULL == exchange->wire_request) &&
-       (GNUNET_NO == exchange->pending) &&
+       (! exchange->pending) &&
        (NULL != exchange->wire_task) )
   {
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -1000,7 +1008,7 @@ TMH_EXCHANGES_find_exchange (const char *chosen_exchange,
     /* This is a new exchange */
     exchange = GNUNET_new (struct Exchange);
     exchange->url = GNUNET_strdup (chosen_exchange);
-    exchange->pending = GNUNET_YES;
+    exchange->pending = true;
     GNUNET_CONTAINER_DLL_insert (exchange_head,
                                  exchange_tail,
                                  exchange);
@@ -1039,7 +1047,7 @@ TMH_EXCHANGES_find_exchange (const char *chosen_exchange,
   }
 
 
-  if ( (GNUNET_YES != exchange->pending) &&
+  if ( (! exchange->pending) &&
        ( (NULL == fo->wire_method) ||
          (NULL != get_wire_fees (exchange,
                                  now,
@@ -1056,14 +1064,14 @@ TMH_EXCHANGES_find_exchange (const char 
*chosen_exchange,
   /* If new or resumed, (re)try fetching /keys */
   if ( (NULL == exchange->conn) &&
        (NULL == exchange->retry_task) &&
-       (GNUNET_YES == exchange->pending) )
+       (exchange->pending) )
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Do not have current key data. Will request /keys now\n");
     exchange->retry_task = GNUNET_SCHEDULER_add_now (&retry_exchange,
                                                      exchange);
   }
-  else if ( (GNUNET_NO == exchange->pending) &&
+  else if ( (! exchange->pending) &&
             (NULL == exchange->wire_task) &&
             (NULL == exchange->wire_request) )
   {
@@ -1167,7 +1175,7 @@ accept_exchanges (void *cls,
                                                     &exchange->master_pub.
                                                     eddsa_pub))
     {
-      exchange->trusted = GNUNET_YES;
+      exchange->trusted = true;
     }
     else
     {
@@ -1188,7 +1196,7 @@ accept_exchanges (void *cls,
   GNUNET_CONTAINER_DLL_insert (exchange_head,
                                exchange_tail,
                                exchange);
-  exchange->pending = GNUNET_YES;
+  exchange->pending = true;
   GNUNET_assert (NULL == exchange->retry_task);
   exchange->retry_task = GNUNET_SCHEDULER_add_now (&retry_exchange,
                                                    exchange);
@@ -1228,7 +1236,7 @@ TMH_EXCHANGES_init (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
   {
     json_t *j_exchange;
 
-    if (GNUNET_YES != exchange->trusted)
+    if (! exchange->trusted)
       continue;
     j_exchange = json_pack ("{s:s, s:o}",
                             "url", exchange->url,
@@ -1270,6 +1278,7 @@ TMH_EXCHANGES_done ()
         GNUNET_free (af);
       }
       GNUNET_free (f->wire_method);
+      GNUNET_free (f->payto_uri);
       GNUNET_free (f);
     }
     if (NULL != exchange->wire_request)
diff --git a/src/backend/taler-merchant-httpd_exchanges.h 
b/src/backend/taler-merchant-httpd_exchanges.h
index 3a47408..4fcb812 100644
--- a/src/backend/taler-merchant-httpd_exchanges.h
+++ b/src/backend/taler-merchant-httpd_exchanges.h
@@ -61,15 +61,17 @@ TMH_EXCHANGES_done (void);
  * @param cls closure
  * @param hr HTTP response details
  * @param eh handle to the exchange context
+ * @param payto_uri payto://-URI of the exchange
  * @param wire_fee current applicable wire fee for dealing with @a eh, NULL if 
not available
- * @param exchange_trusted #GNUNET_YES if this exchange is trusted by config
+ * @param exchange_trusted true if this exchange is trusted by config
  */
 typedef void
 (*TMH_EXCHANGES_FindContinuation)(void *cls,
                                   const struct TALER_EXCHANGE_HttpResponse *hr,
                                   struct TALER_EXCHANGE_Handle *eh,
+                                  const char *payto_uri,
                                   const struct TALER_Amount *wire_fee,
-                                  int exchange_trusted);
+                                  bool exchange_trusted);
 
 
 /**
diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.c 
b/src/backend/taler-merchant-httpd_get-orders-ID.c
index f22ac8a..15a40f2 100644
--- a/src/backend/taler-merchant-httpd_get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_get-orders-ID.c
@@ -496,18 +496,21 @@ refund_cb (void *cls,
  * @param cls a `struct CoinRefund *`
  * @param hr HTTP response details
  * @param eh handle to the exchange context
+ * @param payto_uri payto://-URI of the exchange
  * @param wire_fee current applicable wire fee for dealing with @a eh, NULL if 
not available
- * @param exchange_trusted #GNUNET_YES if this exchange is trusted by config
+ * @param exchange_trusted true if this exchange is trusted by config
  */
 static void
 exchange_found_cb (void *cls,
                    const struct TALER_EXCHANGE_HttpResponse *hr,
                    struct TALER_EXCHANGE_Handle *eh,
+                   const char *payto_uri,
                    const struct TALER_Amount *wire_fee,
-                   int exchange_trusted)
+                   bool exchange_trusted)
 {
   struct CoinRefund *cr = cls;
 
+  (void) payto_uri;
   cr->fo = NULL;
   if (TALER_EC_NONE == hr->ec)
   {
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-abort.c 
b/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
index 564f0e3..19f7223 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
@@ -469,21 +469,25 @@ refund_cb (void *cls,
  *
  * @param cls the `struct AbortContext`
  * @param hr HTTP response details
+ * @param payto_uri payto://-URI of the exchange
  * @param exchange_handle NULL if exchange was not found to be acceptable
  * @param wire_fee current applicable fee for dealing with @a exchange_handle,
  *        NULL if not available
- * @param exchange_trusted #GNUNET_YES if this exchange is
+ * @param exchange_trusted true if this exchange is
  *        trusted by config
  */
 static void
 process_abort_with_exchange (void *cls,
                              const struct TALER_EXCHANGE_HttpResponse *hr,
                              struct TALER_EXCHANGE_Handle *exchange_handle,
+                             const char *payto_uri,
                              const struct TALER_Amount *wire_fee,
-                             int exchange_trusted)
+                             bool exchange_trusted)
 {
   struct AbortContext *ac = cls;
 
+  (void) payto_uri;
+  (void) exchange_trusted;
   ac->fo = NULL;
   GNUNET_assert (GNUNET_YES == ac->suspended);
   if (MHD_HTTP_OK != hr->http_status)
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c 
b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
index ca519a9..b1f5c03 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -689,22 +689,25 @@ deposit_cb (void *cls,
  * @param cls the `struct PayContext`
  * @param hr HTTP response details
  * @param exchange_handle NULL if exchange was not found to be acceptable
+ * @param payto_uri payto://-URI of the exchange
  * @param wire_fee current applicable fee for dealing with @a exchange_handle,
  *        NULL if not available
- * @param exchange_trusted #GNUNET_YES if this exchange is
+ * @param exchange_trusted true if this exchange is
  *        trusted by config
  */
 static void
 process_pay_with_exchange (void *cls,
                            const struct TALER_EXCHANGE_HttpResponse *hr,
                            struct TALER_EXCHANGE_Handle *exchange_handle,
+                           const char *payto_uri,
                            const struct TALER_Amount *wire_fee,
-                           int exchange_trusted)
+                           bool exchange_trusted)
 {
   struct PayContext *pc = cls;
   struct TMH_HandlerContext *hc = pc->hc;
   const struct TALER_EXCHANGE_Keys *keys;
 
+  (void) payto_uri;
   pc->fo = NULL;
   GNUNET_assert (GNUNET_YES == pc->suspended);
   if (MHD_HTTP_OK != hr->http_status)
diff --git a/src/backend/taler-merchant-httpd_private-post-reserves.c 
b/src/backend/taler-merchant-httpd_private-post-reserves.c
new file mode 100644
index 0000000..abb6d0b
--- /dev/null
+++ b/src/backend/taler-merchant-httpd_private-post-reserves.c
@@ -0,0 +1,288 @@
+/*
+  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-post-reserves.c
+ * @brief implementing POST /reserves request handling
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler-merchant-httpd_exchanges.h"
+#include "taler-merchant-httpd_private-post-reserves.h"
+#include <taler/taler_json_lib.h>
+
+
+/**
+ * Information we keep for an individual call to the POST /reserves handler.
+ */
+struct PostReserveContext
+{
+
+  /**
+   * Stored in a DLL.
+   */
+  struct PostReserveContext *next;
+
+  /**
+   * Stored in a DLL.
+   */
+  struct PostReserveContext *prev;
+
+  /**
+   * Array with @e coins_cnt coins we are despositing.
+   */
+  struct DepositConfirmation *dc;
+
+  /**
+   * MHD connection to return to
+   */
+  struct MHD_Connection *connection;
+
+  /**
+   * Details about the client's request.
+   */
+  struct TMH_HandlerContext *hc;
+
+  /**
+   * URL of the exchange.
+   */
+  const char *exchange_url;
+
+  /**
+   * URI of the exchange where the payment needs to be made to.
+   */
+  char *payto_uri;
+
+  /**
+   * Handle for contacting the exchange.
+   */
+  struct TMH_EXCHANGES_FindOperation *fo;
+
+  /**
+   * Initial balance of the reserve.
+   */
+  struct TALER_Amount initial_balance;
+
+  /**
+   * When will the reserve expire.
+   */
+  struct GNUNET_TIME_Absolute reserve_expiration;
+
+  /**
+   * Are we suspended?
+   */
+  bool suspended;
+};
+
+
+/**
+ * Stored in a DLL.
+ */
+static struct PostReserveContext *rc_head;
+
+/**
+ * Stored in a DLL.
+ */
+static struct PostReserveContext *rc_tail;
+
+
+/**
+ * Force all post reserve contexts to be resumed as we are about
+ * to shut down MHD.
+ */
+void
+TMH_force_rc_resume ()
+{
+  for (struct PostReserveContext *rc = rc_head;
+       NULL != rc;
+       rc = rc->next)
+  {
+    if (rc->suspended)
+    {
+      rc->suspended = false;
+      MHD_resume_connection (rc->connection);
+      GNUNET_CONTAINER_DLL_remove (rc_head,
+                                   rc_tail,
+                                   rc);
+    }
+    if (NULL != rc->fo)
+    {
+      TMH_EXCHANGES_find_exchange_cancel (rc->fo);
+      rc->fo = NULL;
+    }
+  }
+}
+
+
+/**
+ * Custom cleanup routine for a `struct PostReserveContext`.
+ *
+ * @param cls the `struct PostReserveContext` to clean up.
+ */
+static void
+reserve_context_cleanup (void *cls)
+{
+  struct PostReserveContext *rc = cls;
+
+  if (NULL != rc->fo)
+  {
+    TMH_EXCHANGES_find_exchange_cancel (rc->fo);
+    rc->fo = NULL;
+  }
+  GNUNET_assert (! rc->suspended);
+  GNUNET_free_non_null (rc->payto_uri);
+  GNUNET_free (rc);
+}
+
+
+/**
+ * Function called with the result of a #TMH_EXCHANGES_find_exchange()
+ * operation.
+ *
+ * @param cls closure with our `struct PostReserveContext *`
+ * @param hr HTTP response details
+ * @param payto_uri URI of the exchange for the wire transfer, NULL on errors
+ * @param eh handle to the exchange context
+ * @param wire_fee current applicable wire fee for dealing with @a eh, NULL if 
not available
+ * @param exchange_trusted true if this exchange is trusted by config
+ */
+static void
+handle_exchange (void *cls,
+                 const struct TALER_EXCHANGE_HttpResponse *hr,
+                 struct TALER_EXCHANGE_Handle *eh,
+                 const char *payto_uri,
+                 const struct TALER_Amount *wire_fee,
+                 bool exchange_trusted)
+{
+  struct PostReserveContext *rc = cls;
+  const struct TALER_EXCHANGE_Keys *keys;
+
+  rc->suspended = false;
+  MHD_resume_connection (rc->connection);
+  keys = TALER_EXCHANGE_get_keys (eh);
+  if ( (NULL != keys) &&
+       (NULL != payto_uri) )
+  {
+    rc->reserve_expiration
+      = GNUNET_TIME_relative_to_absolute (keys->reserve_closing_delay);
+    rc->payto_uri = GNUNET_strdup (payto_uri);
+  }
+}
+
+
+/**
+ * Generate a reserve, given its keys and balance.
+ *
+ * @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 (const struct TMH_RequestHandler *rh,
+                           struct MHD_Connection *connection,
+                           struct TMH_HandlerContext *hc)
+{
+  struct PostReserveContext *rc = hc->ctx;
+  struct TMH_MerchantInstance *mi = hc->instance;
+
+  GNUNET_assert (NULL != mi);
+  if (NULL == rc)
+  {
+    const char *wire_method;
+
+    rc = GNUNET_new (struct PostReserveContext);
+    rc->connection = connection;
+    rc->hc = hc;
+    hc->ctx = rc;
+    hc->cc = &reserve_context_cleanup;
+
+    {
+      enum GNUNET_GenericReturnValue res;
+      struct GNUNET_JSON_Specification spec[] = {
+        GNUNET_JSON_spec_string ("exchange_url",
+                                 &rc->exchange_url),
+        GNUNET_JSON_spec_string ("wire_method",
+                                 &wire_method),
+        TALER_JSON_spec_amount ("initial_balance",
+                                &rc->initial_balance),
+        GNUNET_JSON_spec_end ()
+      };
+      res = TALER_MHD_parse_json_data (connection,
+                                       hc->request_body,
+                                       spec);
+      if (GNUNET_OK != res)
+        return (GNUNET_NO == res)
+               ? MHD_YES
+               : MHD_NO;
+    }
+    rc->fo = TMH_EXCHANGES_find_exchange (rc->exchange_url,
+                                          wire_method,
+                                          GNUNET_NO,
+                                          &handle_exchange,
+                                          rc);
+    rc->suspended = true;
+    GNUNET_CONTAINER_DLL_insert (rc_head,
+                                 rc_tail,
+                                 rc);
+    MHD_suspend_connection (connection);
+    return MHD_YES;
+  }
+
+  GNUNET_assert (! rc->suspended);
+  if (NULL == rc->payto_uri)
+  {
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                       
TALER_EC_RESERVES_POST_UNSUPPORTED_WIRE_METHOD,
+                                       "Exchange does not support wire 
method");
+  }
+  {
+    struct TALER_ReservePublicKeyP reserve_pub;
+    struct TALER_ReservePrivateKeyP reserve_priv;
+    enum GNUNET_DB_QueryStatus qs;
+
+    GNUNET_CRYPTO_eddsa_key_create (&reserve_priv.eddsa_priv);
+    GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv.eddsa_priv,
+                                        &reserve_pub.eddsa_pub);
+    qs = TMH_db->insert_reserve (TMH_db->cls,
+                                 mi->settings.id,
+                                 &reserve_priv,
+                                 &reserve_pub,
+                                 rc->exchange_url,
+                                 &rc->initial_balance,
+                                 rc->reserve_expiration);
+    GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
+    if (qs < 0)
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                         
TALER_EC_RESERVES_POST_DB_COMMIT_HARD_ERROR,
+                                         "Failed to commit transaction");
+    return TALER_MHD_reply_json_pack (connection,
+                                      MHD_HTTP_OK,
+                                      "{s:o,s:s}",
+                                      "reserve_pub",
+                                      GNUNET_JSON_from_data_auto 
(&reserve_pub),
+                                      "payto_uri",
+                                      rc->payto_uri);
+  }
+}
+
+
+/* end of taler-merchant-httpd_private-post-reserves.c */
diff --git a/src/backend/taler-merchant-httpd_private-post-reserves.h 
b/src/backend/taler-merchant-httpd_private-post-reserves.h
new file mode 100644
index 0000000..2c35648
--- /dev/null
+++ b/src/backend/taler-merchant-httpd_private-post-reserves.h
@@ -0,0 +1,50 @@
+/*
+  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-post-reserves.h
+ * @brief implementing POST /reserves request handling
+ * @author Christian Grothoff
+ */
+#ifndef TALER_MERCHANT_HTTPD_PRIVATE_POST_RESERVES_H
+#define TALER_MERCHANT_HTTPD_PRIVATE_POST_RESERVES_H
+#include "taler-merchant-httpd.h"
+
+/**
+ * Force all post reserve contexts to be resumed as we are about
+ * to shut down MHD.
+ */
+void
+TMH_force_rc_resume ();
+
+
+/**
+ * Generate a reserve entry in our inventory.
+ *
+ * @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 (const struct TMH_RequestHandler *rh,
+                           struct MHD_Connection *connection,
+                           struct TMH_HandlerContext *hc);
+
+#endif
diff --git a/src/backend/taler-merchant-httpd_private-post-transfers.c 
b/src/backend/taler-merchant-httpd_private-post-transfers.c
index 0b9b672..3687f6d 100644
--- a/src/backend/taler-merchant-httpd_private-post-transfers.c
+++ b/src/backend/taler-merchant-httpd_private-post-transfers.c
@@ -534,6 +534,7 @@ retry:
  * @param cls the `struct PostTransfersContext`
  * @param hr HTTP response details
  * @param eh NULL if exchange was not found to be acceptable
+ * @param payto_uri payto://-URI of the exchange
  * @param wire_fee NULL (we did not specify a wire method)
  * @param exchange_trusted #GNUNET_YES if this exchange is trusted by config
  */
@@ -541,11 +542,14 @@ static void
 process_transfer_with_exchange (void *cls,
                                 const struct TALER_EXCHANGE_HttpResponse *hr,
                                 struct TALER_EXCHANGE_Handle *eh,
+                                const char *payto_uri,
                                 const struct TALER_Amount *wire_fee,
-                                int exchange_trusted)
+                                bool exchange_trusted)
 {
   struct PostTransfersContext *ptc = cls;
 
+  (void) payto_uri;
+  (void) exchange_trusted;
   ptc->fo = NULL;
   if (MHD_HTTP_OK != hr->http_status)
   {
diff --git a/src/include/taler_merchantdb_plugin.h 
b/src/include/taler_merchantdb_plugin.h
index 5321b57..066c2b2 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -1456,6 +1456,32 @@ struct TALER_MERCHANTDB_Plugin
                       void *cb_cls);
 
 
+  /**
+   * Add @a credit to a reserve to be used for tipping.  Note that
+   * this function does not actually perform any wire transfers to
+   * credit the reserve, it merely tells the merchant backend that
+   * a reserve now exists.  This has to happen before tips can be
+   * authorized.
+   *
+   * @param cls closure, typically a connection to the db
+   * @param instance_id which instance is the reserve tied to
+   * @param reserve_priv which reserve is topped up or created
+   * @param reserve_pub which reserve is topped up or created
+   * @param exchange_url what URL is the exchange reachable at where the 
reserve is located
+   * @param initial_balance how much money will be added to the reserve
+   * @param expiration when does the reserve expire?
+   * @return transaction status, usually
+   *      #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT for success
+   */
+  enum GNUNET_DB_QueryStatus
+  (*insert_reserve)(void *cls,
+                    const char *instance_id,
+                    const struct TALER_ReservePrivateKeyP *reserve_priv,
+                    const struct TALER_ReservePublicKeyP *reserve_pub,
+                    const char *exchange_url,
+                    const struct TALER_Amount *initial_balance,
+                    struct GNUNET_TIME_Absolute expiration);
+
   /* ****************** OLD API ******************** */
 
 

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