@@ -165,43 +165,69 @@ def __init__(self, hs: "HomeServer"):
165
165
self .config = hs .config
166
166
167
167
@staticmethod
168
- def filter_out_private (events : List [JsonDict ], user_id : str ) -> List [JsonDict ]:
168
+ def filter_out_private_receipts (
169
+ rooms : List [JsonDict ], user_id : str
170
+ ) -> List [JsonDict ]:
169
171
"""
170
- This method takes in what is returned by
171
- get_linearized_receipts_for_rooms() and goes through read receipts
172
- filtering out m.read.private receipts if they were not sent by the
173
- current user.
174
- """
175
-
176
- visible_events = []
172
+ Filters a list of serialized receipts (as returned by /sync and /initialSync)
173
+ and removes private read receipts of other users.
177
174
178
- # filter out private receipts the user shouldn't see
179
- for event in events :
180
- content = event .get ("content" , {})
181
- new_event = event .copy ()
182
- new_event ["content" ] = {}
175
+ This operates on the return value of get_linearized_receipts_for_rooms(),
176
+ which is wrapped in a cache. Care must be taken to ensure that the input
177
+ values are not modified.
183
178
184
- for event_id , event_content in content .items ():
185
- receipt_event = {}
186
- for receipt_type , receipt_content in event_content .items ():
187
- if receipt_type == ReceiptTypes .READ_PRIVATE :
188
- user_rr = receipt_content .get (user_id , None )
189
- if user_rr :
190
- receipt_event [ReceiptTypes .READ_PRIVATE ] = {
191
- user_id : user_rr .copy ()
192
- }
193
- else :
194
- receipt_event [receipt_type ] = receipt_content .copy ()
195
-
196
- # Only include the receipt event if it is non-empty.
197
- if receipt_event :
198
- new_event ["content" ][event_id ] = receipt_event
179
+ Args:
180
+ rooms: A list of mappings, each mapping has a `content` field, which
181
+ is a map of event ID -> receipt type -> user ID -> receipt information.
199
182
200
- # Append new_event to visible_events unless empty
201
- if len ( new_event [ "content" ]. keys ()) > 0 :
202
- visible_events . append ( new_event )
183
+ Returns:
184
+ The same as rooms, but filtered.
185
+ """
203
186
204
- return visible_events
187
+ result = []
188
+
189
+ # Iterate through each room's receipt content.
190
+ for room in rooms :
191
+ # The receipt content with other user's private read receipts removed.
192
+ content = {}
193
+
194
+ # Iterate over each event ID / receipts for that event.
195
+ for event_id , orig_event_content in room .get ("content" , {}).items ():
196
+ event_content = orig_event_content
197
+ # If there are private read receipts, additional logic is necessary.
198
+ if ReceiptTypes .READ_PRIVATE in event_content :
199
+ # Make a copy without private read receipts to avoid leaking
200
+ # other user's private read receipts..
201
+ event_content = {
202
+ receipt_type : receipt_value
203
+ for receipt_type , receipt_value in event_content .items ()
204
+ if receipt_type != ReceiptTypes .READ_PRIVATE
205
+ }
206
+
207
+ # Copy the current user's private read receipt from the
208
+ # original content, if it exists.
209
+ user_private_read_receipt = orig_event_content [
210
+ ReceiptTypes .READ_PRIVATE
211
+ ].get (user_id , None )
212
+ if user_private_read_receipt :
213
+ event_content [ReceiptTypes .READ_PRIVATE ] = {
214
+ user_id : user_private_read_receipt
215
+ }
216
+
217
+ # Include the event if there is at least one non-private read
218
+ # receipt or the current user has a private read receipt.
219
+ if event_content :
220
+ content [event_id ] = event_content
221
+
222
+ # Include the event if there is at least one non-private read receipt
223
+ # or the current user has a private read receipt.
224
+ if content :
225
+ # Build a new event to avoid mutating the cache.
226
+ new_room = {k : v for k , v in room .items () if k != "content" }
227
+ new_room ["content" ] = content
228
+ result .append (new_room )
229
+
230
+ return result
205
231
206
232
async def get_new_events (
207
233
self ,
@@ -223,7 +249,9 @@ async def get_new_events(
223
249
)
224
250
225
251
if self .config .experimental .msc2285_enabled :
226
- events = ReceiptEventSource .filter_out_private (events , user .to_string ())
252
+ events = ReceiptEventSource .filter_out_private_receipts (
253
+ events , user .to_string ()
254
+ )
227
255
228
256
return events , to_key
229
257
0 commit comments