From 2df2918814ba4d8ec269df837b6169de53357b47 Mon Sep 17 00:00:00 2001 From: Dmitry Tantsur Date: Mon, 14 Dec 2015 13:01:56 +0100 Subject: [PATCH] Validate that data received from the ramdisk is a JSON object Change-Id: I16210ece532f7901c20074cd205b44fdb2f4084d Closes-Bug: #1525876 --- ironic_inspector/main.py | 5 ++++- ironic_inspector/test/test_main.py | 18 ++++++++++++------ ...ssing-data-type-check-7c914339d3ab15ba.yaml | 5 +++++ 3 files changed, 21 insertions(+), 7 deletions(-) create mode 100644 releasenotes/notes/processing-data-type-check-7c914339d3ab15ba.yaml diff --git a/ironic_inspector/main.py b/ironic_inspector/main.py index 05fd9a886..51d5cd2d8 100644 --- a/ironic_inspector/main.py +++ b/ironic_inspector/main.py @@ -165,8 +165,11 @@ def version_root(version): @convert_exceptions def api_continue(): data = flask.request.get_json(force=True) - LOG.debug("/v1/continue got JSON %s", data) + if not isinstance(data, dict): + raise utils.Error(_('Invalid data: expected a JSON object, got %s') % + data.__class__.__name__) + LOG.debug("/v1/continue got JSON %s", data) return flask.jsonify(process.process(data)) diff --git a/ironic_inspector/test/test_main.py b/ironic_inspector/test/test_main.py index 3cc870a39..9b9c924b0 100644 --- a/ironic_inspector/test/test_main.py +++ b/ironic_inspector/test/test_main.py @@ -109,25 +109,31 @@ class TestApiIntrospect(BaseAPITest): self.assertEqual(400, res.status_code) +@mock.patch.object(process, 'process', autospec=True) class TestApiContinue(BaseAPITest): - @mock.patch.object(process, 'process', autospec=True) def test_continue(self, process_mock): # should be ignored CONF.set_override('auth_strategy', 'keystone') process_mock.return_value = {'result': 42} - res = self.app.post('/v1/continue', data='"JSON"') + res = self.app.post('/v1/continue', data='{"foo": "bar"}') self.assertEqual(200, res.status_code) - process_mock.assert_called_once_with("JSON") + process_mock.assert_called_once_with({"foo": "bar"}) self.assertEqual({"result": 42}, json.loads(res.data.decode())) - @mock.patch.object(process, 'process', autospec=True) def test_continue_failed(self, process_mock): process_mock.side_effect = iter([utils.Error("boom")]) - res = self.app.post('/v1/continue', data='"JSON"') + res = self.app.post('/v1/continue', data='{"foo": "bar"}') self.assertEqual(400, res.status_code) - process_mock.assert_called_once_with("JSON") + process_mock.assert_called_once_with({"foo": "bar"}) self.assertEqual('boom', _get_error(res)) + def test_continue_wrong_type(self, process_mock): + res = self.app.post('/v1/continue', data='42') + self.assertEqual(400, res.status_code) + self.assertEqual('Invalid data: expected a JSON object, got int', + _get_error(res)) + self.assertFalse(process_mock.called) + class TestApiGetStatus(BaseAPITest): @mock.patch.object(node_cache, 'get_node', autospec=True) diff --git a/releasenotes/notes/processing-data-type-check-7c914339d3ab15ba.yaml b/releasenotes/notes/processing-data-type-check-7c914339d3ab15ba.yaml new file mode 100644 index 000000000..d65800011 --- /dev/null +++ b/releasenotes/notes/processing-data-type-check-7c914339d3ab15ba.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - The data processing API endpoint now validates that data received from + the ramdisk is actually a JSON object instead of failing the internal error + later (issue https://bugs.launchpad.net/bugs/1525876).