diff --git a/slack_bolt/middleware/ssl_check/async_ssl_check.py b/slack_bolt/middleware/ssl_check/async_ssl_check.py index 5b806a4bc..62712aa67 100644 --- a/slack_bolt/middleware/ssl_check/async_ssl_check.py +++ b/slack_bolt/middleware/ssl_check/async_ssl_check.py @@ -18,7 +18,7 @@ async def async_process( next: Callable[[], Awaitable[BoltResponse]], ) -> BoltResponse: if self._is_ssl_check_request(req.body): - if self._verify_token_if_needed(req.body): + if not self._verify_token_if_needed(req.body): return self._build_error_response() return self._build_success_response() else: diff --git a/slack_bolt/middleware/ssl_check/ssl_check.py b/slack_bolt/middleware/ssl_check/ssl_check.py index 5e5d9ad9c..d7f6a759d 100644 --- a/slack_bolt/middleware/ssl_check/ssl_check.py +++ b/slack_bolt/middleware/ssl_check/ssl_check.py @@ -39,7 +39,7 @@ def process( next: Callable[[], BoltResponse], ) -> BoltResponse: if self._is_ssl_check_request(req.body): - if self._verify_token_if_needed(req.body): + if not self._verify_token_if_needed(req.body): return self._build_error_response() return self._build_success_response() else: @@ -51,8 +51,12 @@ def process( def _is_ssl_check_request(body: dict): return "ssl_check" in body and body["ssl_check"] == "1" - def _verify_token_if_needed(self, body: dict): - return self.verification_token and self.verification_token == body["token"] + def _verify_token_if_needed(self, body: dict) -> bool: + # Returns True when the request is acceptable: either no token check is configured, + # or the token in the body matches the configured one + if self.verification_token is None: + return True + return self.verification_token == body.get("token") @staticmethod def _build_success_response() -> BoltResponse: diff --git a/tests/scenario_tests/test_ssl_check.py b/tests/scenario_tests/test_ssl_check.py index 937f9d7e4..6cd146598 100644 --- a/tests/scenario_tests/test_ssl_check.py +++ b/tests/scenario_tests/test_ssl_check.py @@ -56,6 +56,32 @@ def test_ssl_check(self): assert response.status == 200 assert response.body == "" + def test_ssl_check_with_verification_token(self): + app = App(client=self.web_client, signing_secret=self.signing_secret, verification_token="expected") + + def dispatch(body: str): + timestamp = str(int(time())) + request = BoltRequest( + body=body, + query={}, + headers={ + "content-type": ["application/x-www-form-urlencoded"], + "x-slack-signature": [self.generate_signature(body, timestamp)], + "x-slack-request-timestamp": [timestamp], + }, + ) + return app.dispatch(request) + + response = dispatch("token=expected&ssl_check=1") + assert response.status == 200 + assert response.body == "" + + response = dispatch("token=wrong&ssl_check=1") + assert response.status == 401 + + response = dispatch("ssl_check=1") + assert response.status == 401 + def test_ssl_check_disabled(self): app = App( client=self.web_client, diff --git a/tests/scenario_tests_async/test_ssl_check.py b/tests/scenario_tests_async/test_ssl_check.py index ef32bc0dd..f1967163b 100644 --- a/tests/scenario_tests_async/test_ssl_check.py +++ b/tests/scenario_tests_async/test_ssl_check.py @@ -61,3 +61,30 @@ async def test_ssl_check(self): response = await app.async_dispatch(request) assert response.status == 200 assert response.body == "" + + @pytest.mark.asyncio + async def test_ssl_check_with_verification_token(self): + app = AsyncApp(client=self.web_client, signing_secret=self.signing_secret, verification_token="expected") + + async def dispatch(body: str): + timestamp = str(int(time())) + request = AsyncBoltRequest( + body=body, + query={}, + headers={ + "content-type": ["application/x-www-form-urlencoded"], + "x-slack-signature": [self.generate_signature(body, timestamp)], + "x-slack-request-timestamp": [timestamp], + }, + ) + return await app.async_dispatch(request) + + response = await dispatch("token=expected&ssl_check=1") + assert response.status == 200 + assert response.body == "" + + response = await dispatch("token=wrong&ssl_check=1") + assert response.status == 401 + + response = await dispatch("ssl_check=1") + assert response.status == 401