From 24b371be62972a688e928e9b65b0b86f1c2e7b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 20 Jul 2020 14:26:07 +0200 Subject: [PATCH] daemon: Sanitize the GET /rooms/{room_id}/messages filters as well. Fractal started to apply filters on their scroll-back requests, this sadly doesn't include encrypted messages so the scroll-back appeared to be broken for encrypted rooms. This patch modifies the filter sanitization logic, since Fractal also sends out a new filter format that we didn't support, and applies it to the GET /rooms/{room_id}/messages endpoint as well. --- pantalaimon/daemon.py | 47 ++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/pantalaimon/daemon.py b/pantalaimon/daemon.py index 8ad2b93..0e1bd97 100755 --- a/pantalaimon/daemon.py +++ b/pantalaimon/daemon.py @@ -411,29 +411,34 @@ class ProxyDaemon: return access_token + def sanitize_subfilter(self, request_filter: Dict[Any, Any]): + types_filter = request_filter.get("types", None) + + if types_filter: + if "m.room.encrypted" not in types_filter: + types_filter.append("m.room.encrypted") + + not_types_filter = request_filter.get("not_types", None) + + if not_types_filter: + try: + not_types_filter.remove("m.room.encrypted") + except ValueError: + pass + def sanitize_filter(self, sync_filter): # type: (Dict[Any, Any]) -> Dict[Any, Any] """Make sure that a filter isn't filtering encrypted messages.""" sync_filter = dict(sync_filter) room_filter = sync_filter.get("room", None) + self.sanitize_subfilter(sync_filter) + if room_filter: timeline_filter = room_filter.get("timeline", None) if timeline_filter: - types_filter = timeline_filter.get("types", None) - - if types_filter: - if "m.room.encrypted" not in types_filter: - types_filter.append("m.room.encrypted") - - not_types_filter = timeline_filter.get("not_types", None) - - if not_types_filter: - try: - not_types_filter.remove("m.room.encrypted") - except ValueError: - pass + self.sanitize_subfilter(timeline_filter) return sync_filter @@ -763,8 +768,22 @@ class ProxyDaemon: if not client: return self._unknown_token + request_filter = request.query.get("filter", None) + query = CIMultiDict(request.query) + + if request_filter: + try: + request_filter = json.loads(request_filter) + except (JSONDecodeError, TypeError): + pass + + if isinstance(request_filter, dict): + request_filter = json.dumps(self.sanitize_filter(request_filter)) + + query["filter"] = request_filter + try: - response = await self.forward_request(request) + response = await self.forward_request(request, params=query) except ClientConnectionError as e: return web.Response(status=500, text=str(e))