From 974896506507eeaf7290536a75009eeb812186be Mon Sep 17 00:00:00 2001 From: Jonathan Buchanan Date: Sun, 19 Jul 2020 17:48:03 -0400 Subject: add update_contract_terms to backenddb (for forget) --- src/backenddb/plugin_merchantdb_postgres.c | 92 ++++++++++++++++++++++++++++++ src/backenddb/test_merchantdb.c | 32 +++++++++++ src/include/taler_merchantdb_plugin.h | 22 +++++++ 3 files changed, 146 insertions(+) (limited to 'src') diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c index b0c82e4f..6e7b9554 100644 --- a/src/backenddb/plugin_merchantdb_postgres.c +++ b/src/backenddb/plugin_merchantdb_postgres.c @@ -1546,6 +1546,83 @@ postgres_insert_contract_terms (void *cls, } +/** + * Update the contract terms stored for @a order_id. Note that some attributes are + * expected to be calculated inside of the function, like the hash of the + * contract terms (to be hashed), the creation_time and pay_deadline (to be + * obtained from the merchant_orders table). The "session_id" should be + * initially set to the empty string. The "fulfillment_url" and "refund_deadline" + * must be extracted from @a contract_terms. + * + * @param cls closure + * @param instance_id instance's identifier + * @param order_id order_id used to store + * @param contract_terms contract to store + * @return transaction status, #GNUNET_DB_STATUS_HARD_ERROR if @a contract_terms + * is malformed + */ +static enum GNUNET_DB_QueryStatus +postgres_update_contract_terms (void *cls, + const char *instance_id, + const char *order_id, + json_t *contract_terms) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_TIME_Absolute pay_deadline; + struct GNUNET_TIME_Absolute refund_deadline; + const char *fulfillment_url; + struct GNUNET_HashCode h_contract_terms; + + if (GNUNET_OK != + TALER_JSON_contract_hash (contract_terms, + &h_contract_terms)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + + { + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ("fulfillment_url", + &fulfillment_url), + TALER_JSON_spec_absolute_time ("pay_deadline", + &pay_deadline), + TALER_JSON_spec_absolute_time ("refund_deadline", + &refund_deadline), + GNUNET_JSON_spec_end () + }; + enum GNUNET_GenericReturnValue res; + + res = TALER_MHD_parse_json_data (NULL, + contract_terms, + spec); + if (GNUNET_OK != res) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + } + + check_connection (pg); + { + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_string (order_id), + TALER_PQ_query_param_json (contract_terms), + GNUNET_PQ_query_param_auto_from_type (&h_contract_terms), + GNUNET_PQ_query_param_absolute_time (&pay_deadline), + GNUNET_PQ_query_param_absolute_time (&refund_deadline), + GNUNET_PQ_query_param_string (fulfillment_url), + GNUNET_PQ_query_param_end + }; + + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "update_contract_terms", + params); + } +} + + /** * Delete information about a contract. Note that the transaction must * enforce that the contract is not awaiting payment anymore AND was not @@ -7046,6 +7123,20 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) " FROM merchant_instances" " WHERE merchant_id=$1)", 7), + /* for postgres_update_contract_terms() */ + GNUNET_PQ_make_prepare ("update_contract_terms", + "UPDATE merchant_contract_terms SET" + " contract_terms=$3" + ",h_contract_terms=$4" + ",pay_deadline=$5" + ",refund_deadline=$6" + ",fulfillment_url=$7" + " WHERE order_id=$2" + " AND merchant_serial=" + " (SELECT merchant_serial" + " FROM merchant_instances" + " WHERE merchant_id=$1)", + 7), /* for postgres_delete_contract_terms() */ GNUNET_PQ_make_prepare ("delete_contract_terms", "DELETE FROM merchant_contract_terms" @@ -8316,6 +8407,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) plugin->insert_order_lock = &postgres_insert_order_lock; plugin->lookup_contract_terms = &postgres_lookup_contract_terms; plugin->insert_contract_terms = &postgres_insert_contract_terms; + plugin->update_contract_terms = &postgres_update_contract_terms; plugin->delete_contract_terms = &postgres_delete_contract_terms; plugin->lookup_deposits = &postgres_lookup_deposits; plugin->insert_exchange_signkey = &postgres_insert_exchange_signkey; diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c index 0d415555..9a5cec54 100644 --- a/src/backenddb/test_merchantdb.c +++ b/src/backenddb/test_merchantdb.c @@ -1631,6 +1631,29 @@ test_insert_contract_terms (const struct InstanceData *instance, } +/** + * Test updating contract terms for an order. + * + * @param instance the instance. + * @param order the order containing the contract terms. + * @param expected_result the result we expect to receive. + * @return 0 on success, 1 otherwise. + */ +static int +test_update_contract_terms (const struct InstanceData *instance, + const struct OrderData *order, + enum GNUNET_DB_QueryStatus expected_result) +{ + TEST_COND_RET_ON_FAIL (expected_result == + plugin->update_contract_terms (plugin->cls, + instance->instance.id, + order->id, + order->contract), + "Update contract terms failed\n"); + return 0; +} + + /** * Tests lookup of contract terms * @@ -2019,6 +2042,15 @@ run_test_orders (struct TestOrders_Closure *cls) return 1; } } + /* Test update contract terms */ + json_object_set_new (cls->orders[0].contract, + "some_new_field", + json_string ("another value")); + TEST_RET_ON_FAIL (test_update_contract_terms (&cls->instance, + &cls->orders[0], + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + TEST_RET_ON_FAIL (test_lookup_contract_terms (&cls->instance, + &cls->orders[0])); /* Test lookup order status */ TEST_RET_ON_FAIL (test_lookup_order_status (&cls->instance, &cls->orders[0], diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h index 71b28fb7..16152245 100644 --- a/src/include/taler_merchantdb_plugin.h +++ b/src/include/taler_merchantdb_plugin.h @@ -1086,6 +1086,28 @@ struct TALER_MERCHANTDB_Plugin json_t *contract_terms); + /** + * Update the contract terms stored for @a order_id. Note that some attributes are + * expected to be calculated inside of the function, like the hash of the + * contract terms (to be hashed), the creation_time and pay_deadline (to be + * obtained from the merchant_orders table). The "session_id" should be + * initially set to the empty string. The "fulfillment_url" and "refund_deadline" + * must be extracted from @a contract_terms. + * + * @param cls closure + * @param instance_id instance's identifier + * @param order_id order_id used to store + * @param contract_terms contract to store + * @return transaction status, #GNUNET_DB_STATUS_HARD_ERROR if @a contract_terms + * is malformed + */ + enum GNUNET_DB_QueryStatus + (*update_contract_terms)(void *cls, + const char *instance_id, + const char *order_id, + json_t *contract_terms); + + /** * Delete information about a contract. Note that the transaction must * enforce that the contract is not awaiting payment anymore AND was not -- cgit v1.2.3