Enforce that an admin token also has the basic Matrix API scope

This commit is contained in:
Quentin Gliech 2023-05-26 15:16:34 +02:00 committed by Patrick Cloke
parent 32a2f05004
commit ceb3dd77db
2 changed files with 27 additions and 6 deletions

View File

@ -248,13 +248,10 @@ class MSC3861DelegatedAuth(BaseAuth):
scope: List[str] = scope_to_list(introspection_result.get("scope", "")) scope: List[str] = scope_to_list(introspection_result.get("scope", ""))
# Determine type of user based on presence of particular scopes # Determine type of user based on presence of particular scopes
has_admin_scope = SCOPE_SYNAPSE_ADMIN in scope
has_user_scope = SCOPE_MATRIX_API in scope has_user_scope = SCOPE_MATRIX_API in scope
has_guest_scope = SCOPE_MATRIX_GUEST in scope has_guest_scope = SCOPE_MATRIX_GUEST in scope
is_user = has_user_scope or has_admin_scope
is_guest = has_guest_scope and not is_user
if not is_user and not is_guest: if not has_user_scope and not has_guest_scope:
raise InvalidClientTokenError("No scope in token granting user rights") raise InvalidClientTokenError("No scope in token granting user rights")
# Match via the sub claim # Match via the sub claim
@ -351,5 +348,5 @@ class MSC3861DelegatedAuth(BaseAuth):
user_id=user_id, user_id=user_id,
device_id=device_id, device_id=device_id,
scope=scope, scope=scope,
is_guest=is_guest, is_guest=(has_guest_scope and not has_user_scope),
) )

View File

@ -224,6 +224,30 @@ class MSC3861OAuthDelegation(HomeserverTestCase):
) )
self._assertParams() self._assertParams()
def test_active_admin_not_user(self) -> None:
"""The handler should raise when the scope has admin right but not user."""
self.http_client.request = simple_async_mock(
return_value=FakeResponse.json(
code=200,
payload={
"active": True,
"sub": SUBJECT,
"scope": " ".join([SYNAPSE_ADMIN_SCOPE]),
"username": USERNAME,
},
)
)
request = Mock(args={})
request.args[b"access_token"] = [b"mockAccessToken"]
request.requestHeaders.getRawHeaders = mock_getRawHeaders()
self.get_failure(self.auth.get_user_by_req(request), InvalidClientTokenError)
self.http_client.get_json.assert_called_once_with(WELL_KNOWN)
self.http_client.request.assert_called_once_with(
method="POST", uri=INTROSPECTION_ENDPOINT, data=ANY, headers=ANY
)
self._assertParams()
def test_active_admin(self) -> None: def test_active_admin(self) -> None:
"""The handler should return a requester with admin rights.""" """The handler should return a requester with admin rights."""
@ -233,7 +257,7 @@ class MSC3861OAuthDelegation(HomeserverTestCase):
payload={ payload={
"active": True, "active": True,
"sub": SUBJECT, "sub": SUBJECT,
"scope": " ".join([SYNAPSE_ADMIN_SCOPE]), "scope": " ".join([SYNAPSE_ADMIN_SCOPE, MATRIX_USER_SCOPE]),
"username": USERNAME, "username": USERNAME,
}, },
) )