Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion slack_bolt/middleware/ssl_check/async_ssl_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
10 changes: 7 additions & 3 deletions slack_bolt/middleware/ssl_check/ssl_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand Down
26 changes: 26 additions & 0 deletions tests/scenario_tests/test_ssl_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
27 changes: 27 additions & 0 deletions tests/scenario_tests_async/test_ssl_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -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