Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for issue 4998 - Web Hook Rules check http headers in case sensitive manner #5038

Merged
merged 11 commits into from
Jan 28, 2022
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ Added

Contributed by @khushboobhatia01

* Added `trigger.headers_lower` to webhook trigger payload. This allows rules to match webhook triggers
without dealing with the case-sensitive nature of `trigger.headers`, as `triggers.headers_lower` providers
the same headers, but with the header name lower cased. #5038

Contributed by @Rand01ph

Fixed
~~~~~

Expand Down
1 change: 1 addition & 0 deletions st2api/st2api/controllers/v1/webhooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ def post(self, hook, webhook_body_api, headers, requester_user):
payload = {}

payload["headers"] = headers
payload["headers_lower"] = {k.lower(): v for k, v in headers.items()}
payload["body"] = body

# Dispatch trigger instance for each of the trigger found
Expand Down
27 changes: 27 additions & 0 deletions st2api/tests/unit/controllers/v1/test_webhooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,33 @@ def test_authentication_headers_should_be_removed(self, dispatch_mock):
)
self.assertNotIn("Cookie", dispatch_mock.call_args[1]["payload"]["headers"])

@mock.patch.object(
TriggerInstancePublisher, "publish_trigger", mock.MagicMock(return_value=True)
)
@mock.patch.object(
WebhooksController, "_is_valid_hook", mock.MagicMock(return_value=True)
)
@mock.patch.object(
HooksHolder,
"get_triggers_for_hook",
mock.MagicMock(return_value=[DUMMY_TRIGGER_DICT]),
)
@mock.patch("st2common.transport.reactor.TriggerDispatcher.dispatch")
def test_st2_webhook_lower_header(self, dispatch_mock):
data = WEBHOOK_1
post_resp = self.__do_post(
"git", data, headers={"X-Github-Token": "customvalue"}
)
self.assertEqual(post_resp.status_int, http_client.ACCEPTED)
self.assertEqual(
dispatch_mock.call_args[1]["payload"]["headers"]["X-Github-Token"],
"customvalue",
)
self.assertEqual(
dispatch_mock.call_args[1]["payload"]["headers_lower"]["x-github-token"],
"customvalue",
)

def __do_post(self, hook, webhook, expect_errors=False, headers=None):
return self.app.post_json(
"/v1/webhooks/" + hook,
Expand Down