diff --git a/changelog.d/17973.feature b/changelog.d/17973.feature new file mode 100644 index 00000000000..261df6c72fe --- /dev/null +++ b/changelog.d/17973.feature @@ -0,0 +1 @@ +Implement MSC4185: Event Visibility API. diff --git a/synapse/config/experimental.py b/synapse/config/experimental.py index 3411179a2a3..75ac705d531 100644 --- a/synapse/config/experimental.py +++ b/synapse/config/experimental.py @@ -443,6 +443,9 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None: # MSC4151: Report room API (Client-Server API) self.msc4151_enabled: bool = experimental.get("msc4151_enabled", False) + # MSC4185: Event Visibility API + self.msc4185_enabled: bool = experimental.get("msc4185_enabled", False) + # MSC4210: Remove legacy mentions self.msc4210_enabled: bool = experimental.get("msc4210_enabled", False) diff --git a/synapse/rest/__init__.py b/synapse/rest/__init__.py index 4e594e6595f..f81aca7a892 100644 --- a/synapse/rest/__init__.py +++ b/synapse/rest/__init__.py @@ -27,6 +27,7 @@ account, account_data, account_validity, + appservice_event_visibility, appservice_ping, auth, auth_issuer, @@ -117,6 +118,7 @@ password_policy.register_servlets, knock.register_servlets, appservice_ping.register_servlets, + appservice_event_visibility.register_servlets, admin.register_servlets_for_client_rest_resource, mutual_rooms.register_servlets, login_token_request.register_servlets, diff --git a/synapse/rest/client/appservice_event_visibility.py b/synapse/rest/client/appservice_event_visibility.py new file mode 100644 index 00000000000..37cb4581c01 --- /dev/null +++ b/synapse/rest/client/appservice_event_visibility.py @@ -0,0 +1,75 @@ +# Copyright 2024 The Matrix.org Foundation C.I.C +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +from http import HTTPStatus +from typing import TYPE_CHECKING, Tuple + +from synapse.api.errors import ( + Codes, + SynapseError, +) +from synapse.http.server import HttpServer +from synapse.http.servlet import RestServlet +from synapse.http.site import SynapseRequest +from synapse.visibility import filter_events_for_client + +from ._base import client_patterns + +if TYPE_CHECKING: + from synapse.server import HomeServer + +logger = logging.getLogger(__name__) + + +class AppserviceEventVisibilityrestServlet(RestServlet): + PATTERNS = client_patterns( + "/net.tadzik/appservice/(?P[^/]*)/can_user_see_event/(?P[^/]*)/(?P[^/]*)/(?P[^/]*)$", + unstable=True, + releases=(), + ) + + def __init__(self, hs: "HomeServer"): + super().__init__() + self.auth = hs.get_auth() + self.store = hs.get_datastores().main + self._storage_controllers = hs.get_storage_controllers() + + async def on_GET( + self, request: SynapseRequest, appservice_id: str, room_id: str, user_id: str, event_id: str + ) -> Tuple[int, bool]: + logger.info('on_GET') + requester = await self.auth.get_user_by_req(request) + + if not requester.app_service: + raise SynapseError( + HTTPStatus.FORBIDDEN, + "Only application services can use the /can_user_see_event endpoint", + Codes.FORBIDDEN, + ) + elif requester.app_service.id != appservice_id: + raise SynapseError( + HTTPStatus.FORBIDDEN, + "Mismatching application service ID in path", + Codes.FORBIDDEN, + ) + + event = await self.store.get_event(event_id, check_room_id=room_id) + filtered = await filter_events_for_client(self._storage_controllers, user_id, [event]) + + return HTTPStatus.OK, bool(filtered) + +def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None: + if hs.config.experimental.msc4185_enabled: + AppserviceEventVisibilityrestServlet(hs).register(http_server) diff --git a/synapse/rest/client/versions.py b/synapse/rest/client/versions.py index ba1141bbe59..e46acd9bbb9 100644 --- a/synapse/rest/client/versions.py +++ b/synapse/rest/client/versions.py @@ -143,6 +143,8 @@ async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]: "fi.mau.msc2815": self.config.experimental.msc2815_enabled, # Adds a ping endpoint for appservices to check HS->AS connection "fi.mau.msc2659.stable": True, # TODO: remove when "v1.7" is added above + # Adds Event visibility API + "net.tadzik.msc4185": self.config.experimental.msc4185_enabled, # TODO: this is no longer needed once unstable MSC3882 does not need to be supported: "org.matrix.msc3882": self.config.auth.login_via_existing_enabled, # Adds support for remotely enabling/disabling pushers, as per MSC3881