gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-exchange] branch master updated (3e757cde -> 8655a40


From: gnunet
Subject: [GNUnet-SVN] [taler-exchange] branch master updated (3e757cde -> 8655a40a)
Date: Fri, 05 Apr 2019 19:32:00 +0200

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

marcello pushed a change to branch master
in repository exchange.

    from 3e757cde Inserting "now" argument into "/keys".
     new 32cdef2b Making the bug /history[-range] args parser.
     new a19baacc Do not include legally expired keys into /keys response.
     new 8655a40a Half-baking #5666.

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/bank-lib/fakebank.c                      | 550 ++++++++++++++++++++++++++-
 src/exchange/taler-exchange-httpd_keystate.c |   7 +
 2 files changed, 545 insertions(+), 12 deletions(-)

diff --git a/src/bank-lib/fakebank.c b/src/bank-lib/fakebank.c
index 09ec1bbe..3eea5f8b 100644
--- a/src/bank-lib/fakebank.c
+++ b/src/bank-lib/fakebank.c
@@ -2,16 +2,19 @@
   This file is part of TALER
   (C) 2016, 2017, 2018 Inria and GNUnet e.V.
 
-  TALER is free software; you can redistribute it and/or modify it under the
-  terms of the GNU General Public License as published by the Free Software
-  Foundation; either version 3, or (at your option) any later version.
-
-  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License along with
-  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+  TALER is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License
+  as published by the Free Software Foundation; either version 3,
+  or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public
+  License along with TALER; see the file COPYING.  If not,
+  see <http://www.gnu.org/licenses/>
 */
 
 /**
@@ -29,6 +32,14 @@
 #define REQUEST_BUFFER_MAX (4*1024)
 
 
+/**
+ * Parse URL arguments of a /history[-range] HTTP request.
+ *
+ * @param connection MHD connection object.
+ * @param ha @a HistoryArgs structure.
+ */
+#define PARSE_HISTORY_ARGS(connection, ha) \
+  parse_history_args_ (connection, ha, __FUNCTION__)
 
 /**
  * Details about a transcation we (as the simulated bank) received.
@@ -120,6 +131,72 @@ struct HistoryElement
 
 
 /**
+ * Values to implement the "/history-range" range.
+ */
+struct HistoryRangeDates
+{
+  /**
+   * Oldest row in the results.
+   */
+  struct GNUNET_TIME_Absolute start;
+
+  /**
+   * Youngest row in the results.
+   */
+  struct GNUNET_TIME_Absolute end;
+};
+
+/**
+ * Values to implement the "/history" range.
+ */
+struct HistoryRangeIds
+{
+
+  /**
+   * (Exclusive) row ID for the result set.
+   */
+  unsigned long long start;
+
+  /**
+   * How many transactions we want in the result set.  If
+   * negative/positive, @a start will be strictly younger/older
+   * of any element in the result set.
+   */
+  long long count;
+};
+
+
+/**
+ * This is the "base" structure for both the /history and the
+ * /history-range API calls.
+ */
+struct HistoryArgs
+{
+
+  /**
+   * Direction asked by the client: CREDIT / DEBIT / BOTH / CANCEL.
+   */
+  enum TALER_BANK_Direction direction;
+
+  /**
+   * Bank account number of the requesting client.
+   */
+  unsigned long long account_number;
+
+  /**
+   * Ordering of the results.
+   */
+  unsigned int ascending;
+
+  /**
+   * Overloaded type that indicates the "range" to be returned
+   * in the results; this can be either a date range, or a
+   * starting row id + the count.
+   */
+  void *range;
+};
+
+/**
  * Handle for the fake bank.
  */
 struct TALER_FAKEBANK_Handle
@@ -162,6 +239,17 @@ struct TALER_FAKEBANK_Handle
 #endif
 };
 
+typedef int (*CheckAdvance)(const struct HistoryArgs *ha,
+                            struct Transaction *pos);
+
+typedef struct Transaction * (*Step)
+  (const struct HistoryArgs *ha,
+   const struct Transaction *pos);
+
+typedef struct Transaction * (*Skip)
+  (const struct HistoryArgs *ha,
+   const struct Transaction *pos);
+
 
 /**
  * Check that the @a want_amount was transferred from
@@ -671,6 +759,443 @@ handle_reject (struct TALER_FAKEBANK_Handle *h,
 
 
 /**
+ * Parse URL history arguments, of _both_ APIs:
+ * /history and /history-range.
+ *
+ * @param connection MHD connection.
+ * @param function_name name of the caller.
+ * @param ha[out] will contain the parsed values.
+ * @return GNUNET_OK only if the parsing succeedes.
+ */
+static int
+parse_history_common_args (struct MHD_Connection *connection,
+                           struct HistoryArgs *ha)
+{
+  /**
+   * @variable
+   * Just check if given and == "basic", no need to keep around.
+   */
+  const char *auth;
+
+  /**
+   * All those will go into the structure, after parsing.
+   */
+  const char *direction;
+  const char *cancelled;
+  const char *ordering;
+  const char *account_number;
+
+
+  auth = MHD_lookup_connection_value (connection,
+                                      MHD_GET_ARGUMENT_KIND,
+                                      "auth");
+  direction = MHD_lookup_connection_value (connection,
+                                           MHD_GET_ARGUMENT_KIND,
+                                           "direction");
+  cancelled = MHD_lookup_connection_value (connection,
+                                           MHD_GET_ARGUMENT_KIND,
+                                           "cancelled");
+  ordering = MHD_lookup_connection_value (connection,
+                                          MHD_GET_ARGUMENT_KIND,
+                                          "ordering");
+  account_number = MHD_lookup_connection_value
+    (connection,
+     MHD_GET_ARGUMENT_KIND,
+     "account_number");
+
+  /* Fail if one of the above failed.  */
+  if ( (NULL == direction) ||
+       (NULL == cancelled) ||
+       ( (0 != strcasecmp (cancelled,
+                           "OMIT")) &&
+         (0 != strcasecmp (cancelled,
+                           "SHOW")) ) ||
+       ( (0 != strcasecmp (direction,
+                           "BOTH")) &&
+         (0 != strcasecmp (direction,
+                           "CREDIT")) &&
+         (0 != strcasecmp (direction,
+                           "DEBIT")) ) ||
+         (1 != sscanf (account_number,
+                       "%llu",
+                       &ha->account_number)) ||
+         ( (NULL == auth) || (0 != strcasecmp (auth,
+                                               "basic")) ) )
+  {
+    /* Invalid request, given that this is fakebank we impolitely
+     * just kill the connection instead of returning a nice error.
+     */
+    GNUNET_break (0);
+    return GNUNET_NO;
+  }
+
+  if (0 == strcasecmp (direction,
+                       "CREDIT"))
+  {
+    ha->direction = TALER_BANK_DIRECTION_CREDIT;
+  }
+  else if (0 == strcasecmp (direction,
+                            "DEBIT"))
+  {
+    ha->direction = TALER_BANK_DIRECTION_DEBIT;
+  }
+  else if (0 == strcasecmp (direction,
+                            "BOTH"))
+  {
+    ha->direction = TALER_BANK_DIRECTION_BOTH;
+  }
+
+  /* Direction is invalid.  */
+  else
+  {
+    GNUNET_break (0);
+    return GNUNET_NO;
+  }
+
+  if (0 == strcasecmp (cancelled,
+                       "OMIT"))
+  {
+    /* nothing */
+  } else if (0 == strcasecmp (cancelled,
+                              "SHOW"))
+  {
+    ha->direction |= TALER_BANK_DIRECTION_CANCEL;
+  }
+
+  /* Cancel-showing policy is invalid.  */
+  else
+  {
+    GNUNET_break (0);
+    return GNUNET_NO;
+  }
+
+  if ((NULL != ordering)
+      && 0 == strcmp ("ascending",
+                      ordering))
+    ha->ascending = GNUNET_YES;
+  else
+    ha->ascending = GNUNET_NO;
+
+  return GNUNET_OK;
+}
+
+/**
+ * Handle incoming HTTP request for /history
+ *
+ * @param h the fakebank handle
+ * @param connection the connection
+ * @param con_cls place to store state, not used
+ * @return MHD result code
+ */
+static int
+handle_history_new (struct TALER_FAKEBANK_Handle *h,
+                    struct MHD_Connection *connection,
+                    void **con_cls)
+{
+  struct HistoryArgs ha;
+  struct HistoryRangeIds hri;
+  const char *start;
+  const char *delta;
+  struct Transaction *pos;
+
+  if (GNUNET_OK != parse_history_common_args (connection,
+                                              &ha))
+  {
+    GNUNET_break (0);
+    return MHD_NO;
+  }
+
+  start = MHD_lookup_connection_value (connection,
+                                       MHD_GET_ARGUMENT_KIND,
+                                       "start");
+  delta = MHD_lookup_connection_value (connection,
+                                       MHD_GET_ARGUMENT_KIND,
+                                       "delta");
+  if ( ((NULL != start) && (1 != sscanf (start,
+                                        "%llu",
+                                        &hri.start))) ||
+    (NULL == delta) || (1 != sscanf (delta,
+                                     "%lld",
+                                     &hri.count)) )
+  {
+    GNUNET_break (0);
+    return MHD_NO;
+  }
+
+  if (NULL == start)
+    pos = 0 > hri.count ?
+      h->transactions_tail : h->transactions_head;
+
+  else if (NULL != h->transactions_head)
+  {
+    for (pos = h->transactions_head;
+         NULL != pos;
+         pos = pos->next)
+      if (pos->row_id  == hri.start)
+        break;
+    if (NULL == pos)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Invalid range specified,"
+                  " transaction %llu not known!\n",
+                  (unsigned long long) hri.start);
+      return MHD_NO;
+    }
+    /* range is exclusive, skip the matching entry */
+    if (hri.count > 0)
+      pos = pos->next;
+    if (hri.count < 0)
+      pos = pos->prev;
+  }
+  else
+  {
+    /* list is empty */
+    pos = NULL;
+  }
+
+}
+
+/**
+ * Handle incoming HTTP request for /history-range.
+ *
+ * @param h the fakebank handle
+ * @param connection the connection
+ * @param con_cls place to store state, not used
+ * @return MHD result code
+ */
+static int
+handle_history_range (struct TALER_FAKEBANK_Handle *h,
+                      struct MHD_Connection *connection,
+                      void **con_cls)
+{
+
+  struct HistoryArgs ha;
+  struct HistoryRangeDates hrd;
+  const char *start;
+  const char *end;
+  long long unsigned int start_stamp; 
+  long long unsigned int end_stamp; 
+
+  if (GNUNET_OK != parse_history_common_args (connection,
+                                              &ha))
+  {
+    GNUNET_break (0);
+    return MHD_NO;
+  }
+  start = MHD_lookup_connection_value (connection,
+                                       MHD_GET_ARGUMENT_KIND,
+                                       "start");
+  end = MHD_lookup_connection_value (connection,
+                                     MHD_GET_ARGUMENT_KIND,
+                                     "end");
+
+  if ( (NULL == start) || (1 != sscanf (start,
+                                        "%llu",
+                                        &start_stamp)) ||
+    (NULL == end) || (1 != sscanf (end,
+                                   "%lld",
+                                   &end_stamp)) )
+  {
+    GNUNET_break (0);
+    return GNUNET_NO;
+  }
+
+  hrd.start.abs_value_us = start_stamp * 1000LL * 1000LL;
+  hrd.end.abs_value_us = end_stamp * 1000LL * 1000LL;
+}
+
+
+/**
+ * Decides whether the history builder will advance or not
+ * to the next element.
+ *
+ * @param ha history args
+ * @return GNUNET_YES/NO to advance/not-advance.
+ */
+static int
+handle_history_advance (const struct HistoryArgs *ha,
+                        struct Transaction *pos)
+{
+  const struct HistoryRangeIds *hri = ha->range;
+
+  return (NULL != pos) && (0 != hri->count);
+}
+
+
+/**
+ * Iterates on the "next" element to be processed.  To
+ * be used when the current element does not get inserted in
+ * the result.
+ *
+ * @param ha history arguments.
+ * @param pos current element being processed.
+ * @return the next element to be processed.
+ */
+static struct Transaction *
+handle_history_skip (const struct HistoryArgs *ha,
+                     const struct Transaction *pos)
+{
+  const struct HistoryRangeIds *hri = ha->range;
+
+  if (hri->count > 0)
+    return pos->next;
+  if (hri->count < 0)
+    return pos->prev;
+}
+
+
+/**
+ * Iterates on the "next" element to be processed.  To
+ * be used when the current element _gets_ inserted in the result.
+ *
+ * @param ha history arguments.
+ * @param pos current element being processed.
+ * @return the next element to be processed.
+ */
+static struct Transaction *
+handle_history_step (struct HistoryArgs *ha,
+                     const struct Transaction *pos)
+{
+  struct HistoryRangeIds *hri = ha->range;
+
+  if (hri->count > 0)
+  {
+    hri->count--;
+    return pos->next;
+  }
+  if (hri->count < 0)
+  {
+    hri->count++;
+    return pos->prev;
+  }
+}
+
+
+/**
+ * Decides whether the history builder will advance or not
+ * to the next element.
+ *
+ * @param ha history args
+ * @return GNUNET_YES/NO to advance/not-advance.
+ */
+static int
+handle_history_range_advance (const struct HistoryArgs *ha)
+{
+  const struct HistoryRangeDates *hrd = ha->range;
+}
+
+
+/**
+ * Iterates towards the "next" element to be processed.  To
+ * be used when the current element does not get inserted in
+ * the result.
+ *
+ * @param ha history arguments.
+ * @param pos current element being processed.
+ * @return the next element to be processed.
+ */
+static struct Transaction *
+handle_history_range_skip (const struct HistoryArgs *ha)
+{
+  const struct HistoryRangeDates *hrd = ha->range;
+}
+
+/**
+ * Iterates on the "next" element to be processed.  To
+ * be used when the current element _gets_ inserted in the result.
+ *
+ * @param ha history arguments.
+ * @param pos current element being processed.
+ * @return the next element to be processed.
+ */
+static struct Transaction *
+handle_history_range_step (const struct HistoryArgs *ha)
+{
+  const struct HistoryRangeDates *hrd = ha->range;
+}
+
+/**
+ * Actual history response builder.
+ *
+ * @param pos first (included) element in the result set.
+ * @param ha history arguments.
+ * @param caller_name which function is building the history.
+ * @return MHD response object, or NULL if any error occurs.
+ */
+static struct MHD_response *
+build_history_response (struct Transaction *pos,
+                        struct HistoryArgs *ha,
+                        Skip skip,
+                        Step step,
+                        CheckAdvance advance)
+{
+
+  struct HistoryElement *history_results_head = NULL;
+  struct HistoryElement *history_results_tail = NULL;
+  struct HistoryElement *history_element = NULL;
+
+  while (GNUNET_YES == advance (ha,
+                                pos))
+  {
+    json_t *trans;
+    char *subject;
+    const char *sign;
+
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Found transaction over %s from %llu to %llu\n",
+                TALER_amount2s (&pos->amount),
+                (unsigned long long) pos->debit_account,
+                (unsigned long long) pos->credit_account);
+
+    if ( (! ( ( (ha->account_number == pos->debit_account) &&
+                (0 != (ha->direction & TALER_BANK_DIRECTION_DEBIT)) ) ||
+              ( (ha->account_number == pos->credit_account) &&
+                (0 != (ha->direction & TALER_BANK_DIRECTION_CREDIT) ) ) ) ) ||
+         ( (0 == (ha->direction & TALER_BANK_DIRECTION_CANCEL)) &&
+           (GNUNET_YES == pos->rejected) ) )
+    {
+      pos = skip (ha,
+                  pos);
+      continue;
+    }
+
+    GNUNET_asprintf (&subject,
+                     "%s %s",
+                     pos->subject,
+                     pos->exchange_base_url);
+    sign =
+      (ha->account_number == pos->debit_account)
+      ? (pos->rejected ? "cancel-" : "-")
+      : (pos->rejected ? "cancel+" : "+");
+    trans = json_pack
+      ("{s:I, s:o, s:o, s:s, s:I, s:s}",
+       "row_id", (json_int_t) pos->row_id,
+       "date", GNUNET_JSON_from_time_abs (pos->date),
+       "amount", TALER_JSON_from_amount (&pos->amount),
+       "sign", sign,
+       "counterpart", (json_int_t)
+         ( (ha->account_number == pos->debit_account)
+            ? pos->credit_account
+            : pos->debit_account),
+       "wt_subject", subject);
+    GNUNET_assert (NULL != trans);
+    GNUNET_free (subject);
+
+    history_element = GNUNET_new (struct HistoryElement);
+    history_element->element = trans;
+
+
+    /* XXX: the ordering feature is missing.  */
+
+    GNUNET_CONTAINER_DLL_insert_tail (history_results_head,
+                                      history_results_tail,
+                                      history_element);
+    pos = step (ha, pos);
+  }
+}
+
+
+/**
  * Handle incoming HTTP request for /history
  *
  * @param h the fakebank handle
@@ -759,8 +1284,9 @@ handle_history (struct TALER_FAKEBANK_Handle *h,
          (0 != strcasecmp (dir,
                            "DEBIT")) ) )
   {
-    /* Invalid request, given that this is fakebank we impolitely just
-       kill the connection instead of returning a nice error. */
+    /* Invalid request, given that this is fakebank we impolitely
+     * just kill the connection instead of returning a nice error.
+     */
     GNUNET_break (0);
     return MHD_NO;
   }
diff --git a/src/exchange/taler-exchange-httpd_keystate.c 
b/src/exchange/taler-exchange-httpd_keystate.c
index 0ee3806f..ad1883ba 100644
--- a/src/exchange/taler-exchange-httpd_keystate.c
+++ b/src/exchange/taler-exchange-httpd_keystate.c
@@ -1494,6 +1494,13 @@ reload_public_denoms_cb (void *cls,
   struct ResponseFactoryContext *rfc = cls;
   struct TALER_EXCHANGEDB_DenominationKeyIssueInformation dki;
 
+  if (rfc->now.abs_value_us > GNUNET_TIME_absolute_ntoh
+    (issue->properties.expire_legal).abs_value_us)
+  {
+    /* Expired key, discard.  */
+    return;
+  }
+
   if (NULL !=
       GNUNET_CONTAINER_multihashmap_get (rfc->key_state->denomkey_map,
                                          &issue->properties.denom_hash))

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

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