diff --git a/slack_bolt/authorization/async_authorize.py b/slack_bolt/authorization/async_authorize.py index 18189adc8..76cfaf64c 100644 --- a/slack_bolt/authorization/async_authorize.py +++ b/slack_bolt/authorization/async_authorize.py @@ -207,10 +207,11 @@ async def __call__( if latest_bot_installation.user_id != user_id: # First off, remove the user token as the installer is a different user user_token = None + user_scopes = None latest_bot_installation.user_token = None latest_bot_installation.user_refresh_token = None latest_bot_installation.user_token_expires_at = None - latest_bot_installation.user_scopes = [] + latest_bot_installation.user_scopes = None # try to fetch the request user's installation # to reflect the user's access token if exists diff --git a/slack_bolt/authorization/authorize.py b/slack_bolt/authorization/authorize.py index 05b306165..170955810 100644 --- a/slack_bolt/authorization/authorize.py +++ b/slack_bolt/authorization/authorize.py @@ -206,10 +206,11 @@ def __call__( if latest_bot_installation.user_id != user_id: # First off, remove the user token as the installer is a different user user_token = None + user_scopes = None latest_bot_installation.user_token = None latest_bot_installation.user_refresh_token = None latest_bot_installation.user_token_expires_at = None - latest_bot_installation.user_scopes = [] + latest_bot_installation.user_scopes = None # try to fetch the request user's installation # to reflect the user's access token if exists diff --git a/tests/scenario_tests/test_app_actor_user_token.py b/tests/scenario_tests/test_app_actor_user_token.py index 4fd1b4751..5c05de43e 100644 --- a/tests/scenario_tests/test_app_actor_user_token.py +++ b/tests/scenario_tests/test_app_actor_user_token.py @@ -109,12 +109,12 @@ def build_headers(self, timestamp: str, body: str): "x-slack-request-timestamp": [timestamp], } - def build_request(self): + def build_request(self, team_id: str = "T014GJXU940"): timestamp, body = str(int(time())), json.dumps( { - "team_id": "T014GJXU940", + "team_id": team_id, "enterprise_id": "E013Y3SHLAY", - "context_team_id": "T014GJXU940", + "context_team_id": team_id, "context_enterprise_id": "E013Y3SHLAY", "api_app_id": "A04TEM7H4S0", "event": { @@ -123,7 +123,7 @@ def build_request(self): "upload": False, "user": "W013QGS7BPF", "display_as_bot": False, - "team": "T014GJXU940", + "team": team_id, "channel": "C04T3ACM40K", "subtype": "file_share", }, @@ -176,3 +176,38 @@ def handle_events(context: BoltContext, say: Say): assert_auth_test_count(self, 1) sleep(1) # wait a bit after auto ack() assert self.mock_received_requests["/chat.postMessage"] == 1 + + def test_authorize_result_no_user_token(self): + app = App( + client=self.web_client, + signing_secret=self.signing_secret, + oauth_settings=OAuthSettings( + client_id="111.222", + client_secret="secret", + scopes=["commands", "chat:write"], + user_scopes=["search:read", "chat:write"], + installation_store=MemoryInstallationStore(), + user_token_resolution="actor", + ), + ) + + @app.event("message") + def handle_events(context: BoltContext, say: Say): + assert context.actor_enterprise_id == "E013Y3SHLAY" + assert context.actor_team_id == "T111111" + assert context.actor_user_id == "W013QGS7BPF" + + assert context.authorize_result.bot_id == "BZYBOTHED" + assert context.authorize_result.bot_user_id == "W23456789" + assert context.authorize_result.bot_token == "xoxb-valid-2" + assert context.authorize_result.bot_scopes == ["commands", "chat:write"] + assert context.authorize_result.user_id is None + assert context.authorize_result.user_token is None + assert context.authorize_result.user_scopes is None + say("What's up?") + + response = app.dispatch(self.build_request(team_id="T111111")) + assert response.status == 200 + assert_auth_test_count(self, 1) + sleep(1) # wait a bit after auto ack() + assert self.mock_received_requests["/chat.postMessage"] == 1 diff --git a/tests/scenario_tests_async/test_app_actor_user_token.py b/tests/scenario_tests_async/test_app_actor_user_token.py index c9c395297..f2a7ddd00 100644 --- a/tests/scenario_tests_async/test_app_actor_user_token.py +++ b/tests/scenario_tests_async/test_app_actor_user_token.py @@ -61,12 +61,12 @@ def build_headers(self, timestamp: str, body: str): "x-slack-request-timestamp": [timestamp], } - def build_request(self) -> AsyncBoltRequest: + def build_request(self, team_id: str = "T014GJXU940") -> AsyncBoltRequest: timestamp, body = str(int(time())), json.dumps( { - "team_id": "T014GJXU940", + "team_id": team_id, "enterprise_id": "E013Y3SHLAY", - "context_team_id": "T014GJXU940", + "context_team_id": team_id, "context_enterprise_id": "E013Y3SHLAY", "api_app_id": "A04TEM7H4S0", "event": { @@ -75,7 +75,7 @@ def build_request(self) -> AsyncBoltRequest: "upload": False, "user": "W013QGS7BPF", "display_as_bot": False, - "team": "T014GJXU940", + "team": team_id, "channel": "C04T3ACM40K", "subtype": "file_share", }, @@ -129,6 +129,41 @@ async def handle_events(context: AsyncBoltContext, say: AsyncSay): await asyncio.sleep(1) # wait a bit after auto ack() assert self.mock_received_requests["/chat.postMessage"] == 1 + @pytest.mark.asyncio + async def test_authorize_result_no_user_token(self): + app = AsyncApp( + client=self.web_client, + signing_secret=self.signing_secret, + oauth_settings=AsyncOAuthSettings( + client_id="111.222", + client_secret="secret", + installation_store=MemoryInstallationStore(), + user_token_resolution="actor", + ), + ) + + @app.event("message") + async def handle_events(context: AsyncBoltContext, say: AsyncSay): + assert context.actor_enterprise_id == "E013Y3SHLAY" + assert context.actor_team_id == "T11111" + assert context.actor_user_id == "W013QGS7BPF" + + assert context.authorize_result.bot_id == "BZYBOTHED" + assert context.authorize_result.bot_user_id == "W23456789" + assert context.authorize_result.bot_token == "xoxb-valid-2" + assert context.authorize_result.bot_scopes == ["commands", "chat:write"] + assert context.authorize_result.user_id is None + assert context.authorize_result.user_token is None + assert context.authorize_result.user_scopes is None + await say("What's up?") + + request = self.build_request(team_id="T11111") + response = await app.async_dispatch(request) + assert response.status == 200 + await assert_auth_test_count_async(self, 1) + await asyncio.sleep(1) # wait a bit after auto ack() + assert self.mock_received_requests["/chat.postMessage"] == 1 + class MemoryInstallationStore(AsyncInstallationStore): @property