Compare commits

...

6 Commits

Author SHA1 Message Date
Travis Ralston
c4f3e97879 Appease the linter 2019-09-05 22:10:57 -06:00
Travis Ralston
170526557f Filter out hidden read receipts from sync too 2019-09-05 21:51:53 -06:00
Travis Ralston
30f0824079 Filter out hidden read receipts for federation workers 2019-09-05 20:56:01 -06:00
Travis Ralston
27eac52813 import the important things in life 2019-09-05 20:41:54 -06:00
Travis Ralston
53cf721ede changelog 2019-09-05 20:41:10 -06:00
Travis Ralston
aab3f5d11e Support optionally not sending read receipts to other users/servers 2019-09-05 20:37:58 -06:00
7 changed files with 50 additions and 7 deletions

1
changelog.d/5990.feature Normal file
View File

@@ -0,0 +1 @@
Support a way for clients to not send read receipts to other users/servers.

View File

@@ -262,6 +262,8 @@ class FederationSenderHandler(object):
# we only want to send on receipts for our own users
if not self._is_mine_id(receipt.user_id):
continue
if receipt.data.get("hidden", False):
return # do not send over federation
receipt_info = ReadReceipt(
receipt.room_id,
receipt.receipt_type,

View File

@@ -395,7 +395,12 @@ class InitialSyncHandler(BaseHandler):
)
if not receipts:
receipts = []
return receipts
return [
r
for r in receipts
if not r.data.get("hidden", False) or r.user_id == user_id
]
presence, receipts, (messages, token) = yield make_deferred_yieldable(
defer.gatherResults(

View File

@@ -106,7 +106,7 @@ class ReceiptsHandler(BaseHandler):
return True
@defer.inlineCallbacks
def received_client_receipt(self, room_id, receipt_type, user_id, event_id):
def received_client_receipt(self, room_id, receipt_type, user_id, event_id, hidden):
"""Called when a client tells us a local user has read up to the given
event_id in the room.
"""
@@ -115,14 +115,15 @@ class ReceiptsHandler(BaseHandler):
receipt_type=receipt_type,
user_id=user_id,
event_ids=[event_id],
data={"ts": int(self.clock.time_msec())},
data={"ts": int(self.clock.time_msec()), "hidden": hidden},
)
is_new = yield self._handle_new_receipts([receipt])
if not is_new:
return
yield self.federation.send_read_receipt(receipt)
if not hidden:
yield self.federation.send_read_receipt(receipt)
@defer.inlineCallbacks
def get_receipts_for_room(self, room_id, to_key):

View File

@@ -334,6 +334,7 @@ class SyncHandler(object):
"""
sync_config = sync_result_builder.sync_config
user_id = sync_result_builder.sync_config.user.to_string()
with Measure(self.clock, "ephemeral_by_room"):
typing_key = since_token.typing_key if since_token else "0"
@@ -376,7 +377,33 @@ class SyncHandler(object):
room_id = event["room_id"]
# exclude room id, as above
event_copy = {k: v for (k, v) in iteritems(event) if k != "room_id"}
ephemeral_by_room.setdefault(room_id, []).append(event_copy)
# filter out receipts the user shouldn't see
content = event_copy.get("content", {})
event_ids = content.keys()
reconstructed = event_copy.copy()
reconstructed["content"] = {} # clear old content
for event_id in event_ids:
m_read = content[event_id].get("m.read", None)
if m_read is None:
# clone it now - it's not something we can process
reconstructed["content"][event_id] = content[event_id]
continue
user_ids = m_read.keys()
for rr_user_id in user_ids:
data = m_read[rr_user_id]
hidden = data.get("hidden", False)
if rr_user_id == user_id or not hidden:
# append the key to the reconstructed receipt
new_content = reconstructed["content"]
if new_content.get(event_id, None) is None:
new_content[event_id] = {"m.read": {}}
ev_content = new_content[event_id]["m.read"]
if ev_content.get(rr_user_id, None) is None:
ev_content[rr_user_id] = {}
ev_content[rr_user_id] = data
if len(reconstructed["content"].keys()) > 0:
ephemeral_by_room.setdefault(room_id, []).append(reconstructed)
return now_token, ephemeral_by_room

View File

@@ -49,6 +49,7 @@ class ReadMarkerRestServlet(RestServlet):
"m.read",
user_id=requester.user.to_string(),
event_id=read_event_id,
hidden=body.get("m.hidden", False),
)
read_marker_event_id = body.get("m.fully_read", None)

View File

@@ -18,7 +18,7 @@ import logging
from twisted.internet import defer
from synapse.api.errors import SynapseError
from synapse.http.servlet import RestServlet
from synapse.http.servlet import RestServlet, parse_json_object_from_request
from ._base import client_patterns
@@ -46,10 +46,16 @@ class ReceiptRestServlet(RestServlet):
if receipt_type != "m.read":
raise SynapseError(400, "Receipt type must be 'm.read'")
body = parse_json_object_from_request(request)
yield self.presence_handler.bump_presence_active_time(requester.user)
yield self.receipts_handler.received_client_receipt(
room_id, receipt_type, user_id=requester.user.to_string(), event_id=event_id
room_id,
receipt_type,
user_id=requester.user.to_string(),
event_id=event_id,
hidden=body.get("m.hidden", False),
)
return 200, {}