From 08d795551739e047805fd2f89d6c16ca743289d1 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 17 Apr 2021 21:46:53 +0200 Subject: add tests and bugfixes to fix #6778 and #6779 --- src/backend/taler-merchant-httpd.c | 9 +- ...merchant-httpd_private-post-instances-ID-auth.c | 15 +-- src/lib/merchant_api_delete_instance.c | 4 +- src/lib/merchant_api_patch_instance.c | 4 +- src/lib/merchant_api_post_instance_auth.c | 19 ++-- src/testing/test_merchant_api.c | 101 +++++++++++++++++++++ src/testing/testing_api_cmd_delete_instance.c | 7 +- src/testing/testing_api_cmd_get_product.c | 12 ++- src/testing/testing_api_cmd_get_products.c | 9 +- 9 files changed, 155 insertions(+), 25 deletions(-) diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index 58278856..1ee4c1b3 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -1137,6 +1137,7 @@ url_handler (void *cls, { .url_prefix = "/instances/", .method = MHD_HTTP_METHOD_GET, + .skip_instance = true, .default_only = true, .have_id_segment = true, .handler = &TMH_private_get_instances_default_ID @@ -1145,6 +1146,7 @@ url_handler (void *cls, { .url_prefix = "/instances/", .method = MHD_HTTP_METHOD_DELETE, + .skip_instance = true, .default_only = true, .have_id_segment = true, .handler = &TMH_private_delete_instances_default_ID @@ -1153,6 +1155,7 @@ url_handler (void *cls, { .url_prefix = "/instances/", .method = MHD_HTTP_METHOD_PATCH, + .skip_instance = true, .default_only = true, .have_id_segment = true, .handler = &TMH_private_patch_instances_default_ID, @@ -1167,6 +1170,7 @@ url_handler (void *cls, .url_prefix = "/instances/", .url_suffix = "auth", .method = MHD_HTTP_METHOD_POST, + .skip_instance = true, .default_only = true, .have_id_segment = true, .handler = &TMH_private_post_instances_default_ID_auth, @@ -1872,9 +1876,10 @@ url_handler (void *cls, auth_malformed = true; } - /* If we have not even a default instance AND no override + /* If we have no selected instance, no default instance AND no override credentials, THEN we accept anything (no access control) */ - auth_ok = ( (NULL == TMH_lookup_instance (NULL)) && + auth_ok = ( (NULL == hc->instance) && + (NULL == TMH_lookup_instance (NULL)) && (NULL == TMH_default_auth) ); /* Check against selected instance, if we have one */ if (NULL != hc->instance) diff --git a/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c b/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c index a6e1326c..93b0f784 100644 --- a/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c +++ b/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c @@ -57,22 +57,25 @@ post_instances_ID_auth (struct TMH_MerchantInstance *mi, "method")); if (NULL == auth_method) + { GNUNET_break_op (0); - else if (0 == strcmp (auth_method, "external")) + } + else if (0 == strcmp (auth_method, + "external")) { auth_token = NULL; auth_ok = true; } - else if (0 == strcmp (auth_method, "token")) + else if (0 == strcmp (auth_method, + "token")) { - auth_token = json_string_value (json_object_get (jauth, "token")); + auth_token = json_string_value (json_object_get (jauth, + "token")); if (NULL != auth_token) { - if (0 != strncasecmp (RFC_8959_PREFIX, + if (0 == strncasecmp (RFC_8959_PREFIX, auth_token, strlen (RFC_8959_PREFIX))) - GNUNET_break_op (0); - else auth_ok = true; } else diff --git a/src/lib/merchant_api_delete_instance.c b/src/lib/merchant_api_delete_instance.c index 4ef40952..d83ea467 100644 --- a/src/lib/merchant_api_delete_instance.c +++ b/src/lib/merchant_api_delete_instance.c @@ -145,7 +145,7 @@ instance_delete (struct GNUNET_CURL_Context *ctx, char *path; GNUNET_asprintf (&path, - "instances/%s/private", + "private/instances/%s", instance_id); idh->url = TALER_url_join (backend_url, path, @@ -158,7 +158,7 @@ instance_delete (struct GNUNET_CURL_Context *ctx, { /* backend_url is already identifying the instance */ idh->url = TALER_url_join (backend_url, - "/private", + "private", "purge", (purge) ? "yes" : NULL, NULL); diff --git a/src/lib/merchant_api_patch_instance.c b/src/lib/merchant_api_patch_instance.c index f51bb953..871dbbba 100644 --- a/src/lib/merchant_api_patch_instance.c +++ b/src/lib/merchant_api_patch_instance.c @@ -228,7 +228,7 @@ TALER_MERCHANT_instance_patch ( char *path; GNUNET_asprintf (&path, - "instances/%s/private", + "private/instances/%s", instance_id); iph->url = TALER_url_join (backend_url, path, @@ -239,7 +239,7 @@ TALER_MERCHANT_instance_patch ( { /* backend_url is already identifying the instance */ iph->url = TALER_url_join (backend_url, - "/private", + "private", NULL); } if (NULL == iph->url) diff --git a/src/lib/merchant_api_post_instance_auth.c b/src/lib/merchant_api_post_instance_auth.c index d16bd2cd..a659ffb5 100644 --- a/src/lib/merchant_api_post_instance_auth.c +++ b/src/lib/merchant_api_post_instance_auth.c @@ -97,6 +97,12 @@ handle_post_instance_auth_finished (void *cls, { case MHD_HTTP_NO_CONTENT: break; + case MHD_HTTP_BAD_REQUEST: + /* happens if the auth token is malformed */ + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_UNAUTHORIZED: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); @@ -139,7 +145,7 @@ TALER_MERCHANT_instance_auth_post ( char *path; GNUNET_asprintf (&path, - "instances/%s/private/auth", + "private/instances/%s/auth", instance_id); iaph->url = TALER_url_join (backend_url, path, @@ -150,7 +156,7 @@ TALER_MERCHANT_instance_auth_post ( { /* backend_url is already identifying the instance */ iaph->url = TALER_url_join (backend_url, - "/private/auth", + "private/auth", NULL); } if (NULL == iaph->url) @@ -208,10 +214,11 @@ TALER_MERCHANT_instance_auth_post ( curl_easy_setopt (eh, CURLOPT_CUSTOMREQUEST, MHD_HTTP_METHOD_POST)); - iaph->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_post_instance_auth_finished, - iaph); + iaph->job = GNUNET_CURL_job_add2 (ctx, + eh, + iaph->post_ctx.headers, + &handle_post_instance_auth_finished, + iaph); } return iaph; } diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c index 6d9314b6..052b0c1d 100644 --- a/src/testing/test_merchant_api.c +++ b/src/testing/test_merchant_api.c @@ -83,6 +83,11 @@ static struct TALER_TESTING_ExchangeConfiguration ec; */ static char *merchant_url; +/** + * Merchant instance "i1a" base URL. + */ +static char *merchant_url_i1a; + /** * Merchant process. */ @@ -842,6 +847,97 @@ run (void *cls, TALER_TESTING_cmd_end () }; + struct TALER_TESTING_Command auth[] = { + TALER_TESTING_cmd_merchant_post_instances ("instance-create-i1a", + merchant_url, + "i1a", + PAYTO_I1, + "EUR", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-1", + merchant_url_i1a, + "nx-product", + MHD_HTTP_NOT_FOUND, + NULL), + TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-1", + merchant_url_i1a, + MHD_HTTP_OK, + NULL), + TALER_TESTING_cmd_merchant_post_instance_auth ( + "instance-create-i1a-auth-fail", + merchant_url, + "i1a", + "my-secret", + MHD_HTTP_BAD_REQUEST), + TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-2", + merchant_url_i1a, + "nx-product", + MHD_HTTP_NOT_FOUND, + NULL), + TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-2", + merchant_url_i1a, + MHD_HTTP_OK, + NULL), + TALER_TESTING_cmd_merchant_post_instance_auth ( + "instance-create-i1a-auth-ok", + merchant_url, + "i1a", + RFC_8959_PREFIX "my-secret", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-3", + merchant_url_i1a, + "nx-product", + MHD_HTTP_UNAUTHORIZED, + NULL), + TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-3", + merchant_url_i1a, + MHD_HTTP_UNAUTHORIZED, + NULL), + TALER_TESTING_cmd_set_authorization ("set-auth-valid", + "Bearer " RFC_8959_PREFIX "my-secret"), + TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-4", + merchant_url_i1a, + "nx-product", + MHD_HTTP_NOT_FOUND, + NULL), + TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-4", + merchant_url_i1a, + MHD_HTTP_OK, + NULL), + TALER_TESTING_cmd_merchant_post_instance_auth ( + "instance-create-i1a-change-auth", + merchant_url_i1a, + NULL, + RFC_8959_PREFIX "my-other-secret", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-5", + merchant_url_i1a, + "nx-product", + MHD_HTTP_UNAUTHORIZED, + NULL), + TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-5", + merchant_url_i1a, + MHD_HTTP_UNAUTHORIZED, + NULL), + TALER_TESTING_cmd_merchant_purge_instance ("instance-delete-i1a-fail", + merchant_url_i1a, + NULL, + MHD_HTTP_UNAUTHORIZED), + TALER_TESTING_cmd_set_authorization ("set-auth-none", + NULL), + TALER_TESTING_cmd_merchant_post_instance_auth ( + "instance-create-i1a-clear-auth", + merchant_url, + "i1a", + NULL, + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_purge_instance ("instance-delete-i1a", + merchant_url, + "i1a", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_end () + }; + struct TALER_TESTING_Command tip[] = { TALER_TESTING_cmd_merchant_post_reserves ("create-reserve-tip-1", merchant_url, @@ -1454,6 +1550,8 @@ run (void *cls, refund), TALER_TESTING_cmd_batch ("tip", tip), + TALER_TESTING_cmd_batch ("auth", + auth), /** * End the suite. */ @@ -1491,6 +1589,9 @@ main (int argc, (merchant_url = TALER_TESTING_prepare_merchant (CONFIG_FILE))) return 77; + GNUNET_asprintf (&merchant_url_i1a, + "%sinstances/i1a/", + merchant_url); TALER_TESTING_cleanup_files (CONFIG_FILE); switch (TALER_TESTING_prepare_exchange (CONFIG_FILE, diff --git a/src/testing/testing_api_cmd_delete_instance.c b/src/testing/testing_api_cmd_delete_instance.c index 9bb3efb7..ca2acb76 100644 --- a/src/testing/testing_api_cmd_delete_instance.c +++ b/src/testing/testing_api_cmd_delete_instance.c @@ -92,7 +92,11 @@ delete_instance_cb (void *cls, } switch (hr->http_status) { - case MHD_HTTP_OK: + case MHD_HTTP_NO_CONTENT: + break; + case MHD_HTTP_UNAUTHORIZED: + break; + case MHD_HTTP_NOT_FOUND: break; default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -105,7 +109,6 @@ delete_instance_cb (void *cls, /** * Run the "DELETE instance" CMD. * - * * @param cls closure. * @param cmd command being run now. * @param is interpreter state. diff --git a/src/testing/testing_api_cmd_get_product.c b/src/testing/testing_api_cmd_get_product.c index 88050a42..d1f844b0 100644 --- a/src/testing/testing_api_cmd_get_product.c +++ b/src/testing/testing_api_cmd_get_product.c @@ -109,10 +109,6 @@ get_product_cb (void *cls, struct GetProductState *gis = cls; const struct TALER_TESTING_Command *product_cmd; - product_cmd = TALER_TESTING_interpreter_lookup_command ( - gis->is, - gis->product_reference); - gis->igh = NULL; if (gis->http_status != hr->http_status) { @@ -129,6 +125,10 @@ get_product_cb (void *cls, case MHD_HTTP_OK: { const char *expected_description; + + product_cmd = TALER_TESTING_interpreter_lookup_command ( + gis->is, + gis->product_reference); if (GNUNET_OK != TALER_TESTING_get_trait_string (product_cmd, 0, @@ -276,6 +276,10 @@ get_product_cb (void *cls, } } break; + case MHD_HTTP_UNAUTHORIZED: + break; + case MHD_HTTP_NOT_FOUND: + break; default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unhandled HTTP status.\n"); diff --git a/src/testing/testing_api_cmd_get_products.c b/src/testing/testing_api_cmd_get_products.c index 2df168ee..534ffea5 100644 --- a/src/testing/testing_api_cmd_get_products.c +++ b/src/testing/testing_api_cmd_get_products.c @@ -135,9 +135,16 @@ get_products_cb (void *cls, } } break; + case MHD_HTTP_UNAUTHORIZED: + break; + case MHD_HTTP_NOT_FOUND: + /* instance does not exist */ + break; default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unhandled HTTP status.\n"); + "Unhandled HTTP status %u (%d).\n", + hr->http_status, + hr->ec); } TALER_TESTING_interpreter_next (gis->is); } -- cgit v1.2.3