mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-09 07:09:11 +02:00
Record effective scopes on the OAuth transaction (#4670)
This commit is contained in:
parent
4e136e60d6
commit
95edc1d2f3
2 changed files with 70 additions and 1 deletions
|
|
@ -55,6 +55,67 @@ class TestOAuthProxyAuthorization:
|
|||
assert transaction.client_state == "client-state-123"
|
||||
assert transaction.scopes == ["read", "write"]
|
||||
|
||||
async def test_authorize_records_configured_scopes_when_client_omits_scope(
|
||||
self, oauth_proxy
|
||||
):
|
||||
"""A client that omits `scope` has the configured default recorded.
|
||||
|
||||
The transaction is the single source of truth for what is being
|
||||
authorized, so it must hold the effective scopes rather than an empty
|
||||
list that each downstream consumer patches up on its own.
|
||||
"""
|
||||
client = OAuthClientInformationFull.model_validate(
|
||||
{
|
||||
"client_id": "test-client",
|
||||
"client_secret": "test-secret",
|
||||
"redirect_uris": ["http://localhost:54321/callback"],
|
||||
"jwt_signing_key": "test-secret",
|
||||
}
|
||||
)
|
||||
await oauth_proxy.register_client(client)
|
||||
|
||||
params = AuthorizationParams(
|
||||
redirect_uri=AnyUrl("http://localhost:54321/callback"),
|
||||
redirect_uri_provided_explicitly=True,
|
||||
state="client-state-123",
|
||||
code_challenge="challenge-abc",
|
||||
scopes=None,
|
||||
)
|
||||
|
||||
redirect_url = await oauth_proxy.authorize(client, params)
|
||||
txn_id = parse_qs(urlparse(redirect_url).query)["txn_id"][0]
|
||||
|
||||
transaction = await oauth_proxy._transaction_store.get(key=txn_id)
|
||||
assert transaction is not None
|
||||
assert transaction.scopes == ["read", "write"]
|
||||
|
||||
async def test_authorize_does_not_widen_explicit_client_scopes(self, oauth_proxy):
|
||||
"""An explicit narrow scope request is never widened to the configured set."""
|
||||
client = OAuthClientInformationFull.model_validate(
|
||||
{
|
||||
"client_id": "test-client",
|
||||
"client_secret": "test-secret",
|
||||
"redirect_uris": ["http://localhost:54321/callback"],
|
||||
"jwt_signing_key": "test-secret",
|
||||
}
|
||||
)
|
||||
await oauth_proxy.register_client(client)
|
||||
|
||||
params = AuthorizationParams(
|
||||
redirect_uri=AnyUrl("http://localhost:54321/callback"),
|
||||
redirect_uri_provided_explicitly=True,
|
||||
state="client-state-123",
|
||||
code_challenge="challenge-abc",
|
||||
scopes=["read"],
|
||||
)
|
||||
|
||||
redirect_url = await oauth_proxy.authorize(client, params)
|
||||
txn_id = parse_qs(urlparse(redirect_url).query)["txn_id"][0]
|
||||
|
||||
transaction = await oauth_proxy._transaction_store.get(key=txn_id)
|
||||
assert transaction is not None
|
||||
assert transaction.scopes == ["read"]
|
||||
|
||||
|
||||
class TestOAuthProxyPKCE:
|
||||
"""Tests for OAuth proxy PKCE forwarding."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue