diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1640606364..72e1cf5b24 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,6 +7,11 @@ in development Fixed ~~~~~ + +* Fix deserialization bug in st2 API for url encoded payloads. #5536 + + Contributed by @sravs-dev + * Fix issue of WinRM parameter passing fails for larger scripts.#5538 Contributed by @ashwini-orchestral diff --git a/st2api/tests/unit/controllers/v1/test_webhooks.py b/st2api/tests/unit/controllers/v1/test_webhooks.py index f6e17fe39f..3e2e6085ae 100644 --- a/st2api/tests/unit/controllers/v1/test_webhooks.py +++ b/st2api/tests/unit/controllers/v1/test_webhooks.py @@ -262,11 +262,6 @@ def test_json_request_body(self, dispatch_mock): ) @mock.patch("st2common.transport.reactor.TriggerDispatcher.dispatch") def test_form_encoded_request_body(self, dispatch_mock): - return - # TODO: Fix on deserialization on API side, body dict values being decoded as bytes - # instead of unicode which breakgs things. Likely issue / bug with form urlencoding - # parsing or perhaps in the test client when sending data - # Send request body as form urlencoded data data = {"form": ["test"]} headers = { @@ -274,10 +269,11 @@ def test_form_encoded_request_body(self, dispatch_mock): "St2-Trace-Tag": "tag1", } - self.app.post("/v1/webhooks/git", data, headers=headers) + post_resp = self.app.post("/v1/webhooks/git", data, headers=headers) + self.assertEqual(post_resp.status_int, http_client.ACCEPTED) self.assertEqual( dispatch_mock.call_args[1]["payload"]["headers"]["Content-Type"], - "application/x-www-form-urlencoded", + "application/x-www-form-urlencoded; charset=UTF-8", ) self.assertEqual(dispatch_mock.call_args[1]["payload"]["body"], data) self.assertEqual(dispatch_mock.call_args[1]["trace_context"].trace_tag, "tag1") diff --git a/st2auth/tests/unit/controllers/v1/test_sso.py b/st2auth/tests/unit/controllers/v1/test_sso.py index 2b6edb1f83..5596b0fb01 100644 --- a/st2auth/tests/unit/controllers/v1/test_sso.py +++ b/st2auth/tests/unit/controllers/v1/test_sso.py @@ -137,6 +137,17 @@ def test_idp_callback(self): self.assertIn("token", st2_auth_token) self.assertEqual(st2_auth_token["user"], MOCK_USER) + @mock.patch.object( + sso_api_controller.SSO_BACKEND, + "verify_response", + mock.MagicMock(return_value={"referer": MOCK_REFERER, "username": MOCK_USER}), + ) + def test_callback_url_encoded_payload(self): + data = {"foo": ["bar"]} + headers = {"Content-Type": "application/x-www-form-urlencoded"} + response = self.app.post(SSO_CALLBACK_V1_PATH, data, headers=headers) + self.assertTrue(response.status_code, http_client.OK) + @mock.patch.object( sso_api_controller.SSO_BACKEND, "verify_response", diff --git a/st2common/st2common/router.py b/st2common/st2common/router.py index 36a9476ed6..acbb6cc5f0 100644 --- a/st2common/st2common/router.py +++ b/st2common/st2common/router.py @@ -494,7 +494,7 @@ def __call__(self, req): "application/x-www-form-urlencoded", "multipart/form-data", ]: - data = urlparse.parse_qs(req.body) + data = urlparse.parse_qs(six.ensure_str(req.body)) else: raise ValueError( 'Unsupported Content-Type: "%s"' % (content_type)