chore: import upstream snapshot with attribution
Deploy Docs / deploy-docs (push) Failing after 1s
Conformance Tests / client-conformance (push) Failing after 3s
Conformance Tests / server-conformance (push) Failing after 1s
GitHub Actions Security Analysis / zizmor (push) Failing after 1s
CI / checks (push) Failing after 59m20s
CI / all-green (push) Has been cancelled
Deploy Docs / deploy-docs (push) Failing after 1s
Conformance Tests / client-conformance (push) Failing after 3s
Conformance Tests / server-conformance (push) Failing after 1s
GitHub Actions Security Analysis / zizmor (push) Failing after 1s
CI / checks (push) Failing after 59m20s
CI / all-green (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import pytest
|
||||
from pydantic import AnyHttpUrl
|
||||
|
||||
from mcp.server.auth.routes import build_metadata, validate_issuer_url
|
||||
from mcp.server.auth.settings import AuthSettings, ClientRegistrationOptions, RevocationOptions
|
||||
|
||||
|
||||
def test_validate_issuer_url_https_allowed():
|
||||
validate_issuer_url(AnyHttpUrl("https://example.com/path"))
|
||||
|
||||
|
||||
def test_validate_issuer_url_http_localhost_allowed():
|
||||
validate_issuer_url(AnyHttpUrl("http://localhost:8080/path"))
|
||||
|
||||
|
||||
def test_validate_issuer_url_http_127_0_0_1_allowed():
|
||||
validate_issuer_url(AnyHttpUrl("http://127.0.0.1:8080/path"))
|
||||
|
||||
|
||||
def test_validate_issuer_url_http_ipv6_loopback_allowed():
|
||||
validate_issuer_url(AnyHttpUrl("http://[::1]:8080/path"))
|
||||
|
||||
|
||||
def test_validate_issuer_url_http_non_loopback_rejected():
|
||||
with pytest.raises(ValueError, match="Issuer URL must be HTTPS"):
|
||||
validate_issuer_url(AnyHttpUrl("http://evil.com/path"))
|
||||
|
||||
|
||||
def test_validate_issuer_url_http_127_prefix_domain_rejected():
|
||||
"""A domain like 127.0.0.1.evil.com is not loopback."""
|
||||
with pytest.raises(ValueError, match="Issuer URL must be HTTPS"):
|
||||
validate_issuer_url(AnyHttpUrl("http://127.0.0.1.evil.com/path"))
|
||||
|
||||
|
||||
def test_validate_issuer_url_http_127_prefix_subdomain_rejected():
|
||||
"""A domain like 127.0.0.1something.example.com is not loopback."""
|
||||
with pytest.raises(ValueError, match="Issuer URL must be HTTPS"):
|
||||
validate_issuer_url(AnyHttpUrl("http://127.0.0.1something.example.com/path"))
|
||||
|
||||
|
||||
def test_validate_issuer_url_fragment_rejected():
|
||||
with pytest.raises(ValueError, match="fragment"):
|
||||
validate_issuer_url(AnyHttpUrl("https://example.com/path#frag"))
|
||||
|
||||
|
||||
def test_validate_issuer_url_query_rejected():
|
||||
with pytest.raises(ValueError, match="query"):
|
||||
validate_issuer_url(AnyHttpUrl("https://example.com/path?q=1"))
|
||||
|
||||
|
||||
def test_auth_settings_preserves_path_less_issuer():
|
||||
"""A path-less issuer passed as a string keeps its canonical form (no trailing slash)."""
|
||||
settings = AuthSettings(
|
||||
issuer_url="https://as.example.com", # type: ignore[arg-type]
|
||||
resource_server_url="https://rs.example.com", # type: ignore[arg-type]
|
||||
)
|
||||
assert str(settings.issuer_url) == "https://as.example.com"
|
||||
assert str(settings.resource_server_url) == "https://rs.example.com"
|
||||
|
||||
|
||||
def test_build_metadata_serves_issuer_without_trailing_slash():
|
||||
"""The served issuer matches the configured one exactly (RFC 8414/9207 string comparison)."""
|
||||
settings = AuthSettings(
|
||||
issuer_url="https://as.example.com", # type: ignore[arg-type]
|
||||
resource_server_url="https://rs.example.com", # type: ignore[arg-type]
|
||||
)
|
||||
metadata = build_metadata(settings.issuer_url, None, ClientRegistrationOptions(), RevocationOptions())
|
||||
|
||||
served = metadata.model_dump(mode="json", exclude_none=True)
|
||||
assert served["issuer"] == "https://as.example.com"
|
||||
assert served["authorization_endpoint"] == "https://as.example.com/authorize"
|
||||
assert served["token_endpoint"] == "https://as.example.com/token"
|
||||
Reference in New Issue
Block a user