Use 120 characters instead of 88 (#856)

This commit is contained in:
Marcelo Trylesinski 2025-06-11 02:45:50 -07:00 • committed by GitHub
commit 543961968c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -7,19 +7,10 @@ from typing import Annotated, Any, Literal
from pydantic import AnyHttpUrl, AnyUrl, BaseModel, Field, RootModel, ValidationError
from starlette.requests import Request
from mcp.server.auth.errors import (
stringify_pydantic_error,
)
from mcp.server.auth.errors import stringify_pydantic_error
from mcp.server.auth.json_response import PydanticJSONResponse
from mcp.server.auth.middleware.client_auth import (
AuthenticationError,
ClientAuthenticator,
)
from mcp.server.auth.provider import (
OAuthAuthorizationServerProvider,
TokenError,
TokenErrorCode,
)
from mcp.server.auth.middleware.client_auth import AuthenticationError, ClientAuthenticator
from mcp.server.auth.provider import OAuthAuthorizationServerProvider, TokenError, TokenErrorCode
from mcp.shared.auth import OAuthToken
@ -27,9 +18,7 @@ class AuthorizationCodeRequest(BaseModel):
# See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3
grant_type: Literal["authorization_code"]
code: str = Field(..., description="The authorization code")
redirect_uri: AnyUrl | None = Field(
None, description="Must be the same as redirect URI provided in /authorize"
)
redirect_uri: AnyUrl | None = Field(None, description="Must be the same as redirect URI provided in /authorize")
client_id: str
# we use the client_secret param, per https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1
client_secret: str | None = None
@ -127,8 +116,7 @@ class TokenHandler:
TokenErrorResponse(
error="unsupported_grant_type",
error_description=(
f"Unsupported grant type (supported grant types are "
f"{client_info.grant_types})"
f"Unsupported grant type (supported grant types are " f"{client_info.grant_types})"
),
)
)
@ -137,9 +125,7 @@ class TokenHandler:
match token_request:
case AuthorizationCodeRequest():
auth_code = await self.provider.load_authorization_code(
client_info, token_request.code
)
auth_code = await self.provider.load_authorization_code(client_info, token_request.code)
if auth_code is None or auth_code.client_id != token_request.client_id:
# if code belongs to different client, pretend it doesn't exist
return self.response(
@ -169,18 +155,13 @@ class TokenHandler:
return self.response(
TokenErrorResponse(
error="invalid_request",
error_description=(
"redirect_uri did not match the one "
"used when creating auth code"
),
error_description=("redirect_uri did not match the one " "used when creating auth code"),
)
)
# Verify PKCE code verifier
sha256 = hashlib.sha256(token_request.code_verifier.encode()).digest()
hashed_code_verifier = (
base64.urlsafe_b64encode(sha256).decode().rstrip("=")
)
hashed_code_verifier = base64.urlsafe_b64encode(sha256).decode().rstrip("=")
if hashed_code_verifier != auth_code.code_challenge:
# see https://datatracker.ietf.org/doc/html/rfc7636#section-4.6
@ -193,9 +174,7 @@ class TokenHandler:
try:
# Exchange authorization code for tokens
tokens = await self.provider.exchange_authorization_code(
client_info, auth_code
)
tokens = await self.provider.exchange_authorization_code(client_info, auth_code)
except TokenError as e:
return self.response(
TokenErrorResponse(
@ -205,13 +184,8 @@ class TokenHandler:
)
case RefreshTokenRequest():
refresh_token = await self.provider.load_refresh_token(
client_info, token_request.refresh_token
)
if (
refresh_token is None
or refresh_token.client_id != token_request.client_id
):
refresh_token = await self.provider.load_refresh_token(client_info, token_request.refresh_token)
if refresh_token is None or refresh_token.client_id != token_request.client_id:
# if token belongs to different client, pretend it doesn't exist
return self.response(
TokenErrorResponse(
@ -230,29 +204,20 @@ class TokenHandler:
)
# Parse scopes if provided
scopes = (
token_request.scope.split(" ")
if token_request.scope
else refresh_token.scopes
)
scopes = token_request.scope.split(" ") if token_request.scope else refresh_token.scopes
for scope in scopes:
if scope not in refresh_token.scopes:
return self.response(
TokenErrorResponse(
error="invalid_scope",
error_description=(
f"cannot request scope `{scope}` "
"not provided by refresh token"
),
error_description=(f"cannot request scope `{scope}` " "not provided by refresh token"),
)
)
try:
# Exchange refresh token for new tokens
tokens = await self.provider.exchange_refresh_token(
client_info, refresh_token, scopes
)
tokens = await self.provider.exchange_refresh_token(client_info, refresh_token, scopes)
except TokenError as e:
return self.response(
TokenErrorResponse(