Skip to content

Commit fbba6cd

Browse files
authored
Fix a #855 bug where user_scopes exist even when user token is absent (#858)
1 parent a301d3a commit fbba6cd

File tree

4 files changed

+82
-10
lines changed

4 files changed

+82
-10
lines changed

slack_bolt/authorization/async_authorize.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,11 @@ async def __call__(
207207
if latest_bot_installation.user_id != user_id:
208208
# First off, remove the user token as the installer is a different user
209209
user_token = None
210+
user_scopes = None
210211
latest_bot_installation.user_token = None
211212
latest_bot_installation.user_refresh_token = None
212213
latest_bot_installation.user_token_expires_at = None
213-
latest_bot_installation.user_scopes = []
214+
latest_bot_installation.user_scopes = None
214215

215216
# try to fetch the request user's installation
216217
# to reflect the user's access token if exists

slack_bolt/authorization/authorize.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,11 @@ def __call__(
206206
if latest_bot_installation.user_id != user_id:
207207
# First off, remove the user token as the installer is a different user
208208
user_token = None
209+
user_scopes = None
209210
latest_bot_installation.user_token = None
210211
latest_bot_installation.user_refresh_token = None
211212
latest_bot_installation.user_token_expires_at = None
212-
latest_bot_installation.user_scopes = []
213+
latest_bot_installation.user_scopes = None
213214

214215
# try to fetch the request user's installation
215216
# to reflect the user's access token if exists

tests/scenario_tests/test_app_actor_user_token.py

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,12 @@ def build_headers(self, timestamp: str, body: str):
109109
"x-slack-request-timestamp": [timestamp],
110110
}
111111

112-
def build_request(self):
112+
def build_request(self, team_id: str = "T014GJXU940"):
113113
timestamp, body = str(int(time())), json.dumps(
114114
{
115-
"team_id": "T014GJXU940",
115+
"team_id": team_id,
116116
"enterprise_id": "E013Y3SHLAY",
117-
"context_team_id": "T014GJXU940",
117+
"context_team_id": team_id,
118118
"context_enterprise_id": "E013Y3SHLAY",
119119
"api_app_id": "A04TEM7H4S0",
120120
"event": {
@@ -123,7 +123,7 @@ def build_request(self):
123123
"upload": False,
124124
"user": "W013QGS7BPF",
125125
"display_as_bot": False,
126-
"team": "T014GJXU940",
126+
"team": team_id,
127127
"channel": "C04T3ACM40K",
128128
"subtype": "file_share",
129129
},
@@ -176,3 +176,38 @@ def handle_events(context: BoltContext, say: Say):
176176
assert_auth_test_count(self, 1)
177177
sleep(1) # wait a bit after auto ack()
178178
assert self.mock_received_requests["/chat.postMessage"] == 1
179+
180+
def test_authorize_result_no_user_token(self):
181+
app = App(
182+
client=self.web_client,
183+
signing_secret=self.signing_secret,
184+
oauth_settings=OAuthSettings(
185+
client_id="111.222",
186+
client_secret="secret",
187+
scopes=["commands", "chat:write"],
188+
user_scopes=["search:read", "chat:write"],
189+
installation_store=MemoryInstallationStore(),
190+
user_token_resolution="actor",
191+
),
192+
)
193+
194+
@app.event("message")
195+
def handle_events(context: BoltContext, say: Say):
196+
assert context.actor_enterprise_id == "E013Y3SHLAY"
197+
assert context.actor_team_id == "T111111"
198+
assert context.actor_user_id == "W013QGS7BPF"
199+
200+
assert context.authorize_result.bot_id == "BZYBOTHED"
201+
assert context.authorize_result.bot_user_id == "W23456789"
202+
assert context.authorize_result.bot_token == "xoxb-valid-2"
203+
assert context.authorize_result.bot_scopes == ["commands", "chat:write"]
204+
assert context.authorize_result.user_id is None
205+
assert context.authorize_result.user_token is None
206+
assert context.authorize_result.user_scopes is None
207+
say("What's up?")
208+
209+
response = app.dispatch(self.build_request(team_id="T111111"))
210+
assert response.status == 200
211+
assert_auth_test_count(self, 1)
212+
sleep(1) # wait a bit after auto ack()
213+
assert self.mock_received_requests["/chat.postMessage"] == 1

tests/scenario_tests_async/test_app_actor_user_token.py

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ def build_headers(self, timestamp: str, body: str):
6161
"x-slack-request-timestamp": [timestamp],
6262
}
6363

64-
def build_request(self) -> AsyncBoltRequest:
64+
def build_request(self, team_id: str = "T014GJXU940") -> AsyncBoltRequest:
6565
timestamp, body = str(int(time())), json.dumps(
6666
{
67-
"team_id": "T014GJXU940",
67+
"team_id": team_id,
6868
"enterprise_id": "E013Y3SHLAY",
69-
"context_team_id": "T014GJXU940",
69+
"context_team_id": team_id,
7070
"context_enterprise_id": "E013Y3SHLAY",
7171
"api_app_id": "A04TEM7H4S0",
7272
"event": {
@@ -75,7 +75,7 @@ def build_request(self) -> AsyncBoltRequest:
7575
"upload": False,
7676
"user": "W013QGS7BPF",
7777
"display_as_bot": False,
78-
"team": "T014GJXU940",
78+
"team": team_id,
7979
"channel": "C04T3ACM40K",
8080
"subtype": "file_share",
8181
},
@@ -129,6 +129,41 @@ async def handle_events(context: AsyncBoltContext, say: AsyncSay):
129129
await asyncio.sleep(1) # wait a bit after auto ack()
130130
assert self.mock_received_requests["/chat.postMessage"] == 1
131131

132+
@pytest.mark.asyncio
133+
async def test_authorize_result_no_user_token(self):
134+
app = AsyncApp(
135+
client=self.web_client,
136+
signing_secret=self.signing_secret,
137+
oauth_settings=AsyncOAuthSettings(
138+
client_id="111.222",
139+
client_secret="secret",
140+
installation_store=MemoryInstallationStore(),
141+
user_token_resolution="actor",
142+
),
143+
)
144+
145+
@app.event("message")
146+
async def handle_events(context: AsyncBoltContext, say: AsyncSay):
147+
assert context.actor_enterprise_id == "E013Y3SHLAY"
148+
assert context.actor_team_id == "T11111"
149+
assert context.actor_user_id == "W013QGS7BPF"
150+
151+
assert context.authorize_result.bot_id == "BZYBOTHED"
152+
assert context.authorize_result.bot_user_id == "W23456789"
153+
assert context.authorize_result.bot_token == "xoxb-valid-2"
154+
assert context.authorize_result.bot_scopes == ["commands", "chat:write"]
155+
assert context.authorize_result.user_id is None
156+
assert context.authorize_result.user_token is None
157+
assert context.authorize_result.user_scopes is None
158+
await say("What's up?")
159+
160+
request = self.build_request(team_id="T11111")
161+
response = await app.async_dispatch(request)
162+
assert response.status == 200
163+
await assert_auth_test_count_async(self, 1)
164+
await asyncio.sleep(1) # wait a bit after auto ack()
165+
assert self.mock_received_requests["/chat.postMessage"] == 1
166+
132167

133168
class MemoryInstallationStore(AsyncInstallationStore):
134169
@property

0 commit comments

Comments
 (0)