Skip to content

Commit 7fdd404

Browse files
fix: defer SignatureVerifier construction so Socket Mode apps init without a signing secret (#1541)
Co-authored-by: William Bergamin <wbergamin@salesforce.com>
1 parent 29b9dbd commit 7fdd404

4 files changed

Lines changed: 56 additions & 2 deletions

File tree

slack_bolt/middleware/request_verification/request_verification.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from logging import Logger
2-
from typing import Callable, Dict, Any, Optional
2+
from typing import Any, Callable, Dict, Optional
33

44
from slack_sdk.signature import SignatureVerifier
55

@@ -20,9 +20,17 @@ def __init__(self, signing_secret: str, base_logger: Optional[Logger] = None):
2020
signing_secret: The signing secret
2121
base_logger: The base logger
2222
"""
23-
self.verifier = SignatureVerifier(signing_secret=signing_secret)
23+
self._signing_secret = signing_secret
24+
self._verifier: Optional[SignatureVerifier] = None
2425
self.logger = get_bolt_logger(RequestVerification, base_logger=base_logger)
2526

27+
@property
28+
def verifier(self) -> SignatureVerifier:
29+
# Defer initialization to avoid errors during start up
30+
if self._verifier is None:
31+
self._verifier = SignatureVerifier(signing_secret=self._signing_secret)
32+
return self._verifier
33+
2634
def process(
2735
self,
2836
*,

tests/scenario_tests/test_app.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@ def test_token_verification_enabled_False(self):
9696

9797
assert self.received_requests.get("/auth.test") is None
9898

99+
def test_socket_mode_app_without_signing_secret(self):
100+
app = App(
101+
client=self.web_client,
102+
token_verification_enabled=False,
103+
)
104+
assert app is not None
105+
99106
# --------------------------
100107
# multi teams auth
101108
# --------------------------

tests/slack_bolt/middleware/request_verification/test_request_verification.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from time import time
22

3+
import pytest
34
from slack_sdk.signature import SignatureVerifier
45

56
from slack_bolt.middleware import RequestVerification
@@ -60,3 +61,21 @@ def test_ssl_check_param_requires_valid_signature(self):
6061
resp = middleware.process(req=req, resp=resp, next=next)
6162
assert resp.status == 401
6263
assert resp.body == """{"error": "invalid request"}"""
64+
65+
def test_empty_signing_secret_does_not_raise_on_init(self):
66+
RequestVerification(signing_secret="")
67+
68+
def test_socket_mode_request_skips_verification_without_signing_secret(self):
69+
middleware = RequestVerification(signing_secret="")
70+
req = BoltRequest(mode="socket_mode", body="payload={}", headers={})
71+
resp = BoltResponse(status=404, body="default")
72+
resp = middleware.process(req=req, resp=resp, next=next)
73+
assert resp.status == 200
74+
assert resp.body == "next"
75+
76+
def test_http_request_with_empty_signing_secret_raises(self):
77+
middleware = RequestVerification(signing_secret="")
78+
req = BoltRequest(body="payload={}", headers={})
79+
resp = BoltResponse(status=404)
80+
with pytest.raises(ValueError):
81+
middleware.process(req=req, resp=resp, next=next)

tests/slack_bolt_async/middleware/request_verification/test_request_verification.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,23 @@ async def test_ssl_check_param_requires_valid_signature(self):
6666
resp = await middleware.async_process(req=req, resp=resp, next=next)
6767
assert resp.status == 401
6868
assert resp.body == """{"error": "invalid request"}"""
69+
70+
def test_empty_signing_secret_does_not_raise_on_init(self):
71+
AsyncRequestVerification(signing_secret="")
72+
73+
@pytest.mark.asyncio
74+
async def test_socket_mode_request_skips_verification_without_signing_secret(self):
75+
middleware = AsyncRequestVerification(signing_secret="")
76+
req = AsyncBoltRequest(mode="socket_mode", body="payload={}", headers={})
77+
resp = BoltResponse(status=404, body="default")
78+
resp = await middleware.async_process(req=req, resp=resp, next=next)
79+
assert resp.status == 200
80+
assert resp.body == "next"
81+
82+
@pytest.mark.asyncio
83+
async def test_http_request_with_empty_signing_secret_raises(self):
84+
middleware = AsyncRequestVerification(signing_secret="")
85+
req = AsyncBoltRequest(body="payload={}", headers={})
86+
resp = BoltResponse(status=404)
87+
with pytest.raises(ValueError):
88+
await middleware.async_process(req=req, resp=resp, next=next)

0 commit comments

Comments
 (0)