summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcello Stanisci <marcello.stanisci@inria.fr>2015-08-05 19:03:53 +0200
committerMarcello Stanisci <marcello.stanisci@inria.fr>2015-08-05 19:03:53 +0200
commit8b32ffd60d2d6f34f35fd308183a4b09510c5e7b (patch)
treeb24d968397305ccdf4c9ad92450722e653449df1
parent9e1c2739664c3b0567449c7103b1e028cda340aa (diff)
downloadmerchant-8b32ffd60d2d6f34f35fd308183a4b09510c5e7b.tar.gz
merchant-8b32ffd60d2d6f34f35fd308183a4b09510c5e7b.tar.bz2
merchant-8b32ffd60d2d6f34f35fd308183a4b09510c5e7b.zip
major fixes in JSON mgmt
-rw-r--r--src/backend/melted/merchant_db.c25
-rw-r--r--src/backend/melted/taler-merchant-httpd.c185
2 files changed, 127 insertions, 83 deletions
diff --git a/src/backend/melted/merchant_db.c b/src/backend/melted/merchant_db.c
index 7a79a12c..6345f8a6 100644
--- a/src/backend/melted/merchant_db.c
+++ b/src/backend/melted/merchant_db.c
@@ -88,7 +88,7 @@ MERCHANT_DB_initialize (PGconn *conn, int tmp)
"BEGIN TRANSACTION;"
"CREATE %1$s TABLE IF NOT EXISTS contracts ("
"transaction_id SERIAL8 PRIMARY KEY,"
- "amount INT4 NOT NULL,"
+ "amount INT8 NOT NULL,"
"amount_fraction INT4 NOT NULL,"
"description TEXT NOT NULL,"
"nounce BYTEA NOT NULL,"
@@ -204,21 +204,28 @@ MERCHANT_DB_contract_create (PGconn *conn,
{
PGresult *res;
uint64_t expiry_ms_nbo;
- uint32_t value_nbo;
+ uint64_t value_nbo;
uint32_t fraction_nbo;
uint64_t nounce_nbo;
ExecStatusType status;
uint64_t id;
+
+ value_nbo = GNUNET_htonll (amount->value);
+ fraction_nbo = GNUNET_htonll (amount->fraction);
+ nounce_nbo = GNUNET_htonll (nounce);
+ expiry_ms_nbo = GNUNET_htonll (expiry.abs_value_us);
+ product = GNUNET_htonll (product);
+
/* ported. To be tested/compiled */
struct TALER_PQ_QueryParam params[] = {
- TALER_PQ_query_param_uint32 (&value_nbo),
- TALER_PQ_query_param_uint32 (&fraction_nbo),
+ TALER_PQ_query_param_uint32 (&value_nbo), //FIXME uninitialized!
+ TALER_PQ_query_param_uint32 (&fraction_nbo), //FIXME uninitialized!
/* a *string* is being put in the following statement,
though the API talks about a *blob*. Will this be liked by
the DB ? */
TALER_PQ_query_param_fixed_size (desc, strlen(desc)),
- TALER_PQ_query_param_uint64 (&nounce_nbo),
- TALER_PQ_query_param_uint64 (&expiry_ms_nbo),
+ TALER_PQ_query_param_uint64 (&nounce_nbo), //FIXME uninitialized!
+ TALER_PQ_query_param_uint64 (&expiry_ms_nbo), //FIXME uninitialized!
TALER_PQ_query_param_uint64 (&product),
TALER_PQ_query_param_end
};
@@ -227,11 +234,7 @@ MERCHANT_DB_contract_create (PGconn *conn,
TALER_PQ_result_spec_end
};
- expiry_ms_nbo = GNUNET_htonll (expiry.abs_value_us);
- value_nbo = htonl (amount->value);
- fraction_nbo = htonl (amount->fraction);
- nounce_nbo = GNUNET_htonll (nounce);
- product = GNUNET_htonll (product);
+
/* NOTE: the statement is prepared by MERCHANT_DB_initialize function */
res = TALER_PQ_exec_prepared (conn, "contract_create", params);
status = PQresultStatus (res);
diff --git a/src/backend/melted/taler-merchant-httpd.c b/src/backend/melted/taler-merchant-httpd.c
index bfa7904e..ea3a22de 100644
--- a/src/backend/melted/taler-merchant-httpd.c
+++ b/src/backend/melted/taler-merchant-httpd.c
@@ -33,6 +33,7 @@
#include "taler-mint-httpd_withdraw.h"
#include "taler-mint-httpd_refresh.h"
#include "taler-mint-httpd_keystate.h"
+#include "taler-mint-httpd_responses.h"
#include "merchant.h"
#include "merchant_db.h"
@@ -360,12 +361,12 @@ hash_wireformat (uint64_t nounce)
/*
* Make a binary blob representing a contract, store it into the DB, sign it
-* and return a pointer to the signed blob.
+* and return a pointer to it.
* @param a 0-terminated string representing the description of this
* purchase (it should contain a human readable description of the good
* in question)
-* @param product some product numerical id. Its indended use is to link this
-* good, or service being sold to the original products' DB managed by the frontend
+* @param product some product numerical id. Its indended use is to link the
+* good, or service being sold to some entry in the DB managed by the frontend
* @price the cost of this good or service
* @return pointer to the allocated contract (which has a field, 'sig', holding
* its own signature), NULL upon errors
@@ -470,8 +471,8 @@ url_handler (void *cls,
unsigned int status;
unsigned int no_destroy;
- uint64_t prod_id;
- struct Contract contract;
+ json_int_t prod_id;
+ struct Contract *contract;
struct MHD_Response *resp;
struct TALER_Amount price;
struct GNUNET_CRYPTO_EddsaPublicKey pub;
@@ -483,7 +484,7 @@ url_handler (void *cls,
json_t *response;
int res;
- char *desc;
+ const char *desc;
#define URL_HELLO "/hello"
#define URL_CONTRACT "/contract"
@@ -501,54 +502,108 @@ url_handler (void *cls,
// to be called by the frontend passing all the product's information
// which are relevant for the contract's generation
if (0 == strncasecmp (url, URL_CONTRACT, sizeof (URL_CONTRACT)))
- {
- if (0 == strcmp (MHD_HTTP_METHOD_GET, method))
- status = generate_message (&resp, "Sorry, only POST is allowed");
- else
-
- /*
- 3. pack the contract's json
- 4. return it
- */
-
- res = TMH_PARSE_post_json (connection,
+ {
+ if (0 == strcmp (MHD_HTTP_METHOD_GET, method))
+ status = generate_message (&resp, "Sorry, only POST is allowed");
+ else
+ res = TMH_PARSE_post_json (connection,
connection_cls,
upload_data,
upload_data_size,
&root);
if (GNUNET_SYSERR == res)
- /* how to manage? */
- if ( (GNUNET_NO == res) || (NULL == root) )
- /* how to manage? */
- if (!json_unpack (root, "{s:s, s:I, s:o}",
- "desc", &desc,
- "product", &prod_id,
- "price", json_price))
+ {
+ status = generate_message (&resp, "unable to parse JSON root");
+ return MHD_NO;
+
+ }
+ if ((GNUNET_NO == res) || (NULL == root))
+ return MHD_YES;
+
+ /* The frontend should supply a JSON in the follwoing format:
+
+ {
+
+ "desc" : string human-readable describing this deal,
+ "product" : uint64-like integer referring to the product in some
+ DB adminstered by the frontend,
+ "price" : a 'struct TALER_Amount' in the Taler compliant JSON format }
+
+ */
+
+ #if 0
+ /*res = json_typeof (root); <- seg fault*/
+ json_int_t id;
+ const char *desc_test;
+ const char *cur_test;
+ json_t *id_json;
+ json_t *desc_json;
+ json_t *cur_json;
+ id_json = json_object_get (root, "product");
+ desc_json = json_object_get (root, "desc");
+ id = json_integer_value (id_json);
+ desc_test = json_string_value (desc_json);
+ json_price = json_object_get (root, "price");
+ json_typeof (json_price);
+ cur_json = json_object_get (json_price, "currency");
+ cur_test = json_string_value (cur_json);
+ printf ("id is %" JSON_INTEGER_FORMAT "\n", id);
+ printf ("desc is %s\n", desc_test);
+ TALER_json_to_amount (json_price, &price);
+ printf ("cur_test is %s\n", price.currency);
+ #endif
+ json_error_t err;
+ #if 0
+ if (res = json_unpack_ex (root, &err, JSON_VALIDATE_ONLY, "{s:s, s:I, s:o}",
+ "desc",
+ //&desc,
+ "product",
+ //&prod_id,
+ "price"//,
+ //json_price
+ ))
+ #else
+ if (res = json_unpack (root, "{s:s, s:I, s:o}",
+ "desc",
+ &desc,
+ "product",
+ &prod_id,
+ "price",
+ &json_price
+ ))
+ #endif
+
+
/* still not possible to return a taler-compliant error message
since this JSON format is not among the taler officials ones */
- status = generate_message (&resp, "unable to parse /contract JSON");
+ {
+ status = generate_message (&resp, "unable to parse /contract JSON\n");
+ }
else
{
- if (GNUNET_OK != TALER_json_to_amount (&json_price, &price))
- /* still not possible to return a taler-compliant error message
+
+ if (GNUNET_OK != TALER_json_to_amount (json_price, &price))
+ {/* still not possible to return a taler-compliant error message
since this JSON format is not among the taler officials ones */
- status = generate_message (&resp, "unable to parse `price' field in /contract JSON");
+ status = generate_message (&resp, "unable to parse `price' field in /contract JSON");}
else
- {
+ {
+ /* Let's generate this contract! */
+ if (NULL == (contract = generate_and_store_contract (desc, prod_id, &price)))
+ {
+ /* status equals 500, so the user will get a "Internal server error" */
+ //failure_resp (connection, status);
+ status = generate_message (&resp, "unable to generate and store this contract");
+ //return MHD_YES;
+
+ }
+ else
+ {
json_decref (root);
json_decref (json_price);
- /* Let's generate this contract! */
- /* First, initialize the DB, since it'll be stored there */
- if (NULL == (contract = generate_and_store_contract (desc, prod_id, &price)))
- {
- /* status equals 500, so the user will get a "Internal server error" */
- failure_resp (connection, status);
- return MHD_YES;
-
- }
- else
- {
+
+ printf ("Good contract\n");
/* the contract is good and stored in DB, produce now JSON to return.
As of now, the format is {"contract" : base32contract,
"sig" : contractSignature,
@@ -557,35 +612,22 @@ url_handler (void *cls,
*/
- sig_enc = TALER_json_from_eddsa_sig (contract.purpose, contract.sig);
- GNUNET_CRYPTO_eddsa_key_get_public (&privkey, &pub);
- eddsa_pub_enc = TALER_json_from_data (pub, sizeof (pub));
- /* cutting of the signature at the beginning */
- contract_enc = TALER_json_from_data (&contract.purpose, sizeof (contract
+ sig_enc = TALER_json_from_eddsa_sig (&contract->purpose, &contract->sig);
+ GNUNET_CRYPTO_eddsa_key_get_public (privkey, &pub);
+ eddsa_pub_enc = TALER_json_from_data ((void *) &pub, sizeof (pub));
+ /* cutting of the signature at the beginning */
+ contract_enc = TALER_json_from_data (&contract->purpose, sizeof (*contract)
- offsetof (struct Contract, purpose)
- + 1));
- response = json_pack ("{s:o, s:o, s:o}", "contract", contract_enc, "sig", sig_enc,
+ + strlen (desc) +1);
+ response = json_pack ("{s:o, s:o, s:o}", "contract", contract_enc, "sig", sig_enc,
"eddsa_pub", eddsa_pub_enc);
- TMH_RESPONSE_reply_json (connection, response, MHD_HTTP_OK);
- /* FRONTIER - CODE ABOVE STILL NOT TESTED */
-
- }
-
-
-
-
-
-
-
- }
-
+ TMH_RESPONSE_reply_json (connection, response, MHD_HTTP_OK);
+ printf ("Got something?\n");
+ return MHD_YES;
+ /* FRONTIER - CODE ABOVE STILL NOT TESTED */
+ }
+ }
}
-
-
-
-
-
-
}
if (NULL != resp)
@@ -596,13 +638,12 @@ url_handler (void *cls,
}
else
EXITIF (GNUNET_OK != failure_resp (connection, status));
- return MHD_YES;
-
- EXITIF_exit:
- result = GNUNET_SYSERR;
- GNUNET_SCHEDULER_shutdown ();
- return MHD_NO;
+ return MHD_YES;
+ EXITIF_exit:
+ result = GNUNET_SYSERR;
+ GNUNET_SCHEDULER_shutdown ();
+ return MHD_NO;
}
/**