@@ -228,6 +228,8 @@ impl MatrixDriver {
228
228
// not (as per MSC3819).
229
229
move |raw : Raw < AnyToDeviceEvent > , encryption_info : Option < EncryptionInfo > | {
230
230
// Only sent encrypted to-device events
231
+ // TODO only if the room is enxrypted
232
+ // self.room.
231
233
if encryption_info. is_some ( ) {
232
234
let _ = tx. send ( raw) ;
233
235
}
@@ -252,44 +254,30 @@ impl MatrixDriver {
252
254
) -> Result < send_event_to_device:: v3:: Response > {
253
255
let client = self . room . client ( ) ;
254
256
257
+ // TODO: always encrypt based on the room encryption event
258
+ // Temporarly just log that the encryption flag is deprecated.
259
+ // TODO make encrypted a Option<bool>
255
260
let request = if encrypted {
256
261
// We first want to get all missing session before we start any to device
257
262
// sending!
258
- client. claim_one_time_keys ( messages. keys ( ) . map ( |u| u. as_ref ( ) ) ) . await ?;
259
- let encrypted_content: BTreeMap <
263
+ // TODO transform this into an array of devicesLists per content.
264
+
265
+ let responses: BTreeMap <
260
266
OwnedUserId ,
261
267
BTreeMap < DeviceIdOrAllDevices , Raw < AnyToDeviceEventContent > > ,
262
268
> = join_all ( messages. into_iter ( ) . map ( |( user_id, device_content_map) | {
269
+ // TODO maybe group by content.
263
270
let event_type = event_type. clone ( ) ;
264
271
async move {
265
- (
266
- user_id. clone ( ) ,
267
- to_device_crypto:: encrypted_device_content_map (
268
- & self . room . client ( ) ,
269
- & user_id,
270
- & event_type,
271
- device_content_map,
272
- )
273
- . await ,
274
- )
272
+ client. encryption ( ) . send_raw_to_device ( devices, event_type, content) ;
275
273
}
276
274
} ) )
277
275
. await
278
276
. into_iter ( )
279
277
. collect ( ) ;
280
-
281
- RumaToDeviceRequest :: new_raw (
282
- ToDeviceEventType :: RoomEncrypted ,
283
- TransactionId :: new ( ) ,
284
- encrypted_content,
285
- )
286
- } else {
287
- RumaToDeviceRequest :: new_raw ( event_type, TransactionId :: new ( ) , messages)
278
+ //TODO do sth with the responsesn
279
+ response. map_err ( Into :: into)
288
280
} ;
289
-
290
- let response = client. send ( request) . await ;
291
-
292
- response. map_err ( Into :: into)
293
281
}
294
282
}
295
283
@@ -312,117 +300,6 @@ fn attach_room_id(raw_ev: &Raw<AnySyncTimelineEvent>, room_id: &RoomId) -> Raw<A
312
300
Raw :: new ( & ev_obj) . unwrap ( ) . cast ( )
313
301
}
314
302
315
- /// Move this into the `matrix_crypto` crate!
316
- /// This module contains helper functions to encrypt to device events.
317
- mod to_device_crypto {
318
- use std:: collections:: BTreeMap ;
319
-
320
- use futures_util:: future:: join_all;
321
- use ruma:: {
322
- events:: { AnyToDeviceEventContent , ToDeviceEventType } ,
323
- serde:: Raw ,
324
- to_device:: DeviceIdOrAllDevices ,
325
- UserId ,
326
- } ;
327
- use serde_json:: Value ;
328
- use tracing:: { info, warn} ;
329
-
330
- use crate :: { encryption:: identities:: Device , executor:: spawn, Client , Error , Result } ;
331
-
332
- /// This encrypts to device content for a collection of devices.
333
- /// It will ignore all devices where errors occurred or where the device
334
- /// is not verified or where th user has a has_verification_violation.
335
- async fn encrypted_content_for_devices (
336
- unencrypted_content : & Raw < AnyToDeviceEventContent > ,
337
- devices : Vec < Device > ,
338
- event_type : & ToDeviceEventType ,
339
- ) -> Result < impl Iterator < Item = ( DeviceIdOrAllDevices , Raw < AnyToDeviceEventContent > ) > > {
340
- let content: Value = unencrypted_content. deserialize_as ( ) . map_err ( Into :: < Error > :: into) ?;
341
- let event_type = event_type. clone ( ) ;
342
- let device_content_tasks = devices. into_iter ( ) . map ( |device| spawn ( {
343
- let event_type = event_type. clone ( ) ;
344
- let content = content. clone ( ) ;
345
-
346
- async move {
347
- // This is not yet used. It is incompatible with the spa guest mode (the spa will not verify its crypto identity)
348
- // if !device.is_cross_signed_by_owner() {
349
- // info!("Device {} is not verified, skipping encryption", device.device_id());
350
- // return None;
351
- // }
352
- match device
353
- . inner
354
- . encrypt_event_raw ( & event_type. to_string ( ) , & content)
355
- . await {
356
- Ok ( encrypted) => Some ( ( device. device_id ( ) . to_owned ( ) . into ( ) , encrypted. cast ( ) ) ) ,
357
- Err ( e) =>{ info ! ( "Failed to encrypt to_device event from widget for device: {} because, {}" , device. device_id( ) , e) ; None } ,
358
- }
359
- }
360
- } ) ) ;
361
- let device_encrypted_content_map =
362
- join_all ( device_content_tasks) . await . into_iter ( ) . flatten ( ) . flatten ( ) ;
363
- Ok ( device_encrypted_content_map)
364
- }
365
-
366
- /// Convert the device content map for one user into the same content
367
- /// map with encrypted content This needs to flatten the vectors
368
- /// we get from `encrypted_content_for_devices`
369
- /// since one `DeviceIdOrAllDevices` id can be multiple devices.
370
- pub ( super ) async fn encrypted_device_content_map (
371
- client : & Client ,
372
- user_id : & UserId ,
373
- event_type : & ToDeviceEventType ,
374
- device_content_map : BTreeMap < DeviceIdOrAllDevices , Raw < AnyToDeviceEventContent > > ,
375
- ) -> BTreeMap < DeviceIdOrAllDevices , Raw < AnyToDeviceEventContent > > {
376
- let device_map_futures =
377
- device_content_map. into_iter ( ) . map ( |( device_or_all_id, content) | spawn ( {
378
- let client = client. clone ( ) ;
379
- let user_id = user_id. to_owned ( ) ;
380
- let event_type = event_type. clone ( ) ;
381
- async move {
382
- let Ok ( user_devices) = client. encryption ( ) . get_user_devices ( & user_id) . await else {
383
- warn ! ( "Failed to get user devices for user: {}" , user_id) ;
384
- return None ;
385
- } ;
386
- // This is not yet used. It is incompatible with the spa guest mode (the spa will not verify its crypto identity)
387
- // let Ok(user_identity) = client.encryption().get_user_identity(&user_id).await else{
388
- // warn!("Failed to get user identity for user: {}", user_id);
389
- // return None;
390
- // };
391
- // if user_identity.map(|i|i.has_verification_violation()).unwrap_or(false) {
392
- // info!("User {} has a verification violation, skipping encryption", user_id);
393
- // return None;
394
- // }
395
- let devices: Vec < Device > = match device_or_all_id {
396
- DeviceIdOrAllDevices :: DeviceId ( device_id) => {
397
- vec ! [ user_devices. get( & device_id) ] . into_iter ( ) . flatten ( ) . collect ( )
398
- }
399
- DeviceIdOrAllDevices :: AllDevices => user_devices. devices ( ) . collect ( ) ,
400
- } ;
401
- encrypted_content_for_devices (
402
- & content,
403
- devices,
404
- & event_type,
405
- )
406
- . await
407
- . map_err ( |e| info ! ( "WidgetDriver: could not encrypt content for to device widget event content: {}. because, {}" , content. json( ) , e) )
408
- . ok ( )
409
- } } ) ) ;
410
- let content_map_iterator = join_all ( device_map_futures) . await . into_iter ( ) ;
411
-
412
- // The first flatten takes the iterator over Result<Option<impl Iterator<Item =
413
- // (DeviceIdOrAllDevices, Raw<AnyToDeviceEventContent>)>>, JoinError>>
414
- // and flattens the Result (drops Err() items)
415
- // The second takes the iterator over: Option<impl Iterator<Item =
416
- // (DeviceIdOrAllDevices, Raw<AnyToDeviceEventContent>)>>
417
- // and flattens the Option (drops None items)
418
- // The third takes the iterator over iterators: impl Iterator<Item =
419
- // (DeviceIdOrAllDevices, Raw<AnyToDeviceEventContent>)>
420
- // and flattens it to just an iterator over (DeviceIdOrAllDevices,
421
- // Raw<AnyToDeviceEventContent>)
422
- content_map_iterator. flatten ( ) . flatten ( ) . flatten ( ) . collect ( )
423
- }
424
- }
425
-
426
303
#[ cfg( test) ]
427
304
mod tests {
428
305
use insta;
0 commit comments