gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-merchant] 02/02: add nonce only when proposal is req


From: gnunet
Subject: [GNUnet-SVN] [taler-merchant] 02/02: add nonce only when proposal is requested
Date: Wed, 10 Jan 2018 17:23:56 +0100

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

dold pushed a commit to branch master
in repository merchant.

commit a1301584e3bf32e81bd05773b76836a8869fca08
Author: Florian Dold <address@hidden>
AuthorDate: Wed Jan 10 17:19:54 2018 +0100

    add nonce only when proposal is requested
---
 src/backend/taler-merchant-httpd_proposal.c | 104 +++++++++++++++++++++++----
 src/backenddb/plugin_merchantdb_postgres.c  | 107 ++++++++++++++++++++++++++++
 src/include/taler_merchantdb_plugin.h       |  33 +++++++++
 3 files changed, 230 insertions(+), 14 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_proposal.c 
b/src/backend/taler-merchant-httpd_proposal.c
index bbd7d39..c79e2a8 100644
--- a/src/backend/taler-merchant-httpd_proposal.c
+++ b/src/backend/taler-merchant-httpd_proposal.c
@@ -357,11 +357,11 @@ proposal_put (struct MHD_Connection *connection,
 
   for (unsigned int i=0;i<MAX_RETRIES;i++)
   {
-    qs = db->insert_contract_terms (db->cls,
-                                   order_id,
-                                   &mi->pubkey,
-                                   timestamp,
-                                   order);
+    qs = db->insert_order (db->cls,
+                           order_id,
+                           &mi->pubkey,
+                           timestamp,
+                           order);
     if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
       break;
   }
@@ -377,12 +377,9 @@ proposal_put (struct MHD_Connection *connection,
                                               "db error: could not store this 
proposal's data into db");
   }
 
-  res = TMH_RESPONSE_reply_json_pack (connection,
-                                      MHD_HTTP_OK,
-                                      "{s:O, s:o s:o}",
-                                      "data", order,
-                                      "sig", GNUNET_JSON_from_data_auto 
(&merchant_sig),
-                                      "hash", GNUNET_JSON_from_data_auto 
(&pdps.hash));
+  res = TMH_RESPONSE_reply_json (connection,
+                                 json_object (),
+                                 MHD_HTTP_OK);
   GNUNET_JSON_parse_free (spec);
   return res;
 }
@@ -458,6 +455,8 @@ MH_handler_proposal_put (struct TMH_RequestHandler *rh,
  * proposal's data related to the transaction id given as the URL's
  * parameter.
  *
+ * Binds the proposal to a nonce.
+ *
  * @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)
@@ -474,6 +473,7 @@ MH_handler_proposal_lookup (struct TMH_RequestHandler *rh,
 {
   const char *order_id;
   const char *instance;
+  const char *nonce;
   int res;
   enum GNUNET_DB_QueryStatus qs;
   json_t *contract_terms;
@@ -500,6 +500,14 @@ MH_handler_proposal_lookup (struct TMH_RequestHandler *rh,
                                           TALER_EC_PARAMETER_MISSING,
                                            "order_id");
 
+  nonce = MHD_lookup_connection_value (connection,
+                                       MHD_GET_ARGUMENT_KIND,
+                                       "nonce");
+  if (NULL == nonce)
+    return TMH_RESPONSE_reply_arg_missing (connection,
+                                          TALER_EC_PARAMETER_MISSING,
+                                           "nonce");
+
   qs = db->find_contract_terms (db->cls,
                                &contract_terms,
                                order_id,
@@ -516,9 +524,77 @@ MH_handler_proposal_lookup (struct TMH_RequestHandler *rh,
                                               "An error occurred while 
retrieving proposal data from db");
   }
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
-    return TMH_RESPONSE_reply_not_found (connection,
-                                         TALER_EC_PROPOSAL_LOOKUP_NOT_FOUND,
-                                         "unknown transaction id");
+  {
+    qs = db->find_orders (db->cls,
+                          &contract_terms,
+                          order_id,
+                          &mi->pubkey);
+    if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+    {
+      return TMH_RESPONSE_reply_not_found (connection,
+                                           TALER_EC_PROPOSAL_LOOKUP_NOT_FOUND,
+                                           "unknown order id");
+    }
+    GNUNET_assert (NULL != contract_terms);
+    // FIXME:  now we can delete (merchant_pub, order_id) from the 
merchant_orders table
+    json_object_set_new (contract_terms, "nonce", json_string (nonce));
+
+    struct GNUNET_TIME_Absolute timestamp;
+    struct GNUNET_JSON_Specification spec[] = {
+      GNUNET_JSON_spec_absolute_time ("timestamp", &timestamp),
+      GNUNET_JSON_spec_end ()
+    };
+    /* extract fields we need to sign separately */
+    res = TMH_PARSE_json_data (connection, contract_terms, spec);
+    if (GNUNET_NO == res)
+    {
+      return MHD_YES;
+    }
+    if (GNUNET_SYSERR == res)
+    {
+      return TMH_RESPONSE_reply_internal_error (connection,
+                                                
TALER_EC_PROPOSAL_ORDER_PARSE_ERROR,
+                                                "Impossible to parse the 
order");
+    }
+
+    for (unsigned int i=0;i<MAX_RETRIES;i++)
+    {
+      qs = db->insert_contract_terms (db->cls,
+                                      order_id,
+                                      &mi->pubkey,
+                                      timestamp,
+                                      contract_terms);
+      if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
+        break;
+    }
+    if (0 > qs)
+    {
+      /* Special report if retries insufficient */
+      GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
+      /* Always report on hard error as well to enable diagnostics */
+      GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
+      return TMH_RESPONSE_reply_internal_error (connection,
+                                                
TALER_EC_PROPOSAL_STORE_DB_ERROR,
+                                                "db error: could not store 
this proposal's data into db");
+    }
+  }
+
+  const char *stored_nonce = json_string_value 
(json_object_get(contract_terms, "nonce"));
+
+  if (NULL == stored_nonce)
+  {
+    GNUNET_break (0);
+    return TMH_RESPONSE_reply_internal_error (connection,
+                                              
TALER_EC_PROPOSAL_ORDER_PARSE_ERROR,
+                                              "existing proposal has non 
nonce");
+  }
+
+  if (0 != strcmp (stored_nonce, nonce))
+  {
+    return TMH_RESPONSE_reply_bad_request (connection,
+                                           TALER_EC_PROPOSAL_LOOKUP_NOT_FOUND,
+                                           "mismatched nonce");
+  }
 
   res = TMH_RESPONSE_reply_json (connection,
                                  contract_terms,
diff --git a/src/backenddb/plugin_merchantdb_postgres.c 
b/src/backenddb/plugin_merchantdb_postgres.c
index 54d532f..5b14d31 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -95,6 +95,16 @@ postgres_initialize (void *cls)
 {
   struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_ExecuteStatement es[] = {
+    /* Orders created by the frontend, not signed or given a nonce yet.
+       The contract terms will change (nonce will be added) when moved to the
+       contract terms table */
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS merchant_orders ("
+                            "order_id VARCHAR NOT NULL"
+                            ",merchant_pub BYTEA NOT NULL CHECK 
(LENGTH(merchant_pub)=32)"
+                            ",contract_terms BYTEA NOT NULL"
+                            ",timestamp INT8 NOT NULL"
+                            ",PRIMARY KEY (order_id, merchant_pub)"
+                            ");"),
     /* Offers we made to customers */
     GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS 
merchant_contract_terms ("
                             "order_id VARCHAR NOT NULL"
@@ -313,6 +323,15 @@ postgres_initialize (void *cls)
                             " VALUES "
                             "($1, $2, $3, $4, $5)",
                             5),
+    GNUNET_PQ_make_prepare ("insert_order",
+                            "INSERT INTO merchant_orders"
+                            "(order_id"
+                            ",merchant_pub"
+                            ",timestamp"
+                            ",contract_terms"
+                            " VALUES "
+                            "($1, $2, $3, $4)",
+                            4),
     GNUNET_PQ_make_prepare ("mark_proposal_paid",
                             "UPDATE merchant_contract_terms SET"
                             " paid=TRUE WHERE h_contract_terms=$1"
@@ -388,6 +407,14 @@ postgres_initialize (void *cls)
                             " order_id=$1"
                             " AND merchant_pub=$2",
                             2),
+    GNUNET_PQ_make_prepare ("find_orders",
+                            "SELECT"
+                            " contract_terms"
+                            " FROM merchant_orders"
+                            " WHERE"
+                            " order_id=$1"
+                            " AND merchant_pub=$2",
+                            2),
     GNUNET_PQ_make_prepare ("find_contract_terms_by_date",
                             "SELECT"
                             " contract_terms"
@@ -834,6 +861,47 @@ postgres_find_contract_terms (void *cls,
 
 
 /**
+ * Retrieve order given its order id and the instance's merchant public key.
+ *
+ * @param cls closure
+ * @param[out] contract_terms where to store the retrieved contract terms
+ * @param order id order id used to perform the lookup
+ * @param merchant_pub merchant public key that identifies the instance
+ * @return transaction status
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_find_orders (void *cls,
+                      json_t **contract_terms,
+                      const char *order_id,
+                      const struct TALER_MerchantPublicKeyP *merchant_pub)
+{
+  struct PostgresClosure *pg = cls;
+
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_string (order_id),
+    GNUNET_PQ_query_param_auto_from_type (merchant_pub),
+    GNUNET_PQ_query_param_end
+  };
+  struct GNUNET_PQ_ResultSpec rs[] = {
+    TALER_PQ_result_spec_json ("contract_terms",
+                               contract_terms),
+    GNUNET_PQ_result_spec_end
+  };
+
+  *contract_terms = NULL;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Finding contract term, order_id: '%s', merchant_pub: '%s'.\n",
+              order_id,
+              TALER_B2S (merchant_pub));
+  check_connection (pg);
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                  "find_orders",
+                                                  params,
+                                                  rs);
+}
+
+
+/**
  * Insert proposal data and its hashcode into db
  *
  * @param cls closure
@@ -881,6 +949,43 @@ postgres_insert_contract_terms (void *cls,
 
 
 /**
+ * Insert order into the DB.
+ *
+ * @param cls closure
+ * @param order_id identificator of the proposal being stored
+ * @param merchant_pub merchant's public key
+ * @param timestamp timestamp of this proposal data
+ * @param contract_terms proposal data to store
+ * @return transaction status
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_insert_order (void *cls,
+                       const char *order_id,
+                       const struct TALER_MerchantPublicKeyP *merchant_pub,
+                       struct GNUNET_TIME_Absolute timestamp,
+                       const json_t *contract_terms)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_string (order_id),
+    GNUNET_PQ_query_param_auto_from_type (merchant_pub),
+    GNUNET_PQ_query_param_absolute_time (&timestamp),
+    TALER_PQ_query_param_json (contract_terms),
+    GNUNET_PQ_query_param_end
+  };
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "inserting order: order_id: %s, merchant_pub: %s.\n",
+              order_id,
+              TALER_B2S (merchant_pub));
+  check_connection (pg);
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                            "insert_order",
+                                            params);
+}
+
+
+/**
  * Mark contract terms as payed.  Needed by /history as only payed
  * contracts must be shown.
  *
@@ -3250,6 +3355,8 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
   plugin->find_deposits_by_wtid = &postgres_find_deposits_by_wtid;
   plugin->find_proof_by_wtid = &postgres_find_proof_by_wtid;
   plugin->insert_contract_terms = &postgres_insert_contract_terms;
+  plugin->insert_order = &postgres_insert_order;
+  plugin->find_orders = &postgres_find_orders;
   plugin->find_contract_terms = &postgres_find_contract_terms;
   plugin->find_contract_terms_history = &postgres_find_contract_terms_history;
   plugin->find_contract_terms_by_date = &postgres_find_contract_terms_by_date;
diff --git a/src/include/taler_merchantdb_plugin.h 
b/src/include/taler_merchantdb_plugin.h
index 228fa90..85cadd8 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -184,6 +184,23 @@ struct TALER_MERCHANTDB_Plugin
   int
   (*initialize) (void *cls);
 
+  /**
+   * Insert order into db.
+   *
+   * @param cls closure
+   * @param order_id alphanumeric string that uniquely identifies the proposal
+   * @param merchant_pub merchant's public key
+   * @param timestamp timestamp of this proposal data
+   * @param contract_terms proposal data to store
+   * @return transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*insert_order) (void *cls,
+                   const char *order_id,
+                   const struct TALER_MerchantPublicKeyP *merchant_pub,
+                   struct GNUNET_TIME_Absolute timestamp,
+                   const json_t *contract_terms);
+
 
   /**
    * Insert proposal data into db; the routine will internally hash and
@@ -238,6 +255,22 @@ struct TALER_MERCHANTDB_Plugin
                          const char *order_id,
                          const struct TALER_MerchantPublicKeyP *merchant_pub);
 
+  /**
+   * Retrieve order given its order id and the instance's merchant public key.
+   *
+   * @param cls closure
+   * @param[out] contract_terms where to store the retrieved contract terms
+   * @param order id order id used to perform the lookup
+   * @param merchant_pub merchant public key that identifies the instance
+   * @return transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*find_orders) (void *cls,
+                  json_t **contract_terms,
+                  const char *order_id,
+                  const struct TALER_MerchantPublicKeyP *merchant_pub);
+
+
 
   /**
    * Retrieve proposal data given its hashcode

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



reply via email to

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