summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-08-24 14:12:02 +0200
committerChristian Grothoff <christian@grothoff.org>2020-08-24 14:12:02 +0200
commitf23e2c2cdc8d2665d76a335f58a640763c9a425e (patch)
treed15041acbad399cd3768c97ed4ee5a82d0a0c63c
parent8d73d07d559732dbd010b802ea4ed3602964c0cd (diff)
downloadmerchant-f23e2c2cdc8d2665d76a335f58a640763c9a425e.tar.gz
merchant-f23e2c2cdc8d2665d76a335f58a640763c9a425e.tar.bz2
merchant-f23e2c2cdc8d2665d76a335f58a640763c9a425e.zip
make fulfillment URL optional, fix #6498 as discussed
-rw-r--r--src/backend/taler-merchant-httpd_get-orders-ID.c65
-rw-r--r--src/backend/taler-merchant-httpd_private-get-orders-ID.c19
-rw-r--r--src/backend/taler-merchant-httpd_private-post-orders.c5
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c41
4 files changed, 78 insertions, 52 deletions
diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.c b/src/backend/taler-merchant-httpd_get-orders-ID.c
index 4167c873..8833329a 100644
--- a/src/backend/taler-merchant-httpd_get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_get-orders-ID.c
@@ -90,7 +90,8 @@ struct GetOrderData
/**
* fulfillment URL of the contract (valid as long as @e contract_terms is
- * valid).
+ * valid; but can also be NULL if the contract_terms does not come with
+ * a fulfillment URL).
*/
const char *fulfillment_url;
@@ -560,7 +561,7 @@ send_pay_request (struct GetOrderData *god,
{
ret = TALER_MHD_reply_json_pack (god->sc.con,
MHD_HTTP_PAYMENT_REQUIRED,
- "{s:s, s:s, s:s?}",
+ "{s:s, s:s?, s:s?}",
"taler_pay_uri",
taler_pay_uri,
"fulfillment_url",
@@ -887,26 +888,14 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
} /* end unclaimed order logic */
if (NULL == god->fulfillment_url)
- {
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_string ("fulfillment_url",
- &god->fulfillment_url),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (god->contract_terms,
- spec,
- NULL, NULL))
- {
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GET_ORDERS_DB_LOOKUP_ERROR,
- "Merchant database error (contract terms corrupted)");
- }
- }
-
+ god->fulfillment_url = json_string_value (json_object_get (
+ god->contract_terms,
+ "fulfillment_url"));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Token match: %d, contract match: %d, unclaimed: %d\n",
+ token_match,
+ contract_match,
+ god->unclaimed);
if ( (god->unclaimed) &&
(! token_match) )
{
@@ -917,9 +906,23 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
TALER_EC_MERCHANT_GET_ORDER_INVALID_TOKEN,
"Claim token invalid");
}
- if ( (! token_match) &&
+ if ( ( (! token_match) ||
+ (GNUNET_YES == GNUNET_is_zero (&god->claim_token)) ) &&
(! contract_match) )
{
+ if (NULL == god->fulfillment_url)
+ {
+ if (GNUNET_NO ==
+ GNUNET_is_zero (&god->h_contract_terms))
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_GET_ORDER_WRONG_CONTRACT,
+ "Contract hash does not match order");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_MERCHANT_GET_ORDER_INVALID_TOKEN,
+ "Claim token invalid");
+ }
if (god->generate_html)
{
/* Contract was claimed (maybe by another device), so this client
@@ -947,16 +950,12 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
MHD_destroy_response (reply);
return ret;
}
- else
- {
- /* Need to generate JSON reply */
- return TALER_MHD_reply_json_pack (
- connection,
- MHD_HTTP_ACCEPTED,
- "{s:s}",
- "fulfillment_url",
- god->fulfillment_url);
- }
+ /* Need to generate JSON reply */
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_ACCEPTED,
+ "{s:s}",
+ "fulfillment_url",
+ god->fulfillment_url);
}
if (god->unclaimed)
diff --git a/src/backend/taler-merchant-httpd_private-get-orders-ID.c b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
index bc2a2d03..e7c4a2b2 100644
--- a/src/backend/taler-merchant-httpd_private-get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
@@ -125,7 +125,8 @@ struct GetOrderRequestContext
/**
* Fulfillment URL extracted from the contract. For repurchase detection.
- * Only valid as long as @e contract_terms is valid!
+ * Only valid as long as @e contract_terms is valid! NULL if there is
+ * no fulfillment URL in the contract.
*/
const char *fulfillment_url;
@@ -862,8 +863,6 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler *rh,
/* extract the fulfillment URL and total amount from the contract terms! */
{
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_string ("fulfillment_url",
- &gorc->fulfillment_url),
TALER_JSON_spec_amount ("amount",
&gorc->contract_amount),
GNUNET_JSON_spec_end ()
@@ -893,6 +892,10 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler *rh,
"Merchant database error (contract terms in wrong currency)");
}
}
+ gorc->fulfillment_url
+ = json_string_value (json_object_get (gorc->contract_terms,
+ "fulfillment_url"));
+
if (! order_only)
{
if (GNUNET_OK !=
@@ -941,8 +944,9 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler *rh,
"DB error fetching payment status");
}
}
- if ((! paid) &&
- (NULL != gorc->session_id))
+ if ( (! paid) &&
+ (NULL != gorc->fulfillment_url) &&
+ (NULL != gorc->session_id) )
{
char *already_paid_order_id;
@@ -1057,13 +1061,11 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler *rh,
&claim_token);
ret = TALER_MHD_reply_json_pack (connection,
MHD_HTTP_OK,
- "{s:s, s:s, s:O, s:s}",
+ "{s:s, s:s, s:s}",
"taler_pay_uri",
taler_pay_uri,
"order_status_url",
order_status_url,
- "contract_terms",
- gorc->contract_terms,
"order_status",
"unpaid");
GNUNET_free (taler_pay_uri);
@@ -1097,7 +1099,6 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler *rh,
/* Generate final reply, including wire details if we have them */
{
MHD_RESULT ret;
-
char *order_status_url;
GNUNET_assert (GNUNET_OK ==
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c b/src/backend/taler-merchant-httpd_private-post-orders.c
index d23f33bc..45d766cf 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders.c
@@ -328,7 +328,6 @@ execute_order (struct MHD_Connection *connection,
struct TALER_Amount total;
const char *order_id;
const char *summary;
- const char *fulfillment_url;
json_t *products;
json_t *merchant;
struct GNUNET_TIME_Absolute timestamp;
@@ -342,8 +341,6 @@ execute_order (struct MHD_Connection *connection,
&order_id),
GNUNET_JSON_spec_string ("summary",
&summary),
- GNUNET_JSON_spec_string ("fulfillment_url",
- &fulfillment_url),
/**
* The following entries we don't actually need,
* except to check that the order is well-formed */
@@ -642,8 +639,6 @@ patch_order (struct MHD_Connection *connection,
fulfillment_url = json_string_value (json_object_get (order,
"fulfillment_url"));
if (NULL != fulfillment_url)
- /* The above condition should always be true; if not we do the error
- handling later in execute_order() and just skip the logic here. */
{
const char *pos;
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index 83a4cea2..37d1992f 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -1483,6 +1483,31 @@ postgres_lookup_contract_terms (void *cls,
/**
+ * Create a dummy URL for the 'fulfillment' URL that consist
+ * of random letters. Used because we do not like putting NULL
+ * into the database, but do need to ensure that a query
+ * never matches this URL.
+ *
+ * @return randomized URL starting with "void://", changes at
+ * ever call to this function
+ */
+static const char *
+make_dummy_url (void)
+{
+ static char buf[128] = "void://";
+ struct GNUNET_HashCode hc;
+
+ GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE,
+ &hc);
+ GNUNET_STRINGS_data_to_string (&hc,
+ sizeof (hc),
+ &buf[7],
+ sizeof (buf) - 8);
+ return buf;
+}
+
+
+/**
* Store contract terms given its @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
@@ -1519,8 +1544,6 @@ postgres_insert_contract_terms (void *cls,
{
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",
@@ -1539,6 +1562,11 @@ postgres_insert_contract_terms (void *cls,
}
}
+ fulfillment_url =
+ json_string_value (json_object_get (contract_terms,
+ "fulfillment_url"));
+ if (NULL == fulfillment_url)
+ fulfillment_url = make_dummy_url ();
check_connection (pg);
{
struct GNUNET_PQ_QueryParam params[] = {
@@ -1596,8 +1624,6 @@ postgres_update_contract_terms (void *cls,
{
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",
@@ -1616,6 +1642,12 @@ postgres_update_contract_terms (void *cls,
}
}
+ fulfillment_url =
+ json_string_value (json_object_get (contract_terms,
+ "fulfillment_url"));
+ if (NULL == fulfillment_url)
+ fulfillment_url = make_dummy_url ();
+
check_connection (pg);
{
struct GNUNET_PQ_QueryParam params[] = {
@@ -3232,7 +3264,6 @@ postgres_lookup_order_by_fulfillment (void *cls,
char **order_id)
{
struct PostgresClosure *pg = cls;
-
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_string (instance_id),
GNUNET_PQ_query_param_string (fulfillment_url),