summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/taler-merchant-httpd.c128
-rw-r--r--src/include/platform.h12
-rw-r--r--src/include/taler_merchant_testing_lib.h65
-rw-r--r--src/lib/merchant_api_delete_instance.c3
-rw-r--r--src/lib/merchant_api_delete_order.c5
-rw-r--r--src/lib/merchant_api_delete_product.c5
-rw-r--r--src/lib/merchant_api_delete_reserve.c5
-rw-r--r--src/lib/merchant_api_get_instance.c5
-rw-r--r--src/lib/merchant_api_get_orders.c5
-rw-r--r--src/lib/merchant_api_get_product.c5
-rw-r--r--src/lib/merchant_api_get_products.c5
-rw-r--r--src/lib/merchant_api_get_reserve.c5
-rw-r--r--src/lib/merchant_api_get_reserves.c5
-rw-r--r--src/lib/merchant_api_get_tips.c5
-rw-r--r--src/lib/merchant_api_get_transfers.c17
-rw-r--r--src/lib/merchant_api_lock_product.c5
-rw-r--r--src/lib/merchant_api_merchant_get_order.c11
-rw-r--r--src/lib/merchant_api_merchant_get_tip.c11
-rw-r--r--src/lib/merchant_api_patch_instance.c18
-rw-r--r--src/lib/merchant_api_patch_order_forget.c7
-rw-r--r--src/lib/merchant_api_patch_product.c5
-rw-r--r--src/lib/merchant_api_post_instances.c18
-rw-r--r--src/lib/merchant_api_post_order_pay.c7
-rw-r--r--src/lib/merchant_api_post_order_refund.c7
-rw-r--r--src/lib/merchant_api_post_orders.c5
-rw-r--r--src/lib/merchant_api_post_products.c5
-rw-r--r--src/lib/merchant_api_post_reserves.c5
-rw-r--r--src/lib/merchant_api_post_transfers.c5
-rw-r--r--src/lib/merchant_api_tip_authorize.c7
-rw-r--r--src/testing/test_merchant_api.c37
-rw-r--r--src/testing/testing_api_cmd_patch_instance.c5
-rw-r--r--src/testing/testing_api_cmd_post_instances.c10
32 files changed, 331 insertions, 112 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index 4290668d..f787385c 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -66,13 +66,6 @@
#include "taler-merchant-httpd_statics.h"
#include "taler-merchant-httpd_templating.h"
-/**
- * Required prefix for the authorization header as per RFC 8959.
- * (Follows RFC 6750 albeit technically violates RFC 7235, but
- * Mark Nottingham thinks this should be fixed by revising HTTP
- * spec (https://github.com/httpwg/http-core/issues/733))
- */
-#define RFC_8959_PREFIX "Bearer secret-token:"
/**
* Backlog for listen operation on unix-domain sockets.
@@ -193,6 +186,8 @@ TMH_check_auth (const char *token,
if (GNUNET_is_zero (hash))
return GNUNET_OK;
+ if (NULL == token)
+ return GNUNET_SYSERR;
GNUNET_assert (GNUNET_YES ==
GNUNET_CRYPTO_kdf (&val,
sizeof (val),
@@ -1520,57 +1515,6 @@ url_handler (void *cls,
}
}
- /* Access control for private handlers */
- if (use_private)
- {
- const char *auth;
-
- auth = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_AUTHORIZATION);
- if (NULL != auth)
- {
- if (0 != strncasecmp (auth,
- RFC_8959_PREFIX,
- strlen (RFC_8959_PREFIX)))
- {
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_UNAUTHORIZED,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "'" RFC_8959_PREFIX
- "' prefix missing in 'Authorization' header");
- }
- auth += strlen (RFC_8959_PREFIX);
- }
- if (NULL == hc->instance)
- {
- /* maybe before default instance is even created?
- Check against 'default_auth' */
- if ( (NULL != default_auth) &&
- (0 != strcmp (auth,
- default_auth)) )
- {
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_UNAUTHORIZED,
- TALER_EC_MERCHANT_GENERIC_UNAUTHORIZED,
- "Command-line authentication override is in effect");
- }
- }
- else
- {
- if (GNUNET_OK !=
- TMH_check_auth (auth,
- &hc->instance->settings.auth_salt,
- &hc->instance->settings.auth_hash))
- {
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_UNAUTHORIZED,
- TALER_EC_MERCHANT_GENERIC_UNAUTHORIZED,
- "Check 'Authentication' header");
- }
- }
- }
-
if (0 == strcmp (url,
""))
url = "/"; /* code below does not like empty string */
@@ -1680,6 +1624,74 @@ url_handler (void *cls,
}
/* At this point, we must have found a handler */
GNUNET_assert (NULL != hc->rh);
+
+ /* Access control for private handlers */
+ if (use_private)
+ {
+ const char *auth;
+ struct TMH_MerchantInstance *def_instance;
+ bool auth_ok;
+
+ /* PATCHing an instance can alternatively be checked against
+ the default instance */
+ def_instance = TMH_lookup_instance (NULL);
+ auth = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_AUTHORIZATION);
+ if (NULL != auth)
+ {
+ if (0 != strncasecmp (auth,
+ RFC_8959_PREFIX,
+ strlen (RFC_8959_PREFIX)))
+ {
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_UNAUTHORIZED,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "'" RFC_8959_PREFIX
+ "' prefix missing in 'Authorization' header");
+ }
+ auth += strlen (RFC_8959_PREFIX);
+ }
+
+ /* Are the credentials provided OK for the default instance?
+ Check against CLI override and default instance. */
+ auth_ok = ( (NULL == default_auth) ||
+ ( (NULL != auth) &&
+ (0 == strcmp (auth,
+ default_auth)) ) );
+ /* If we have no default instance, authentication is satisfied EVEN
+ if the 'default_auth' is NULL; otherwise, only if the default_auth
+ matched OR the auth_hash matched */
+ if ( (NULL != def_instance) &&
+ (NULL == default_auth) )
+ auth_ok = (GNUNET_OK ==
+ TMH_check_auth (auth,
+ &def_instance->settings.auth_salt,
+ &def_instance->settings.auth_hash));
+ /* Only permit 'default' auth if we are either working with
+ the default instance OR patching/deleting an instance OR have no instance */
+ if ( (hc->rh->handler != &TMH_private_patch_instances_ID) &&
+ (hc->rh->handler != &TMH_private_delete_instances_ID) &&
+ ( (NULL != hc->instance) ||
+ (def_instance != hc->instance) ) )
+ auth_ok = false;
+
+ /* Check against selected instance if we have one */
+ if (NULL != hc->instance)
+ auth_ok |= (GNUNET_OK ==
+ TMH_check_auth (auth,
+ &hc->instance->settings.auth_salt,
+ &hc->instance->settings.auth_hash));
+ if (! auth_ok)
+ {
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_UNAUTHORIZED,
+ TALER_EC_MERCHANT_GENERIC_UNAUTHORIZED,
+ "Check 'Authentication' header");
+ }
+ }
+
+
if ( (NULL == hc->instance) &&
(GNUNET_YES != hc->rh->skip_instance) )
return TALER_MHD_reply_with_error (connection,
diff --git a/src/include/platform.h b/src/include/platform.h
index b843c298..70c296fd 100644
--- a/src/include/platform.h
+++ b/src/include/platform.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014, 2015, 2016 GNUnet e.V. and INRIA
+ Copyright (C) 2014, 2015, 2016, 2021 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -55,6 +55,16 @@
to "ancient" MHD releases. */
#define MHD_NO_DEPRECATION 1
+
+/**
+ * Required prefix for the authorization header as per RFC 8959.
+ * (Follows RFC 6750 albeit technically violates RFC 7235, but
+ * Mark Nottingham thinks this should be fixed by revising HTTP
+ * spec (https://github.com/httpwg/http-core/issues/733))
+ */
+#define RFC_8959_PREFIX "Bearer secret-token:"
+
+
#endif /* PLATFORM_H_ */
/* end of platform.h */
diff --git a/src/include/taler_merchant_testing_lib.h b/src/include/taler_merchant_testing_lib.h
index c1f8d4dc..4eafd6fa 100644
--- a/src/include/taler_merchant_testing_lib.h
+++ b/src/include/taler_merchant_testing_lib.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- (C) 2018 Taler Systems SA
+ (C) 2018-2021 Taler Systems SA
TALER is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as
@@ -542,20 +542,19 @@ TALER_TESTING_cmd_merchant_post_orders_no_claim (const char *label,
* @return the command
*/
struct TALER_TESTING_Command
-TALER_TESTING_cmd_merchant_post_orders2 (const char *label,
- const char *merchant_url,
- unsigned int http_status,
- const char *order_id,
- struct GNUNET_TIME_Absolute
- refund_deadline,
- struct GNUNET_TIME_Absolute
- pay_deadline,
- bool claim_token,
- const char *amount,
- const char *payment_target,
- const char *products,
- const char *locks,
- const char *duplicate_of);
+TALER_TESTING_cmd_merchant_post_orders2 (
+ const char *label,
+ const char *merchant_url,
+ unsigned int http_status,
+ const char *order_id,
+ struct GNUNET_TIME_Absolute refund_deadline,
+ struct GNUNET_TIME_Absolute pay_deadline,
+ bool claim_token,
+ const char *amount,
+ const char *payment_target,
+ const char *products,
+ const char *locks,
+ const char *duplicate_of);
/**
@@ -1329,15 +1328,15 @@ TALER_TESTING_cmd_tip_authorize_with_ec (const char *label,
* @param ec expected Taler-defined error code.
*/
struct TALER_TESTING_Command
-TALER_TESTING_cmd_tip_authorize_from_reserve_with_ec (const char *label,
- const char *merchant_url,
- const char *exchange_url,
- const char *
- reserve_reference,
- unsigned int http_status,
- const char *justification,
- const char *amount,
- enum TALER_ErrorCode ec);
+TALER_TESTING_cmd_tip_authorize_from_reserve_with_ec (
+ const char *label,
+ const char *merchant_url,
+ const char *exchange_url,
+ const char *reserve_reference,
+ unsigned int http_status,
+ const char *justification,
+ const char *amount,
+ enum TALER_ErrorCode ec);
/**
@@ -1437,9 +1436,9 @@ TALER_TESTING_get_trait_merchant_sig (
* @return the trait
*/
struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_claim_nonce (unsigned int index,
- const struct
- GNUNET_CRYPTO_EddsaPublicKey *nonce);
+TALER_TESTING_make_trait_claim_nonce (
+ unsigned int index,
+ const struct GNUNET_CRYPTO_EddsaPublicKey *nonce);
/**
@@ -1449,14 +1448,13 @@ TALER_TESTING_make_trait_claim_nonce (unsigned int index,
* @param index which nonce to pick if @a
* cmd has multiple on offer
* @param[out] nonce set to the wanted data.
- *
* @return #GNUNET_OK on success
*/
int
-TALER_TESTING_get_trait_claim_nonce (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct
- GNUNET_CRYPTO_EddsaPublicKey **nonce);
+TALER_TESTING_get_trait_claim_nonce (
+ const struct TALER_TESTING_Command *cmd,
+ unsigned int index,
+ const struct GNUNET_CRYPTO_EddsaPublicKey **nonce);
/**
@@ -1542,6 +1540,7 @@ TALER_TESTING_get_trait_planchet_secrets (
unsigned int index,
struct TALER_PlanchetSecretsP **planchet_secrets);
+
/**
* Offer planchet secrets.
*
@@ -1554,6 +1553,7 @@ TALER_TESTING_make_trait_planchet_secrets (
unsigned int index,
const struct TALER_PlanchetSecretsP *planchet_secrets);
+
/**
* Offer tip id.
*
@@ -1566,6 +1566,7 @@ struct TALER_TESTING_Trait
TALER_TESTING_make_trait_tip_id (unsigned int index,
const struct GNUNET_HashCode *tip_id);
+
/**
* Obtain tip id from a @a cmd.
*
diff --git a/src/lib/merchant_api_delete_instance.c b/src/lib/merchant_api_delete_instance.c
index 87b88e0c..793b413c 100644
--- a/src/lib/merchant_api_delete_instance.c
+++ b/src/lib/merchant_api_delete_instance.c
@@ -91,9 +91,10 @@ handle_delete_instance_finished (void *cls,
{
case MHD_HTTP_NO_CONTENT:
break;
- case MHD_HTTP_NOT_FOUND:
+ case MHD_HTTP_UNAUTHORIZED:
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;
default:
/* unexpected response code */
diff --git a/src/lib/merchant_api_delete_order.c b/src/lib/merchant_api_delete_order.c
index 4651fcf7..c3771ba8 100644
--- a/src/lib/merchant_api_delete_order.c
+++ b/src/lib/merchant_api_delete_order.c
@@ -88,6 +88,11 @@ handle_delete_order_finished (void *cls,
{
case MHD_HTTP_NO_CONTENT:
break;
+ case MHD_HTTP_UNAUTHORIZED:
+ hr.ec = TALER_JSON_get_error_code (response);
+ hr.hint = TALER_JSON_get_error_hint (response);
+ /* Nothing really to verify, merchant says we need to authenticate. */
+ break;
case MHD_HTTP_NOT_FOUND:
break;
case MHD_HTTP_CONFLICT:
diff --git a/src/lib/merchant_api_delete_product.c b/src/lib/merchant_api_delete_product.c
index 196ec09d..ba2aaaf4 100644
--- a/src/lib/merchant_api_delete_product.c
+++ b/src/lib/merchant_api_delete_product.c
@@ -91,6 +91,11 @@ handle_delete_product_finished (void *cls,
{
case MHD_HTTP_NO_CONTENT:
break;
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_NOT_FOUND:
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
diff --git a/src/lib/merchant_api_delete_reserve.c b/src/lib/merchant_api_delete_reserve.c
index 9a8d3991..4eedea61 100644
--- a/src/lib/merchant_api_delete_reserve.c
+++ b/src/lib/merchant_api_delete_reserve.c
@@ -92,6 +92,11 @@ handle_delete_reserve_finished (void *cls,
{
case MHD_HTTP_NO_CONTENT:
break;
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_NOT_FOUND:
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
diff --git a/src/lib/merchant_api_get_instance.c b/src/lib/merchant_api_get_instance.c
index 512d1b7c..42d77da9 100644
--- a/src/lib/merchant_api_get_instance.c
+++ b/src/lib/merchant_api_get_instance.c
@@ -195,6 +195,11 @@ handle_get_instance_finished (void *cls,
GNUNET_JSON_parse_free (spec);
break;
}
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_NOT_FOUND:
/* instance does not exist */
hr.ec = TALER_JSON_get_error_code (json);
diff --git a/src/lib/merchant_api_get_orders.c b/src/lib/merchant_api_get_orders.c
index 420510bd..c7b04ab2 100644
--- a/src/lib/merchant_api_get_orders.c
+++ b/src/lib/merchant_api_get_orders.c
@@ -192,6 +192,11 @@ handle_get_orders_finished (void *cls,
GNUNET_JSON_parse_free (spec);
break;
}
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_NOT_FOUND:
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
diff --git a/src/lib/merchant_api_get_product.c b/src/lib/merchant_api_get_product.c
index c88e74f9..32e06123 100644
--- a/src/lib/merchant_api_get_product.c
+++ b/src/lib/merchant_api_get_product.c
@@ -173,6 +173,11 @@ handle_get_product_finished (void *cls,
GNUNET_JSON_parse_free (spec);
break;
}
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_NOT_FOUND:
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
diff --git a/src/lib/merchant_api_get_products.c b/src/lib/merchant_api_get_products.c
index d5d57252..26146ea4 100644
--- a/src/lib/merchant_api_get_products.c
+++ b/src/lib/merchant_api_get_products.c
@@ -180,6 +180,11 @@ handle_get_products_finished (void *cls,
GNUNET_JSON_parse_free (spec);
break;
}
+ case MHD_HTTP_UNAUTHORIZED:
+ 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;
default:
/* unexpected response code */
hr.ec = TALER_JSON_get_error_code (json);
diff --git a/src/lib/merchant_api_get_reserve.c b/src/lib/merchant_api_get_reserve.c
index 429cccff..710bcbc4 100644
--- a/src/lib/merchant_api_get_reserve.c
+++ b/src/lib/merchant_api_get_reserve.c
@@ -198,6 +198,11 @@ handle_reserve_get_finished (void *cls,
return;
}
}
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_INTERNAL_SERVER_ERROR:
/* Server had an internal issue; we should retry, but this API
leaves this to the application */
diff --git a/src/lib/merchant_api_get_reserves.c b/src/lib/merchant_api_get_reserves.c
index 52853065..32455a57 100644
--- a/src/lib/merchant_api_get_reserves.c
+++ b/src/lib/merchant_api_get_reserves.c
@@ -181,6 +181,11 @@ handle_reserves_get_finished (void *cls,
return;
}
}
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_INTERNAL_SERVER_ERROR:
/* Server had an internal issue; we should retry, but this API
leaves this to the application */
diff --git a/src/lib/merchant_api_get_tips.c b/src/lib/merchant_api_get_tips.c
index 16a87fff..fd3dfdae 100644
--- a/src/lib/merchant_api_get_tips.c
+++ b/src/lib/merchant_api_get_tips.c
@@ -184,6 +184,11 @@ handle_get_tips_finished (void *cls,
GNUNET_JSON_parse_free (spec);
break;
}
+ case MHD_HTTP_UNAUTHORIZED:
+ 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;
default:
/* unexpected response code */
hr.ec = TALER_JSON_get_error_code (json);
diff --git a/src/lib/merchant_api_get_transfers.c b/src/lib/merchant_api_get_transfers.c
index 0bfd9990..e31fb38f 100644
--- a/src/lib/merchant_api_get_transfers.c
+++ b/src/lib/merchant_api_get_transfers.c
@@ -143,14 +143,14 @@ handle_transfers_get_finished (void *cls,
GNUNET_JSON_spec_uint64 ("transfer_serial_id",
&td->credit_serial),
GNUNET_JSON_spec_mark_optional (
- TALER_JSON_spec_absolute_time ("execution_time",
- &td->execution_time)),
+ TALER_JSON_spec_absolute_time ("execution_time",
+ &td->execution_time)),
GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_bool ("verified",
- &td->verified)),
+ GNUNET_JSON_spec_bool ("verified",
+ &td->verified)),
GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_bool ("confirmed",
- &td->confirmed)),
+ GNUNET_JSON_spec_bool ("confirmed",
+ &td->confirmed)),
GNUNET_JSON_spec_end ()
};
@@ -184,6 +184,11 @@ handle_transfers_get_finished (void *cls,
return;
}
}
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_NOT_FOUND:
/* Nothing really to verify, this should never
happen, we should pass the JSON reply to the application */
diff --git a/src/lib/merchant_api_lock_product.c b/src/lib/merchant_api_lock_product.c
index 27f4f6e5..e9593fdb 100644
--- a/src/lib/merchant_api_lock_product.c
+++ b/src/lib/merchant_api_lock_product.c
@@ -102,6 +102,11 @@ handle_lock_product_finished (void *cls,
break;
case MHD_HTTP_NO_CONTENT:
break;
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_BAD_REQUEST:
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
diff --git a/src/lib/merchant_api_merchant_get_order.c b/src/lib/merchant_api_merchant_get_order.c
index 9504d16b..ac7da14f 100644
--- a/src/lib/merchant_api_merchant_get_order.c
+++ b/src/lib/merchant_api_merchant_get_order.c
@@ -375,6 +375,14 @@ handle_merchant_order_get_finished (void *cls,
omgh->job = NULL;
switch (response_code)
{
+ case MHD_HTTP_OK:
+ /* see below */
+ break;
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_NOT_FOUND:
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
@@ -383,9 +391,6 @@ handle_merchant_order_get_finished (void *cls,
NULL);
TALER_MERCHANT_merchant_order_get_cancel (omgh);
return;
- case MHD_HTTP_OK:
- /* see below */
- break;
default:
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
diff --git a/src/lib/merchant_api_merchant_get_tip.c b/src/lib/merchant_api_merchant_get_tip.c
index 4d4c66f7..aad72584 100644
--- a/src/lib/merchant_api_merchant_get_tip.c
+++ b/src/lib/merchant_api_merchant_get_tip.c
@@ -212,17 +212,22 @@ handle_merchant_tip_get_finished (void *cls,
GNUNET_JSON_parse_free (spec);
break;
}
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
+ case MHD_HTTP_UNAUTHORIZED:
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_NOT_FOUND:
/* legal, can happen if instance or tip reserve is unknown */
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
break;
+ case MHD_HTTP_INTERNAL_SERVER_ERROR:
+ /* Server had an internal issue; we should retry, but this API
+ leaves this to the application */
+ hr.ec = TALER_JSON_get_error_code (json);
+ hr.hint = TALER_JSON_get_error_hint (json);
+ break;
default:
/* unexpected response code */
GNUNET_break_op (0);
diff --git a/src/lib/merchant_api_patch_instance.c b/src/lib/merchant_api_patch_instance.c
index 721f8dd1..536fbdcf 100644
--- a/src/lib/merchant_api_patch_instance.c
+++ b/src/lib/merchant_api_patch_instance.c
@@ -110,6 +110,11 @@ handle_patch_instance_finished (void *cls,
* or the merchant is buggy (or API version conflict);
* just pass JSON reply to the application */
break;
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_FORBIDDEN:
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
@@ -172,6 +177,19 @@ TALER_MERCHANT_instance_patch (
json_t *jpayto_uris;
json_t *req_obj;
+ if (NULL != auth_token)
+ {
+ if (0 != strncasecmp (RFC_8959_PREFIX,
+ auth_token,
+ strlen (RFC_8959_PREFIX)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Authentication token must start with `%s'\n",
+ RFC_8959_PREFIX);
+ return NULL;
+ }
+ auth_token += strlen (RFC_8959_PREFIX);
+ }
jpayto_uris = json_array ();
if (NULL == jpayto_uris)
{
diff --git a/src/lib/merchant_api_patch_order_forget.c b/src/lib/merchant_api_patch_order_forget.c
index b00361fc..ddb26062 100644
--- a/src/lib/merchant_api_patch_order_forget.c
+++ b/src/lib/merchant_api_patch_order_forget.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2020 Taler Systems SA
+ Copyright (C) 2020, 2021 Taler Systems SA
TALER is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
@@ -106,6 +106,11 @@ handle_forget_finished (void *cls,
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
break;
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_NOT_FOUND:
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
diff --git a/src/lib/merchant_api_patch_product.c b/src/lib/merchant_api_patch_product.c
index e7d22520..f5630fc3 100644
--- a/src/lib/merchant_api_patch_product.c
+++ b/src/lib/merchant_api_patch_product.c
@@ -110,6 +110,11 @@ handle_patch_product_finished (void *cls,
* or the merchant is buggy (or API version conflict);
* just pass JSON reply to the application */
break;
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_FORBIDDEN:
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
diff --git a/src/lib/merchant_api_post_instances.c b/src/lib/merchant_api_post_instances.c
index a21b9b55..a6452045 100644
--- a/src/lib/merchant_api_post_instances.c
+++ b/src/lib/merchant_api_post_instances.c
@@ -109,6 +109,11 @@ handle_post_instances_finished (void *cls,
* or the merchant is buggy (or API version conflict);
* just pass JSON reply to the application */
break;
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_FORBIDDEN:
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
@@ -174,6 +179,19 @@ TALER_MERCHANT_instances_post (
json_t *jpayto_uris;
json_t *req_obj;
+ if (NULL != auth_token)
+ {
+ if (0 != strncasecmp (RFC_8959_PREFIX,
+ auth_token,
+ strlen (RFC_8959_PREFIX)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Authentication token must start with `%s'\n",
+ RFC_8959_PREFIX);
+ return NULL;
+ }
+ auth_token += strlen (RFC_8959_PREFIX);
+ }
jpayto_uris = json_array ();
if (NULL == jpayto_uris)
{
diff --git a/src/lib/merchant_api_post_order_pay.c b/src/lib/merchant_api_post_order_pay.c
index 28e9f6ed..d6b081bd 100644
--- a/src/lib/merchant_api_post_order_pay.c
+++ b/src/lib/merchant_api_post_order_pay.c
@@ -387,6 +387,13 @@ handle_pay_finished (void *cls,
/* Exchange couldn't respond properly; the retry is
left to the application */
break;
+ case MHD_HTTP_GATEWAY_TIMEOUT:
+ TALER_MERCHANT_parse_error_details_ (json,
+ response_code,
+ &hr);
+ /* Exchange couldn't respond in a timely fashion;
+ the retry is left to the application */
+ break;
default:
TALER_MERCHANT_parse_error_details_ (json,
response_code,
diff --git a/src/lib/merchant_api_post_order_refund.c b/src/lib/merchant_api_post_order_refund.c
index 748fb8c1..80ad70d4 100644
--- a/src/lib/merchant_api_post_order_refund.c
+++ b/src/lib/merchant_api_post_order_refund.c
@@ -131,8 +131,13 @@ handle_refund_finished (void *cls,
GNUNET_JSON_parse_free (spec);
}
break;
- case MHD_HTTP_CONFLICT:
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_NOT_FOUND:
+ case MHD_HTTP_CONFLICT:
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
orh->cb (orh->cb_cls,
diff --git a/src/lib/merchant_api_post_orders.c b/src/lib/merchant_api_post_orders.c
index 56de86d1..44c44c9b 100644
--- a/src/lib/merchant_api_post_orders.c
+++ b/src/lib/merchant_api_post_orders.c
@@ -133,6 +133,11 @@ handle_post_order_finished (void *cls,
the merchant is buggy (or API version conflict);
just pass JSON reply to the application */
break;
+ case MHD_HTTP_UNAUTHORIZED:
+ por.hr.ec = TALER_JSON_get_error_code (json);
+ por.hr.hint = TALER_JSON_get_error_hint (json);
+ /* Nothing really to verify, merchant says we need to authenticate. */
+ break;
case MHD_HTTP_FORBIDDEN:
/* Nothing really to verify, merchant says one
of the signatures is invalid; as we checked them,
diff --git a/src/lib/merchant_api_post_products.c b/src/lib/merchant_api_post_products.c
index ed1d3899..7ed9755c 100644
--- a/src/lib/merchant_api_post_products.c
+++ b/src/lib/merchant_api_post_products.c
@@ -109,6 +109,11 @@ handle_post_products_finished (void *cls,
* or the merchant is buggy (or API version conflict);
* just pass JSON reply to the application */
break;
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_FORBIDDEN:
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
diff --git a/src/lib/merchant_api_post_reserves.c b/src/lib/merchant_api_post_reserves.c
index 149ecaeb..8a8dee2d 100644
--- a/src/lib/merchant_api_post_reserves.c
+++ b/src/lib/merchant_api_post_reserves.c
@@ -130,6 +130,11 @@ handle_post_reserves_finished (void *cls,
}
case MHD_HTTP_ACCEPTED:
break;
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_NOT_FOUND:
/* Nothing really to verify, this should never
happen, we should pass the JSON reply to the application */
diff --git a/src/lib/merchant_api_post_transfers.c b/src/lib/merchant_api_post_transfers.c
index 14a44971..e78cb36d 100644
--- a/src/lib/merchant_api_post_transfers.c
+++ b/src/lib/merchant_api_post_transfers.c
@@ -190,6 +190,11 @@ handle_post_transfers_finished (void *cls,
}
case MHD_HTTP_ACCEPTED:
break;
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_NOT_FOUND:
/* Nothing really to verify, this should never
happen, we should pass the JSON reply to the application */
diff --git a/src/lib/merchant_api_tip_authorize.c b/src/lib/merchant_api_tip_authorize.c
index 64aad420..d45f61a9 100644
--- a/src/lib/merchant_api_tip_authorize.c
+++ b/src/lib/merchant_api_tip_authorize.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2017, 2020 Taler Systems SA
+ Copyright (C) 2014-2017, 2020, 2021 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
@@ -161,6 +161,11 @@ handle_tip_authorize_finished (void *cls,
hr.http_status = 0;
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
break;
+ case MHD_HTTP_UNAUTHORIZED:
+ 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_NOT_FOUND:
/* Well-defined status code, pass on to application! */
hr.ec = TALER_JSON_get_error_code (json);
diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c
index 9a69f121..b1932cd6 100644
--- a/src/testing/test_merchant_api.c
+++ b/src/testing/test_merchant_api.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2020 Taler Systems SA
+ Copyright (C) 2014-2021 Taler Systems SA
TALER is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as
@@ -1251,6 +1251,41 @@ run (void *cls,
PAYTO_I1,
"USD",
MHD_HTTP_CONFLICT),
+ TALER_TESTING_cmd_merchant_post_instances2 ("instance-create-ACL",
+ merchant_url,
+ "i-acl",
+ 0, NULL,
+ "controlled instance",
+ json_pack ("{s:s}", "city",
+ "shopcity"),
+ json_pack ("{s:s}", "city",
+ "lawyercity"),
+ "EUR:0.1",
+ 42,
+ "EUR:0.2",
+ GNUNET_TIME_UNIT_MINUTES,
+ GNUNET_TIME_UNIT_MINUTES,
+ RFC_8959_PREFIX "EXAMPLE",
+ MHD_HTTP_NO_CONTENT),
+ TALER_TESTING_cmd_merchant_patch_instance ("instance-patch-ACL",
+ merchant_url,
+ "i-acl",
+ 1,
+ payto_uris,
+ "controlled instance",
+ json_pack ("{s:s}",
+ "street",
+ "bobstreet"),
+ json_pack ("{s:s}",
+ "street",
+ "bobjuryst"),
+ "EUR:0.1",
+ 4,
+ "EUR:0.5",
+ GNUNET_TIME_UNIT_MINUTES,
+ GNUNET_TIME_UNIT_MINUTES,
+ RFC_8959_PREFIX "SANDBOX",
+ MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_post_instances ("instance-create-i2",
merchant_url,
"i2",
diff --git a/src/testing/testing_api_cmd_patch_instance.c b/src/testing/testing_api_cmd_patch_instance.c
index 2248c1ac..2cbd0e5b 100644
--- a/src/testing/testing_api_cmd_patch_instance.c
+++ b/src/testing/testing_api_cmd_patch_instance.c
@@ -142,12 +142,13 @@ patch_instance_cb (void *cls,
}
switch (hr->http_status)
{
- case MHD_HTTP_OK:
+ case MHD_HTTP_NO_CONTENT:
break;
// FIXME: add other legitimate states here...
default:
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Unhandled HTTP status.\n");
+ "Unhandled HTTP status %u.\n",
+ hr->http_status);
}
TALER_TESTING_interpreter_next (pis->is);
}
diff --git a/src/testing/testing_api_cmd_post_instances.c b/src/testing/testing_api_cmd_post_instances.c
index acd623b6..7eb2e7fa 100644
--- a/src/testing/testing_api_cmd_post_instances.c
+++ b/src/testing/testing_api_cmd_post_instances.c
@@ -150,7 +150,8 @@ post_instances_cb (void *cls,
default:
GNUNET_break (0);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Unhandled HTTP status.\n");
+ "Unhandled HTTP status %u.\n",
+ hr->http_status);
}
TALER_TESTING_interpreter_next (pis->is);
}
@@ -188,7 +189,12 @@ post_instances_run (void *cls,
pis->auth_token,
&post_instances_cb,
pis);
- GNUNET_assert (NULL != pis->iph);
+ if (NULL == pis->iph)
+ {
+ GNUNET_break (0);
+ TALER_TESTING_interpreter_fail (pis->is);
+ return;
+ }
}