Skip to content
This repository was archived by the owner on Mar 26, 2024. It is now read-only.

Commit f194caa

Browse files
update read_marker so receipts aren't sent to large rooms
1 parent 143af15 commit f194caa

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

synapse/rest/client/read_marker.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import logging
1616
from typing import TYPE_CHECKING, Tuple
1717

18-
from synapse.api.constants import ReceiptTypes
18+
from synapse.api.constants import RECEIPTS_MAX_ROOM_SIZE, ReceiptTypes
1919
from synapse.http.server import HttpServer
2020
from synapse.http.servlet import RestServlet, parse_json_object_from_request
2121
from synapse.http.site import SynapseRequest
@@ -38,6 +38,7 @@ def __init__(self, hs: "HomeServer"):
3838
self.config = hs.config
3939
self.receipts_handler = hs.get_receipts_handler()
4040
self.read_marker_handler = hs.get_read_marker_handler()
41+
self.store = hs.get_datastores().main
4142
self.presence_handler = hs.get_presence_handler()
4243

4344
self._known_receipt_types = {
@@ -55,6 +56,14 @@ async def on_POST(
5556

5657
body = parse_json_object_from_request(request)
5758

59+
# Beeper: we don't want to send read receipts to large rooms,
60+
# so we convert messages to private, that are over RECEIPT_MAX_ROOM_SIZE.
61+
if ReceiptTypes.READ in body:
62+
num_users = await self.store.get_number_joined_users_in_room(room_id)
63+
if num_users > RECEIPTS_MAX_ROOM_SIZE:
64+
body[ReceiptTypes.READ_PRIVATE] = body[ReceiptTypes.READ]
65+
del body[ReceiptTypes.READ]
66+
5867
unrecognized_types = set(body.keys()) - self._known_receipt_types
5968
if unrecognized_types:
6069
# It's fine if there are unrecognized receipt types, but let's log

tests/rest/client/test_sync.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,53 @@ def test_read_receipt_not_sent_to_large_rooms(self) -> None:
530530
# Test that we didn't get a read receipt.
531531
self.assertIsNone(self._get_read_receipt())
532532

533+
def test_read_marker_doesnt_send_receipt_to_large_rooms(self) -> None:
534+
# Beeper: we don't send read receipts on rooms with over 100 users
535+
# add another 100 users to the room
536+
for i in range(RECEIPTS_MAX_ROOM_SIZE):
537+
user = self.register_user(f"user_{i}", f"secure_password_{i}")
538+
tok = self.login(f"user_{i}", f"secure_password_{i}")
539+
self.helper.join(room=self.room_id, user=user, tok=tok)
540+
541+
res = self.helper.send(
542+
self.room_id, body="woah, this is a big room!", tok=self.tok
543+
)
544+
545+
# Send a read receipt
546+
channel = self.make_request(
547+
"POST",
548+
f"/rooms/{self.room_id}/read_markers",
549+
{
550+
ReceiptTypes.FULLY_READ: res["event_id"],
551+
ReceiptTypes.READ: res["event_id"],
552+
},
553+
access_token=self.tok2,
554+
)
555+
556+
self.assertEqual(channel.code, 200, channel.json_body)
557+
# Test that we didn't get a read receipt.
558+
self.assertIsNone(self._get_read_receipt())
559+
560+
def test_read_marker_does_send_receipt_to_small_rooms(self) -> None:
561+
res = self.helper.send(
562+
self.room_id, body="woah, this is room is tiny!", tok=self.tok
563+
)
564+
565+
# Send a read receipt
566+
channel = self.make_request(
567+
"POST",
568+
f"/rooms/{self.room_id}/read_markers",
569+
{
570+
ReceiptTypes.FULLY_READ: res["event_id"],
571+
ReceiptTypes.READ: res["event_id"],
572+
},
573+
access_token=self.tok2,
574+
)
575+
576+
self.assertEqual(channel.code, 200, channel.json_body)
577+
# Test that we didn't get a read receipt.
578+
self.assertIsNotNone(self._get_read_receipt())
579+
533580
def _get_read_receipt(self) -> Optional[JsonDict]:
534581
"""Syncs and returns the read receipt."""
535582

0 commit comments

Comments
 (0)