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

Commit c24af08

Browse files
committed
Implement changes to MSC2285
Signed-off-by: Šimon Brandner <[email protected]>
1 parent 158e093 commit c24af08

File tree

6 files changed

+88
-99
lines changed

6 files changed

+88
-99
lines changed

synapse/api/constants.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,5 @@ class GuestAccess:
255255

256256
class ReceiptTypes:
257257
READ: Final = "m.read"
258-
259-
260-
class ReadReceiptEventFields:
261-
MSC2285_HIDDEN: Final = "org.matrix.msc2285.hidden"
258+
READ_PRIVATE: Final = "org.matrix.msc2285.read.private"
259+
FULLY_READ: Final = "m.fully_read"

synapse/handlers/receipts.py

+19-29
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import logging
1515
from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple
1616

17-
from synapse.api.constants import ReadReceiptEventFields, ReceiptTypes
17+
from synapse.api.constants import ReceiptTypes
1818
from synapse.appservice import ApplicationService
1919
from synapse.streams import EventSource
2020
from synapse.types import JsonDict, ReadReceipt, UserID, get_domain_from_id
@@ -138,7 +138,7 @@ async def _handle_new_receipts(self, receipts: List[ReadReceipt]) -> bool:
138138
return True
139139

140140
async def received_client_receipt(
141-
self, room_id: str, receipt_type: str, user_id: str, event_id: str, hidden: bool
141+
self, room_id: str, receipt_type: str, user_id: str, event_id: str
142142
) -> None:
143143
"""Called when a client tells us a local user has read up to the given
144144
event_id in the room.
@@ -148,15 +148,15 @@ async def received_client_receipt(
148148
receipt_type=receipt_type,
149149
user_id=user_id,
150150
event_ids=[event_id],
151-
data={"ts": int(self.clock.time_msec()), "hidden": hidden},
151+
data={"ts": int(self.clock.time_msec())},
152152
)
153153

154154
is_new = await self._handle_new_receipts([receipt])
155155
if not is_new:
156156
return
157157

158158
if self.federation_sender and not (
159-
self.hs.config.experimental.msc2285_enabled and hidden
159+
self.hs.config.experimental.msc2285_enabled and receipt_type == ReceiptTypes.READ_PRIVATE
160160
):
161161
await self.federation_sender.send_read_receipt(receipt)
162162

@@ -178,35 +178,25 @@ def filter_out_hidden(events: List[JsonDict], user_id: str) -> List[JsonDict]:
178178

179179
for event_id in content.keys():
180180
event_content = content.get(event_id, {})
181-
m_read = event_content.get(ReceiptTypes.READ, {})
182181

183-
# If m_read is missing copy over the original event_content as there is nothing to process here
184-
if not m_read:
185-
new_event["content"][event_id] = event_content.copy()
182+
m_read = event_content.get(ReceiptTypes.READ, None)
183+
if m_read:
184+
new_event["content"][event_id] = {ReceiptTypes.READ: m_read}
186185
continue
187186

188-
new_users = {}
189-
for rr_user_id, user_rr in m_read.items():
190-
try:
191-
hidden = user_rr.get("hidden")
192-
except AttributeError:
193-
# Due to https://github.com/matrix-org/synapse/issues/10376
194-
# there are cases where user_rr is a string, in those cases
195-
# we just ignore the read receipt
196-
continue
187+
m_read_private = event_content.get(ReceiptTypes.READ_PRIVATE, None)
188+
if m_read_private:
189+
new_users = {}
190+
for rr_user_id, user_rr in m_read_private.items():
191+
if rr_user_id == user_id:
192+
new_users[rr_user_id] = user_rr.copy()
193+
194+
# Set new users unless empty
195+
if len(new_users.keys()) > 0:
196+
new_event["content"][event_id] = {ReceiptTypes.READ_PRIVATE: new_users}
197+
continue
197198

198-
if hidden is not True or rr_user_id == user_id:
199-
new_users[rr_user_id] = user_rr.copy()
200-
# If hidden has a value replace hidden with the correct prefixed key
201-
if hidden is not None:
202-
new_users[rr_user_id].pop("hidden")
203-
new_users[rr_user_id][
204-
ReadReceiptEventFields.MSC2285_HIDDEN
205-
] = hidden
206-
207-
# Set new users unless empty
208-
if len(new_users.keys()) > 0:
209-
new_event["content"][event_id] = {ReceiptTypes.READ: new_users}
199+
new_event["content"][event_id] = event_content
210200

211201
# Append new_event to visible_events unless empty
212202
if len(new_event["content"].keys()) > 0:

synapse/rest/client/read_marker.py

+12-13
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 ReadReceiptEventFields, ReceiptTypes
18+
from synapse.api.constants import ReceiptTypes
1919
from synapse.api.errors import Codes, SynapseError
2020
from synapse.http.server import HttpServer
2121
from synapse.http.servlet import RestServlet, parse_json_object_from_request
@@ -48,27 +48,26 @@ async def on_POST(
4848
await self.presence_handler.bump_presence_active_time(requester.user)
4949

5050
body = parse_json_object_from_request(request)
51-
read_event_id = body.get(ReceiptTypes.READ, None)
52-
hidden = body.get(ReadReceiptEventFields.MSC2285_HIDDEN, False)
53-
54-
if not isinstance(hidden, bool):
55-
raise SynapseError(
56-
400,
57-
"Param %s must be a boolean, if given"
58-
% ReadReceiptEventFields.MSC2285_HIDDEN,
59-
Codes.BAD_JSON,
60-
)
6151

52+
read_event_id = body.get(ReceiptTypes.READ, None)
6253
if read_event_id:
6354
await self.receipts_handler.received_client_receipt(
6455
room_id,
6556
ReceiptTypes.READ,
6657
user_id=requester.user.to_string(),
6758
event_id=read_event_id,
68-
hidden=hidden,
6959
)
7060

71-
read_marker_event_id = body.get("m.fully_read", None)
61+
read_private_event_id = body.get(ReceiptTypes.READ_PRIVATE, None)
62+
if read_private_event_id:
63+
await self.receipts_handler.received_client_receipt(
64+
room_id,
65+
ReceiptTypes.READ_PRIVATE,
66+
user_id=requester.user.to_string(),
67+
event_id=read_private_event_id,
68+
)
69+
70+
read_marker_event_id = body.get(ReceiptTypes.FULLY_READ, None)
7271
if read_marker_event_id:
7372
await self.read_marker_handler.received_client_read_marker(
7473
room_id,

synapse/rest/client/receipts.py

+17-19
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import re
1717
from typing import TYPE_CHECKING, Tuple
1818

19-
from synapse.api.constants import ReadReceiptEventFields, ReceiptTypes
19+
from synapse.api.constants import ReceiptTypes
2020
from synapse.api.errors import Codes, SynapseError
2121
from synapse.http import get_request_user_agent
2222
from synapse.http.server import HttpServer
@@ -46,15 +46,16 @@ def __init__(self, hs: "HomeServer"):
4646
self.hs = hs
4747
self.auth = hs.get_auth()
4848
self.receipts_handler = hs.get_receipts_handler()
49+
self.read_marker_handler = hs.get_read_marker_handler()
4950
self.presence_handler = hs.get_presence_handler()
5051

5152
async def on_POST(
5253
self, request: SynapseRequest, room_id: str, receipt_type: str, event_id: str
5354
) -> Tuple[int, JsonDict]:
5455
requester = await self.auth.get_user_by_req(request)
5556

56-
if receipt_type != ReceiptTypes.READ:
57-
raise SynapseError(400, "Receipt type must be 'm.read'")
57+
if receipt_type in [ReceiptTypes.READ, ReceiptTypes.READ_PRIVATE, ReceiptTypes.FULLY_READ]:
58+
raise SynapseError(400, "Receipt type must be 'm.read', 'm.read.private' or 'm.fully_read'")
5859

5960
# Do not allow older SchildiChat and Element Android clients (prior to Element/1.[012].x) to send an empty body.
6061
user_agent = get_request_user_agent(request)
@@ -63,25 +64,22 @@ async def on_POST(
6364
if pattern.match(user_agent) or "Riot" in user_agent:
6465
allow_empty_body = True
6566
body = parse_json_object_from_request(request, allow_empty_body)
66-
hidden = body.get(ReadReceiptEventFields.MSC2285_HIDDEN, False)
67-
68-
if not isinstance(hidden, bool):
69-
raise SynapseError(
70-
400,
71-
"Param %s must be a boolean, if given"
72-
% ReadReceiptEventFields.MSC2285_HIDDEN,
73-
Codes.BAD_JSON,
74-
)
7567

7668
await self.presence_handler.bump_presence_active_time(requester.user)
7769

78-
await self.receipts_handler.received_client_receipt(
79-
room_id,
80-
receipt_type,
81-
user_id=requester.user.to_string(),
82-
event_id=event_id,
83-
hidden=hidden,
84-
)
70+
if receipt_type == ReceiptTypes.FULLY_READ:
71+
await self.read_marker_handler.received_client_read_marker(
72+
room_id,
73+
user_id=requester.user.to_string(),
74+
event_id=read_marker_event_id,
75+
)
76+
else:
77+
await self.receipts_handler.received_client_receipt(
78+
room_id,
79+
receipt_type,
80+
user_id=requester.user.to_string(),
81+
event_id=event_id,
82+
)
8583

8684
return 200, {}
8785

0 commit comments

Comments
 (0)