From 52f053abef1678fb745e6094085cf34be885c9ac Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Mon, 12 Oct 2026 17:43:38 +0100 Subject: [PATCH] Remove support for unstable MSC2965 (#20143) These things are not needed now that MSC2965 has stabilised. In any case, they should never have been exposed without a config flag in the first place. --- changelog.d/20143.removal | 1 + synapse/api/auth/mas.py | 5 --- synapse/rest/client/auth_metadata.py | 18 +++------ synapse/rest/well_known.py | 10 ----- tests/rest/client/test_auth_metadata.py | 52 ++++++++++++++++++++----- tests/rest/test_well_known.py | 45 --------------------- 6 files changed, 49 insertions(+), 82 deletions(-) create mode 100644 changelog.d/20143.removal diff --git a/changelog.d/20143.removal b/changelog.d/20143.removal new file mode 100644 index 0000000000..1861595cc6 --- /dev/null +++ b/changelog.d/20143.removal @@ -0,0 +1 @@ +Remove support for unstable [MSC2965](https://github.com/matrix-org/matrix-spec-proposals/pull/2965) `.well-known` endpoint. diff --git a/synapse/api/auth/mas.py b/synapse/api/auth/mas.py index d094410ff9..f98ab748fb 100644 --- a/synapse/api/auth/mas.py +++ b/synapse/api/auth/mas.py @@ -67,7 +67,6 @@ STABLE_SCOPE_MATRIX_DEVICE_PREFIX = "urn:matrix:client:device:" class ServerMetadata(BaseModel): model_config = ConfigDict(extra="allow") - issuer: StrictStr account_management_uri: StrictStr @@ -161,10 +160,6 @@ class MasDelegatedAuth(BaseAuth): metadata = ServerMetadata(**response) return metadata - async def issuer(self) -> str: - metadata = await self._server_metadata.get() - return metadata.issuer - async def account_management_url(self) -> str: metadata = await self._server_metadata.get() return metadata.account_management_uri diff --git a/synapse/rest/client/auth_metadata.py b/synapse/rest/client/auth_metadata.py index c5b874b533..d8f172d0bd 100644 --- a/synapse/rest/client/auth_metadata.py +++ b/synapse/rest/client/auth_metadata.py @@ -30,17 +30,11 @@ class AuthMetadataServlet(RestServlet): Advertises the OAuth 2.0 server metadata for the homeserver. """ - PATTERNS = [ - *client_patterns( - "/auth_metadata$", - releases=("v1",), - ), - *client_patterns( - "/org.matrix.msc2965/auth_metadata$", - unstable=True, - releases=(), - ), - ] + PATTERNS = client_patterns( + "/auth_metadata$", + releases=("v1",), + unstable=False, + ) def __init__(self, hs: "HomeServer"): super().__init__() @@ -50,7 +44,7 @@ class AuthMetadataServlet(RestServlet): async def on_GET(self, request: SynapseRequest) -> tuple[int, JsonDict]: # This endpoint is unauthenticated and the response only depends on # the metadata we get from Matrix Authentication Service. Internally, - # MasDelegatedAuth.issuer() is already caching the + # MasDelegatedAuth.auth_metadata() is already caching the # response in memory anyway. Ideally we would follow any Cache-Control directive # given by MAS, but this is fine for now. # diff --git a/synapse/rest/well_known.py b/synapse/rest/well_known.py index 3193761ad0..b2e274e3f3 100644 --- a/synapse/rest/well_known.py +++ b/synapse/rest/well_known.py @@ -23,7 +23,6 @@ from typing import TYPE_CHECKING from twisted.web.resource import Resource from twisted.web.server import Request -from synapse.api.auth.mas import MasDelegatedAuth from synapse.api.errors import NotFoundError from synapse.http.server import DirectServeJsonResource from synapse.http.site import SynapseRequest @@ -40,7 +39,6 @@ logger = logging.getLogger(__name__) class WellKnownBuilder: def __init__(self, hs: "HomeServer"): self._config = hs.config - self._auth = hs.get_auth() async def get_well_known(self) -> JsonDict | None: if not self._config.server.serve_client_wellknown: @@ -53,14 +51,6 @@ class WellKnownBuilder: "base_url": self._config.registration.default_identity_server } - if self._config.mas.enabled: - assert isinstance(self._auth, MasDelegatedAuth) - - result["org.matrix.msc2965.authentication"] = { - "issuer": await self._auth.issuer(), - "account": await self._auth.account_management_url(), - } - if self._config.server.extra_well_known_client_content: for ( key, diff --git a/tests/rest/client/test_auth_metadata.py b/tests/rest/client/test_auth_metadata.py index 683fce46e3..57fe16241d 100644 --- a/tests/rest/client/test_auth_metadata.py +++ b/tests/rest/client/test_auth_metadata.py @@ -19,22 +19,20 @@ # from http import HTTPStatus from typing import ClassVar +from unittest.mock import Mock -from parameterized import parameterized_class +from twisted.internet.testing import MemoryReactor +from synapse.api.auth.mas import MasDelegatedAuth from synapse.rest.client import auth_metadata +from synapse.server import HomeServer +from synapse.types import JsonDict +from synapse.util.clock import Clock from tests.unittest import HomeserverTestCase -@parameterized_class( - ("endpoint",), - [ - ("/_matrix/client/unstable/org.matrix.msc2965/auth_metadata",), - ("/_matrix/client/v1/auth_metadata",), - ], -) -class AuthMetadataTestCase(HomeserverTestCase): +class AuthMetadataMasDisabledTestCase(HomeserverTestCase): endpoint: ClassVar[str] servlets = [ auth_metadata.register_servlets, @@ -42,5 +40,39 @@ class AuthMetadataTestCase(HomeserverTestCase): def test_returns_404_when_mas_disabled(self) -> None: # Make an unauthenticated request for the discovery info. - channel = self.make_request("GET", self.endpoint) + channel = self.make_request("GET", "/_matrix/client/v1/auth_metadata") self.assertEqual(channel.code, HTTPStatus.NOT_FOUND) + + +class AuthMetadataMasEnabledTestCase(HomeserverTestCase): + servlets = [ + auth_metadata.register_servlets, + ] + + def default_config(self) -> JsonDict: + config = super().default_config() + # Registration must be disabled for the MAS integration to be enabled. + config["enable_registration"] = False + config["matrix_authentication_service"] = { + "enabled": True, + "endpoint": "https://auth.example.com/", + "secret": "verysecret", + } + return config + + def make_homeserver(self, reactor: MemoryReactor, clock: Clock) -> HomeServer: + # Install a mock `MasDelegatedAuth` implementation. + self.auth = Mock(spec=MasDelegatedAuth) + return self.setup_test_homeserver(auth=self.auth) + + def test_returns_metadata_from_mas(self) -> None: + test_auth_metadata = { + "issuer": "https://auth.example.com/", + } + + self.auth.auth_metadata.return_value = test_auth_metadata + + channel = self.make_request("GET", "/_matrix/client/v1/auth_metadata") + + self.assertEqual(channel.code, HTTPStatus.OK, channel.result) + self.assertEqual(channel.json_body, test_auth_metadata) diff --git a/tests/rest/test_well_known.py b/tests/rest/test_well_known.py index 3accad842c..5a02a87058 100644 --- a/tests/rest/test_well_known.py +++ b/tests/rest/test_well_known.py @@ -18,8 +18,6 @@ # # -from unittest.mock import AsyncMock - from twisted.web.resource import Resource from synapse.rest.well_known import well_known_resource @@ -105,46 +103,3 @@ class WellKnownTests(unittest.HomeserverTestCase): "GET", "/.well-known/matrix/server", shorthand=False ) self.assertEqual(channel.code, 404) - - @unittest.override_config( - { - "public_baseurl": "https://homeserver", # this is only required so that client well known is served - "matrix_authentication_service": { - "enabled": True, - "endpoint": "https://issuer", - "secret": "secret", - }, - "disable_registration": True, - } - ) - def test_client_well_known_oauth_delegation(self) -> None: - # Patch the HTTP client to return the issuer metadata - req_mock = AsyncMock( - return_value={ - "issuer": "https://issuer", - "account_management_uri": "https://my-account.issuer", - } - ) - self.hs.get_proxied_http_client().get_json = req_mock # type: ignore[method-assign] - - for _ in range(2): - channel = self.make_request( - "GET", "/.well-known/matrix/client", shorthand=False - ) - - self.assertEqual(channel.code, 200) - self.assertEqual( - channel.json_body, - { - "m.homeserver": {"base_url": "https://homeserver/"}, - "org.matrix.msc2965.authentication": { - "issuer": "https://issuer", - "account": "https://my-account.issuer", - }, - }, - ) - - # It should have been called exactly once, because it gets cached - req_mock.assert_called_once_with( - "https://issuer/.well-known/openid-configuration" - )