diff options
author | Christian Grothoff <christian@grothoff.org> | 2020-08-24 14:12:02 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2020-08-24 14:12:02 +0200 |
commit | f23e2c2cdc8d2665d76a335f58a640763c9a425e (patch) | |
tree | d15041acbad399cd3768c97ed4ee5a82d0a0c63c | |
parent | 8d73d07d559732dbd010b802ea4ed3602964c0cd (diff) | |
download | merchant-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.c | 65 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_private-get-orders-ID.c | 19 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_private-post-orders.c | 5 | ||||
-rw-r--r-- | src/backenddb/plugin_merchantdb_postgres.c | 41 |
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), |