Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit ceb3dd7

Browse files
sandhoseclokep
authored andcommitted
Enforce that an admin token also has the basic Matrix API scope
1 parent 32a2f05 commit ceb3dd7

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

synapse/api/auth/msc3861_delegated.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,13 +248,10 @@ async def get_user_by_access_token(
248248
scope: List[str] = scope_to_list(introspection_result.get("scope", ""))
249249

250250
# Determine type of user based on presence of particular scopes
251-
has_admin_scope = SCOPE_SYNAPSE_ADMIN in scope
252251
has_user_scope = SCOPE_MATRIX_API in scope
253252
has_guest_scope = SCOPE_MATRIX_GUEST in scope
254-
is_user = has_user_scope or has_admin_scope
255-
is_guest = has_guest_scope and not is_user
256253

257-
if not is_user and not is_guest:
254+
if not has_user_scope and not has_guest_scope:
258255
raise InvalidClientTokenError("No scope in token granting user rights")
259256

260257
# Match via the sub claim
@@ -351,5 +348,5 @@ async def get_user_by_access_token(
351348
user_id=user_id,
352349
device_id=device_id,
353350
scope=scope,
354-
is_guest=is_guest,
351+
is_guest=(has_guest_scope and not has_user_scope),
355352
)

tests/handlers/test_oauth_delegation.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,30 @@ def test_active_no_user_scope(self) -> None:
224224
)
225225
self._assertParams()
226226

227+
def test_active_admin_not_user(self) -> None:
228+
"""The handler should raise when the scope has admin right but not user."""
229+
230+
self.http_client.request = simple_async_mock(
231+
return_value=FakeResponse.json(
232+
code=200,
233+
payload={
234+
"active": True,
235+
"sub": SUBJECT,
236+
"scope": " ".join([SYNAPSE_ADMIN_SCOPE]),
237+
"username": USERNAME,
238+
},
239+
)
240+
)
241+
request = Mock(args={})
242+
request.args[b"access_token"] = [b"mockAccessToken"]
243+
request.requestHeaders.getRawHeaders = mock_getRawHeaders()
244+
self.get_failure(self.auth.get_user_by_req(request), InvalidClientTokenError)
245+
self.http_client.get_json.assert_called_once_with(WELL_KNOWN)
246+
self.http_client.request.assert_called_once_with(
247+
method="POST", uri=INTROSPECTION_ENDPOINT, data=ANY, headers=ANY
248+
)
249+
self._assertParams()
250+
227251
def test_active_admin(self) -> None:
228252
"""The handler should return a requester with admin rights."""
229253

@@ -233,7 +257,7 @@ def test_active_admin(self) -> None:
233257
payload={
234258
"active": True,
235259
"sub": SUBJECT,
236-
"scope": " ".join([SYNAPSE_ADMIN_SCOPE]),
260+
"scope": " ".join([SYNAPSE_ADMIN_SCOPE, MATRIX_USER_SCOPE]),
237261
"username": USERNAME,
238262
},
239263
)

0 commit comments

Comments
 (0)