diff --git a/include/maxscale/config.h b/include/maxscale/config.h index 3b3f27125..d1d664121 100644 --- a/include/maxscale/config.h +++ b/include/maxscale/config.h @@ -37,6 +37,7 @@ MXS_BEGIN_DECLS #define MAX_ADMIN_HOST_LEN 1024 /** JSON Pointers to key parts of JSON objects */ +#define MXS_JSON_PTR_DATA "/data" #define MXS_JSON_PTR_ID "/data/id" #define MXS_JSON_PTR_PARAMETERS "/data/attributes/parameters" diff --git a/server/core/config_runtime.cc b/server/core/config_runtime.cc index 97756d072..0bc4c0238 100644 --- a/server/core/config_runtime.cc +++ b/server/core/config_runtime.cc @@ -843,6 +843,12 @@ static inline const char* string_or_null(json_t* json, const char* path) return rval; } +/** Check that the body at least defies a data member */ +static bool is_valid_resource_body(json_t* json) +{ + return mxs_json_pointer(json, MXS_JSON_PTR_DATA); +} + static bool server_contains_required_fields(json_t* json) { json_t* id = mxs_json_pointer(json, MXS_JSON_PTR_ID); @@ -911,7 +917,8 @@ SERVER* runtime_create_server_from_json(json_t* json) { SERVER* rval = NULL; - if (server_contains_required_fields(json)) + if (is_valid_resource_body(json) && + server_contains_required_fields(json)) { const char* name = json_string_value(mxs_json_pointer(json, MXS_JSON_PTR_ID)); const char* address = json_string_value(mxs_json_pointer(json, MXS_JSON_PTR_PARAM_ADDRESS)); @@ -987,7 +994,8 @@ bool runtime_alter_server_from_json(SERVER* server, json_t* new_json) Closer old_json(server_to_json(server, "")); ss_dassert(old_json.get()); - if (server_to_object_relations(server, old_json.get(), new_json)) + if (is_valid_resource_body(new_json) && + server_to_object_relations(server, old_json.get(), new_json)) { rval = true; json_t* parameters = mxs_json_pointer(new_json, MXS_JSON_PTR_PARAMETERS); @@ -1043,7 +1051,8 @@ static bool validate_monitor_json(json_t* json) bool rval = false; json_t* value; - if ((value = mxs_json_pointer(json, MXS_JSON_PTR_ID)) && json_is_string(value) && + if (is_valid_resource_body(json) && + (value = mxs_json_pointer(json, MXS_JSON_PTR_ID)) && json_is_string(value) && (value = mxs_json_pointer(json, MXS_JSON_PTR_MODULE)) && json_is_string(value)) { set relations; @@ -1158,7 +1167,8 @@ bool runtime_alter_monitor_from_json(MXS_MONITOR* monitor, json_t* new_json) Closer old_json(monitor_to_json(monitor, "")); ss_dassert(old_json.get()); - if (object_to_server_relations(monitor->name, old_json.get(), new_json)) + if (is_valid_resource_body(new_json) && + object_to_server_relations(monitor->name, old_json.get(), new_json)) { rval = true; bool changed = false; @@ -1223,7 +1233,8 @@ bool runtime_alter_service_from_json(SERVICE* service, json_t* new_json) Closer old_json(service_to_json(service, "")); ss_dassert(old_json.get()); - if (object_to_server_relations(service->name, old_json.get(), new_json)) + if (is_valid_resource_body(new_json) && + object_to_server_relations(service->name, old_json.get(), new_json)) { bool changed = false; json_t* parameters = mxs_json_pointer(new_json, MXS_JSON_PTR_PARAMETERS); diff --git a/server/core/test/rest-api/test/errors.js b/server/core/test/rest-api/test/errors.js new file mode 100644 index 000000000..c8885a81e --- /dev/null +++ b/server/core/test/rest-api/test/errors.js @@ -0,0 +1,21 @@ +require("../utils.js")() + + +describe("Errors", function() +{ + before(startMaxScale) + + it("error on invalid PUT request", function() + { + return request.put(base_url + "/servers/server1", { json: {this_is: "a test"}}) + .should.be.rejected + }) + + it("error on invalid POST request", function() + { + return request.post(base_url + "/servers", { json: {this_is: "a test"}}) + .should.be.rejected + }) + + after(stopMaxScale) +});