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

Commit eda1847

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

File tree

6 files changed

+98
-100
lines changed

6 files changed

+98
-100
lines changed

synapse/api/constants.py

Lines changed: 2 additions & 4 deletions
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

Lines changed: 22 additions & 29 deletions
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,16 @@ 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
160+
and receipt_type == ReceiptTypes.READ_PRIVATE
160161
):
161162
await self.federation_sender.send_read_receipt(receipt)
162163

@@ -178,35 +179,27 @@ def filter_out_hidden(events: List[JsonDict], user_id: str) -> List[JsonDict]:
178179

179180
for event_id in content.keys():
180181
event_content = content.get(event_id, {})
181-
m_read = event_content.get(ReceiptTypes.READ, {})
182182

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()
183+
m_read = event_content.get(ReceiptTypes.READ, None)
184+
if m_read:
185+
new_event["content"][event_id] = {ReceiptTypes.READ: m_read}
186186
continue
187187

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
188+
m_read_private = event_content.get(ReceiptTypes.READ_PRIVATE, None)
189+
if m_read_private:
190+
new_users = {}
191+
for rr_user_id, user_rr in m_read_private.items():
192+
if rr_user_id == user_id:
193+
new_users[rr_user_id] = user_rr.copy()
194+
195+
# Set new users unless empty
196+
if len(new_users.keys()) > 0:
197+
new_event["content"][event_id] = {
198+
ReceiptTypes.READ_PRIVATE: new_users
199+
}
200+
continue
197201

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}
202+
new_event["content"][event_id] = event_content
210203

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

synapse/rest/client/read_marker.py

Lines changed: 12 additions & 13 deletions
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

Lines changed: 23 additions & 19 deletions
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,22 @@ 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 [
58+
ReceiptTypes.READ,
59+
ReceiptTypes.READ_PRIVATE,
60+
ReceiptTypes.FULLY_READ,
61+
]:
62+
raise SynapseError(
63+
400, "Receipt type must be 'm.read', 'm.read.private' or 'm.fully_read'"
64+
)
5865

5966
# Do not allow older SchildiChat and Element Android clients (prior to Element/1.[012].x) to send an empty body.
6067
user_agent = get_request_user_agent(request)
@@ -63,25 +70,22 @@ async def on_POST(
6370
if pattern.match(user_agent) or "Riot" in user_agent:
6471
allow_empty_body = True
6572
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-
)
7573

7674
await self.presence_handler.bump_presence_active_time(requester.user)
7775

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-
)
76+
if receipt_type == ReceiptTypes.FULLY_READ:
77+
await self.read_marker_handler.received_client_read_marker(
78+
room_id,
79+
user_id=requester.user.to_string(),
80+
event_id=read_marker_event_id,
81+
)
82+
else:
83+
await self.receipts_handler.received_client_receipt(
84+
room_id,
85+
receipt_type,
86+
user_id=requester.user.to_string(),
87+
event_id=event_id,
88+
)
8589

8690
return 200, {}
8791

0 commit comments

Comments
 (0)