diff options
author | Marcello Stanisci <marcello.stanisci@inria.fr> | 2015-10-29 11:33:03 +0100 |
---|---|---|
committer | Marcello Stanisci <marcello.stanisci@inria.fr> | 2015-10-29 11:33:03 +0100 |
commit | bfcb32339fbed0513090b0f546b04c90c11ea474 (patch) | |
tree | 2be543c0f888773972e745aafd9b9203f0144e2c | |
parent | 6d18f1bfba939c2446c86c1152c274029bd5d63c (diff) | |
download | merchant-bfcb32339fbed0513090b0f546b04c90c11ea474.tar.gz merchant-bfcb32339fbed0513090b0f546b04c90c11ea474.tar.bz2 merchant-bfcb32339fbed0513090b0f546b04c90c11ea474.zip |
- Adding cli debugging feature to contract generation (i.e. it is
possible to GET the frontend with 'curl' in order to invoke the
backend to generate a contract. See 'generate_taler_contract.php'
to get instructions on how to do it)
- Removing unneeded functions from the 'contract' shared library
(which presusmably will be entirely removed)
- Some minor fixes
-rw-r--r-- | src/backend-lib/merchant_api_contract.c | 79 | ||||
-rw-r--r-- | src/backend-lib/taler_merchant_contract_lib.h | 52 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd.c | 10 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_contract.c | 67 | ||||
-rw-r--r-- | src/frontend/generate_taler_contract.php | 23 | ||||
-rw-r--r-- | src/include/merchant.h | 20 |
6 files changed, 65 insertions, 186 deletions
diff --git a/src/backend-lib/merchant_api_contract.c b/src/backend-lib/merchant_api_contract.c index da55ce5e..20b69cd3 100644 --- a/src/backend-lib/merchant_api_contract.c +++ b/src/backend-lib/merchant_api_contract.c @@ -58,82 +58,3 @@ MERCHANT_get_wire_json (const struct MERCHANT_WIREFORMAT_Sepa *wire, return root; } - - - -/** -* Take from the frontend the (partly) generated contract and fill -* the missing values in it; for example, the SEPA details. -* Moreover, it stores the contract in the DB. -* @param j_contract parsed contract, originated by the frontend. It will be -* hold the new values. -* @param db_conn the handle to the local DB -* @param contract where to store the (subset of the) contract to be (still) signed -* @param timestamp contract's timestamp (shall be generated by the merchant) -* @param expiry the time when the contract will expire -* @param edate when the merchant wants to receive the wire transfer corresponding -* to this deal (this value is also a field inside the 'wire' JSON format) -* @param refund deadline until which the merchant can return the paid amount -* @param nounce the nounce used to hash the wire details -* @param a will be pointed to the (allocated) stringified 0-terminated contract -* @return GNUNET_OK on success, GNUNET_NO if attempting to double insert the -* same contract, GNUNET_SYSERR in case of other (mostly DB related) errors. -*/ - -/** -* TODO: inspect reference counting and, accordingly, free those json_t*(s) -* still allocated */ - -uint32_t -MERCHANT_handle_contract (json_t *j_contract, - PGconn *db_conn, - struct Contract *contract, - struct GNUNET_TIME_Absolute timestamp, - struct GNUNET_TIME_Absolute expiry, - struct GNUNET_TIME_Absolute edate, - struct GNUNET_TIME_Absolute refund, - char **a, - uint64_t nounce) -{ - json_t *j_amount; - json_int_t j_product_id; - json_int_t j_trans_id; - char *contract_str; - - struct TALER_Amount amount; - - - - /* Extracting values useful for DB work. Only gettable from the JSON - since they are generated by the frontend */ - if (-1 == json_unpack (j_contract, "{s:o, s:I, s:{s:I}}", - "amount", &j_amount, - "trans_id", &j_trans_id, - "details", "product_id", - &j_product_id)) - { - printf ("no unpacking\n"); - return GNUNET_SYSERR; - } - - TALER_json_to_amount (j_amount, &amount); - contract_str = json_dumps (j_contract, JSON_COMPACT | JSON_PRESERVE_ORDER); - *a = contract_str; - GNUNET_CRYPTO_hash (contract_str, strlen (contract_str) + 1, - &contract->h_contract_details); - contract->purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_CONTRACT); - contract->purpose.size = htonl (sizeof (struct Contract)); - - // DB mgmt - return MERCHANT_DB_contract_create (db_conn, - timestamp, - expiry, - edate, - refund, - &amount, - &contract->h_contract_details, - (uint64_t) j_trans_id, // safe? - contract_str, - nounce, - (uint64_t) j_product_id); -} diff --git a/src/backend-lib/taler_merchant_contract_lib.h b/src/backend-lib/taler_merchant_contract_lib.h index 1d2d0eba..3f95841f 100644 --- a/src/backend-lib/taler_merchant_contract_lib.h +++ b/src/backend-lib/taler_merchant_contract_lib.h @@ -1,22 +1,4 @@ /** - * The contract sent by the merchant to the wallet - */ -struct Contract -{ - /** - * Purpose header for the signature over contract - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash of the JSON contract in UTF-8 including 0-termination, - * using JSON_COMPACT encoding with sorted fields. - */ - struct GNUNET_HashCode h_contract_details; - -}; - -/** * Take the global wire details and return a JSON containing them, * compliantly with the Taler's API. * @param wire the merchant's wire details @@ -27,37 +9,3 @@ struct Contract json_t * MERCHANT_get_wire_json (const struct MERCHANT_WIREFORMAT_Sepa *wire, uint64_t salt); - -/** -* Take from the frontend the (partly) generated contract and fill -* the missing values in it; for example, the SEPA details. -* Moreover, it stores the contract in the DB. -* @param j_contract parsed contract, originated by the frontend. It will be -* hold the new values. -* @param db_conn the handle to the local DB -* @param contract where to store the (subset of the) contract to be (still) signed -* @param timestamp contract's timestamp (shall be generated by the merchant) -* @param expiry the time when the contract will expire -* @param edate when the merchant wants to receive the wire transfer corresponding -* to this deal (this value is also a field inside the 'wire' JSON format) -* @param refund deadline until which the merchant can return the paid amount -* @param nounce the nounce used to hash the wire details -* @param a will be pointed to the (allocated) stringified 0-terminated contract -* @return GNUNET_OK on success, GNUNET_NO if attempting to double insert the -* same contract, GNUNET_SYSERR in case of other (mostly DB related) errors. -*/ - -/** -* TODO: inspect reference counting and, accordingly, free those json_t*(s) -* still allocated */ - -uint32_t -MERCHANT_handle_contract (json_t *j_contract, - PGconn *db_conn, - struct Contract *contract, - struct GNUNET_TIME_Absolute timestamp, - struct GNUNET_TIME_Absolute expiry, - struct GNUNET_TIME_Absolute edate, - struct GNUNET_TIME_Absolute refund, - char **a, - uint64_t nounce); diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index 8da6ce21..b7a914da 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -177,7 +177,7 @@ url_handler (void *cls, "Hello, Customer.\n", 0, &TMH_MHD_handler_static_response, MHD_HTTP_OK }, - { "/contract", MHD_HTTP_METHOD_GET, "application/json", + { "/contract", MHD_HTTP_METHOD_POST, "application/json", NULL, 0, &MH_handler_contract, MHD_HTTP_OK }, @@ -396,7 +396,6 @@ run (void *cls, char *const *args, const char *cfgfile, { unsigned int cnt; - mints = NULL; keyfile = NULL; result = GNUNET_SYSERR; @@ -426,21 +425,22 @@ run (void *cls, char *const *args, const char *cfgfile, EXITIF (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (config, "merchant", - "port", + "PORT", &port)); EXITIF (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (config, "merchant", - "hostname", + "HOSTNAME", &hostname)); EXITIF (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (config, "merchant", - "currency", + "CURRENCY", &TMH_mint_currency_string)); salt = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX); + EXITIF (NULL == (mctx = TALER_MINT_init ())); for (cnt = 0; cnt < nmints; cnt++) { diff --git a/src/backend/taler-merchant-httpd_contract.c b/src/backend/taler-merchant-httpd_contract.c index 65ec323b..e7278c7c 100644 --- a/src/backend/taler-merchant-httpd_contract.c +++ b/src/backend/taler-merchant-httpd_contract.c @@ -43,14 +43,16 @@ extern PGconn *db_conn; extern long long salt; /** - * Manage a contract request - * + * Manage a contract request. In practical terms, it adds the fields 'mints', + * 'merchant_pub', and 'H_wire' to the contract 'proposition' gotten from the + * frontend. Finally, it adds (outside of the contract) a signature of the + * (hashed stringification) of this contract and the hashed stringification + * of this contract to the final bundle sent back to the frontend. * @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 - * * @return MHD result code */ int @@ -67,44 +69,24 @@ MH_handler_contract (struct TMH_RequestHandler *rh, const struct TALER_MINT_Keys *keys; int res; int cnt; - uint64_t trans_id; - struct TALER_Amount amount; - struct GNUNET_TIME_Absolute timestamp; - struct GNUNET_TIME_Absolute refund; - struct GNUNET_TIME_Absolute expiry; - struct GNUNET_TIME_Absolute edate; struct GNUNET_HashCode h_wire; struct GNUNET_CRYPTO_EddsaPublicKey pubkey; - struct TMH_PARSE_FieldSpecification spec[] = - { - TMH_PARSE_member_time_abs ("timestamp", ×tamp), - TMH_PARSE_member_time_abs ("refund_deadline", &refund), - TMH_PARSE_member_time_abs ("expiry", &expiry), - TMH_PARSE_member_amount ("amount", &amount), - TMH_PARSE_member_uint64 ("trans_id", &trans_id), - TMH_PARSE_MEMBER_END - }; - + struct MERCHANT_Contract contract; + char *contract_str; + res = TMH_PARSE_post_json (connection, connection_cls, upload_data, upload_data_size, &root); - if (GNUNET_SYSERR == res) return MHD_NO; /* the POST's body has to be further fetched */ if ((GNUNET_NO == res) || (NULL == root)) return MHD_YES; - /* 1. Generate preferred mint(s) array. + /* Generate preferred mint(s) array. */ - The 'mint' JSON layout is as follows: - - { "url": "mint_base_url", - "master_pub": "base32 mint's master public key" } - */ - trusted_mints = json_array (); for (cnt = 0; cnt < nmints; cnt++) { @@ -121,31 +103,22 @@ MH_handler_contract (struct TMH_RequestHandler *rh, } } - /* Return badly if no mints are trusted (or ready). WARNING: it - may be possible that a mint trusted by the wallet is good, but - still pending; that case must be handled with some "polling-style" - routine, simply ignored, or ended with an invitation to the wallet - to just retry later */ + /** + * Return badly if no mints are trusted (or no call to /keys has still + * returned the expected data). WARNING: it + * may be possible that a mint trusted by the wallet is good, but + * still pending; that case must be handled with some "polling-style" + * routine, simply ignored, or ended with an invitation to the wallet + * to just retry later + */ if (!json_array_size (trusted_mints)) return MHD_NO; json_object_set_new (root, "mints", trusted_mints); - res = TMH_PARSE_json_data (connection, root, spec); - - if (GNUNET_SYSERR == res) - return MHD_NO; /* hard failure */ - if (GNUNET_NO == res) - return MHD_YES; /* failure */ - - - /* (indicative) deadline which the merchant wants its wire tranfer - before */ - edate = GNUNET_TIME_absolute_add (timestamp, GNUNET_TIME_UNIT_WEEKS); - TALER_round_abs_time (&edate); if (NULL == (j_wire = MERCHANT_get_wire_json (wire, salt))) - return MHD_NO; + return MHD_NO; /* hash wire objcet */ if (GNUNET_SYSERR == @@ -161,8 +134,8 @@ MH_handler_contract (struct TMH_RequestHandler *rh, "merchant_pub", TALER_json_from_data (&pubkey, sizeof (pubkey))); - /* store relevant values for this contract, in DB */ - //res = MERCHANT_handle_contract (); + /* Sign */ + return TMH_RESPONSE_reply_json (connection, root, MHD_HTTP_OK); } diff --git a/src/frontend/generate_taler_contract.php b/src/frontend/generate_taler_contract.php index 1b9648bb..52e11940 100644 --- a/src/frontend/generate_taler_contract.php +++ b/src/frontend/generate_taler_contract.php @@ -23,10 +23,27 @@ 2. generate the JSON to forward to the backend 3. forward the response with the contract from the backend to to the wallet -*/ -$cli_debug = true; + + To test this feature from the command line, issue: + + - $ curl http://merchant_url/generate_taler_contract.php?cli_debug=yes + if the whole "journey" to the backend is begin tested + - $ curl http://merchant_url/generate_taler_contract.php?backend_test=no + if just the frontend job is being tested +*/ + +$cli_debug = false; $backend_test = true; +if ($_GET['cli_debug'] == 'yes') + $cli_debug = true; + +if ($_GET['backend_test'] == 'no') +{ + $cli_debug = true; + $backend_test = false; +} + // 1) recover the session information session_start(); if (!$cli_debug && ((! isset($_SESSION['receiver'])) || @@ -84,7 +101,7 @@ $json = json_encode (array ('amount' => array ('value' => $value, 'max_fee' => array ('value' => 3, 'fraction' => 01010, 'currency' => $currency), - 'trans_id' => $transaction_id, + 'transaction_id' => $transaction_id, 'products' => array ( array ('description' => $desc, 'quantity' => 1, diff --git a/src/include/merchant.h b/src/include/merchant.h index 1368c575..04dd253d 100644 --- a/src/include/merchant.h +++ b/src/include/merchant.h @@ -64,6 +64,26 @@ struct MERCHANT_Mint }; /** + * The contract sent by the merchant to the wallet + */ +struct MERCHANT_Contract +{ + /** + * Purpose header for the signature over contract + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash of the JSON contract in UTF-8 including 0-termination, + * using JSON_COMPACT encoding with sorted fields. + */ + struct GNUNET_HashCode h_contract_details; + +}; + + + +/** * Parses mints from the configuration. * * @param cfg the configuration |