Skip to content

Commit 7fa4e88

Browse files
authored
Fix #584 Wrong user_token assigned to new user (affected versions: v1.11.2, v1.11.3) (#586)
1 parent b4dab2c commit 7fa4e88

File tree

5 files changed

+121
-13
lines changed

5 files changed

+121
-13
lines changed

slack_bolt/authorization/async_authorize.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,10 @@ async def __call__(
194194

195195
if latest_installation.user_id != user_id:
196196
# First off, remove the user token as the installer is a different user
197+
user_token = None
197198
latest_installation.user_token = None
199+
latest_installation.user_refresh_token = None
200+
latest_installation.user_token_expires_at = None
198201
latest_installation.user_scopes = []
199202

200203
# try to fetch the request user's installation

slack_bolt/authorization/authorize.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,10 @@ def __call__(
194194

195195
if latest_installation.user_id != user_id:
196196
# First off, remove the user token as the installer is a different user
197+
user_token = None
197198
latest_installation.user_token = None
199+
latest_installation.user_refresh_token = None
200+
latest_installation.user_token_expires_at = None
198201
latest_installation.user_scopes = []
199202

200203
# try to fetch the request user's installation

tests/mock_web_api_server.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -155,19 +155,21 @@ def _handle(self):
155155
self.logger.info(f"request body: {request_body}")
156156

157157
if request_body.get("grant_type") == "refresh_token":
158-
if "bot-valid" in request_body.get("refresh_token"):
159-
self.send_response(200)
160-
self.set_common_headers()
161-
body = self.oauth_v2_access_bot_refresh_response
162-
self.wfile.write(body.encode("utf-8"))
163-
return
164-
if "user-valid" in request_body.get("refresh_token"):
165-
self.send_response(200)
166-
self.set_common_headers()
167-
body = self.oauth_v2_access_user_refresh_response
168-
self.wfile.write(body.encode("utf-8"))
169-
return
170-
if request_body.get("code") is not None:
158+
refresh_token = request_body.get("refresh_token")
159+
if refresh_token is not None:
160+
if "bot-valid" in refresh_token:
161+
self.send_response(200)
162+
self.set_common_headers()
163+
body = self.oauth_v2_access_bot_refresh_response
164+
self.wfile.write(body.encode("utf-8"))
165+
return
166+
if "user-valid" in refresh_token:
167+
self.send_response(200)
168+
self.set_common_headers()
169+
body = self.oauth_v2_access_user_refresh_response
170+
self.wfile.write(body.encode("utf-8"))
171+
return
172+
elif request_body.get("code") is not None:
171173
self.send_response(200)
172174
self.set_common_headers()
173175
self.wfile.write(self.oauth_v2_access_response.encode("utf-8"))

tests/slack_bolt/authorization/test_authorize.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,55 @@ def test_fetch_different_user_token_with_rotation(self):
245245
assert result.user_token == "xoxp-valid-refreshed"
246246
assert_auth_test_count(self, 1)
247247

248+
def test_remove_latest_user_token_if_it_is_not_relevant(self):
249+
installation_store = ValidUserTokenInstallationStore()
250+
authorize = InstallationStoreAuthorize(
251+
logger=installation_store.logger, installation_store=installation_store
252+
)
253+
context = BoltContext()
254+
context["client"] = WebClient(base_url=self.mock_api_server_base_url)
255+
result = authorize(
256+
context=context, enterprise_id="E111", team_id="T0G9PQBBK", user_id="W333"
257+
)
258+
assert result.bot_id == "BZYBOTHED"
259+
assert result.bot_user_id == "W23456789"
260+
assert result.bot_token == "xoxb-valid"
261+
assert result.user_token is None
262+
assert_auth_test_count(self, 1)
263+
264+
def test_rotate_only_bot_token(self):
265+
context = BoltContext()
266+
mock_client = WebClient(base_url=self.mock_api_server_base_url)
267+
context["client"] = mock_client
268+
269+
installation_store = ValidUserTokenRotationInstallationStore()
270+
invalid_authorize = InstallationStoreAuthorize(
271+
logger=installation_store.logger, installation_store=installation_store
272+
)
273+
with pytest.raises(BoltError):
274+
invalid_authorize(
275+
context=context,
276+
enterprise_id="E111",
277+
team_id="T0G9PQBBK",
278+
user_id="W333",
279+
)
280+
281+
authorize = InstallationStoreAuthorize(
282+
client_id="111.222",
283+
client_secret="secret",
284+
client=mock_client,
285+
logger=installation_store.logger,
286+
installation_store=installation_store,
287+
)
288+
result = authorize(
289+
context=context, enterprise_id="E111", team_id="T0G9PQBBK", user_id="W333"
290+
)
291+
assert result.bot_id == "BZYBOTHED"
292+
assert result.bot_user_id == "W23456789"
293+
assert result.bot_token == "xoxb-valid-refreshed"
294+
assert result.user_token is None
295+
assert_auth_test_count(self, 1)
296+
248297

249298
class LegacyMemoryInstallationStore(InstallationStore):
250299
@property

tests/slack_bolt_async/authorization/test_async_authorize.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,57 @@ async def test_fetch_different_user_token_with_rotation(self):
272272
assert result.user_token == "xoxp-valid-refreshed"
273273
await assert_auth_test_count_async(self, 1)
274274

275+
@pytest.mark.asyncio
276+
async def test_remove_latest_user_token_if_it_is_not_relevant(self):
277+
installation_store = ValidUserTokenInstallationStore()
278+
authorize = AsyncInstallationStoreAuthorize(
279+
logger=installation_store.logger, installation_store=installation_store
280+
)
281+
context = AsyncBoltContext()
282+
context["client"] = AsyncWebClient(base_url=self.mock_api_server_base_url)
283+
result = await authorize(
284+
context=context, enterprise_id="E111", team_id="T0G9PQBBK", user_id="W333"
285+
)
286+
assert result.bot_id == "BZYBOTHED"
287+
assert result.bot_user_id == "W23456789"
288+
assert result.bot_token == "xoxb-valid"
289+
assert result.user_token is None
290+
await assert_auth_test_count_async(self, 1)
291+
292+
@pytest.mark.asyncio
293+
async def test_rotate_only_bot_token(self):
294+
context = AsyncBoltContext()
295+
mock_client = AsyncWebClient(base_url=self.mock_api_server_base_url)
296+
context["client"] = mock_client
297+
298+
installation_store = ValidUserTokenRotationInstallationStore()
299+
invalid_authorize = AsyncInstallationStoreAuthorize(
300+
logger=installation_store.logger, installation_store=installation_store
301+
)
302+
with pytest.raises(BoltError):
303+
await invalid_authorize(
304+
context=context,
305+
enterprise_id="E111",
306+
team_id="T0G9PQBBK",
307+
user_id="W333",
308+
)
309+
310+
authorize = AsyncInstallationStoreAuthorize(
311+
client_id="111.222",
312+
client_secret="secret",
313+
client=mock_client,
314+
logger=installation_store.logger,
315+
installation_store=installation_store,
316+
)
317+
result = await authorize(
318+
context=context, enterprise_id="E111", team_id="T0G9PQBBK", user_id="W333"
319+
)
320+
assert result.bot_id == "BZYBOTHED"
321+
assert result.bot_user_id == "W23456789"
322+
assert result.bot_token == "xoxb-valid-refreshed"
323+
assert result.user_token is None
324+
await assert_auth_test_count_async(self, 1)
325+
275326

276327
class LegacyMemoryInstallationStore(AsyncInstallationStore):
277328
@property

0 commit comments

Comments
 (0)