@@ -16,7 +16,9 @@ use std::{collections::BTreeMap, sync::Arc, time::Duration};
16
16
17
17
use futures_core:: Stream ;
18
18
use futures_util:: { pin_mut, StreamExt } ;
19
- use matrix_sdk_base:: { crypto:: store:: types:: RoomKeyBundleInfo , RoomState } ;
19
+ use matrix_sdk_base:: {
20
+ crypto:: store:: types:: RoomKeyBundleInfo , InviteAcceptanceDetails , RoomState ,
21
+ } ;
20
22
use matrix_sdk_common:: failures_cache:: FailuresCache ;
21
23
use ruma:: {
22
24
events:: room:: encrypted:: { EncryptedEventScheme , OriginalSyncRoomEncryptedEvent } ,
@@ -441,20 +443,40 @@ impl BundleReceiverTask {
441
443
}
442
444
}
443
445
444
- fn should_accept_bundle ( room : & Room , _bundle_info : & RoomKeyBundleInfo ) -> bool {
445
- // TODO: Check that the person that invited us to this room is the same as the
446
- // sender, of the bundle. Otherwise don't ignore the bundle.
447
- // TODO: Check that we joined the room "recently". (How do you do this if you
448
- // accept the invite on another client? I guess we remember when the transition
449
- // from Invited to Joined happened, but can't the server force us into a joined
450
- // state if we do this?
451
- room. state ( ) == RoomState :: Joined
446
+ fn should_accept_bundle ( room : & Room , bundle_info : & RoomKeyBundleInfo ) -> bool {
447
+ // We accept historic room key bundles up to one day after we have accepted an
448
+ // invite.
449
+ const DAY : Duration = Duration :: from_secs ( 24 * 60 * 60 ) ;
450
+
451
+ // If we don't have any invite acceptance details, then this client wasn't the
452
+ // one that accepted the invite.
453
+ let Some ( InviteAcceptanceDetails { invite_accepted_at, inviter } ) =
454
+ room. invite_acceptance_details ( )
455
+ else {
456
+ return false ;
457
+ } ;
458
+
459
+ let state = room. state ( ) ;
460
+ let elapsed_since_join = invite_accepted_at. to_system_time ( ) . and_then ( |t| t. elapsed ( ) . ok ( ) ) ;
461
+ let bundle_sender = & bundle_info. sender ;
462
+
463
+ match ( state, elapsed_since_join) {
464
+ ( RoomState :: Joined , Some ( elapsed_since_join) ) => {
465
+ elapsed_since_join < DAY && bundle_sender == & inviter
466
+ }
467
+ ( RoomState :: Joined , None ) => false ,
468
+ ( RoomState :: Left | RoomState :: Invited | RoomState :: Knocked | RoomState :: Banned , _) => {
469
+ false
470
+ }
471
+ }
452
472
}
453
473
}
454
474
455
475
#[ cfg( all( test, not( target_family = "wasm" ) ) ) ]
456
476
mod test {
457
- use matrix_sdk_test:: { async_test, InvitedRoomBuilder , JoinedRoomBuilder } ;
477
+ use matrix_sdk_test:: {
478
+ async_test, event_factory:: EventFactory , InvitedRoomBuilder , JoinedRoomBuilder ,
479
+ } ;
458
480
use ruma:: { event_id, room_id, user_id} ;
459
481
use serde_json:: json;
460
482
use wiremock:: MockServer ;
@@ -524,28 +546,51 @@ mod test {
524
546
#[ async_test]
525
547
async fn test_should_accept_bundle ( ) {
526
548
let server = MatrixMockServer :: new ( ) . await ;
527
- let client = server. client_builder ( ) . logged_in_with_oauth ( ) . build ( ) . await ;
528
549
529
- let user_id = user_id ! ( "@alice:localhost" ) ;
550
+ let alice_user_id = user_id ! ( "@alice:localhost" ) ;
551
+ let bob_user_id = user_id ! ( "@bob:localhost" ) ;
530
552
let joined_room_id = room_id ! ( "!joined:localhost" ) ;
531
553
let invited_rom_id = room_id ! ( "!invited:localhost" ) ;
532
554
555
+ let client = server
556
+ . client_builder ( )
557
+ . logged_in_with_token ( "ABCD" . to_owned ( ) , alice_user_id. into ( ) , "DEVICEID" . into ( ) )
558
+ . build ( )
559
+ . await ;
560
+
561
+ let event_factory = EventFactory :: new ( ) . room ( invited_rom_id) ;
562
+ let bob_member_event = event_factory. member ( bob_user_id) . into_raw_timeline ( ) ;
563
+ let alice_member_event =
564
+ event_factory. member ( bob_user_id) . invited ( alice_user_id) . into_raw_timeline ( ) ;
565
+
533
566
server
534
567
. mock_sync ( )
535
568
. ok_and_run ( & client, |builder| {
536
- builder
537
- . add_joined_room ( JoinedRoomBuilder :: new ( joined_room_id) )
538
- . add_invited_room ( InvitedRoomBuilder :: new ( invited_rom_id) ) ;
569
+ builder. add_joined_room ( JoinedRoomBuilder :: new ( joined_room_id) ) . add_invited_room (
570
+ InvitedRoomBuilder :: new ( invited_rom_id)
571
+ . add_state_event ( bob_member_event. cast ( ) )
572
+ . add_state_event ( alice_member_event. cast ( ) ) ,
573
+ ) ;
539
574
} )
540
575
. await ;
541
576
542
577
let room =
543
578
client. get_room ( joined_room_id) . expect ( "We should have access to our joined room now" ) ;
544
579
545
- let bundle_info =
546
- RoomKeyBundleInfo { sender : user_id. to_owned ( ) , room_id : joined_room_id. to_owned ( ) } ;
580
+ assert ! (
581
+ room. invite_acceptance_details( ) . is_none( ) ,
582
+ "We shouldn't have any invite acceptance details if we didn't join the room on this Client"
583
+ ) ;
584
+
585
+ let bundle_info = RoomKeyBundleInfo {
586
+ sender : bob_user_id. to_owned ( ) ,
587
+ room_id : joined_room_id. to_owned ( ) ,
588
+ } ;
547
589
548
- assert ! ( BundleReceiverTask :: should_accept_bundle( & room, & bundle_info) ) ;
590
+ assert ! (
591
+ !BundleReceiverTask :: should_accept_bundle( & room, & bundle_info) ,
592
+ "We should not acceept a bundle if we did not join the room from this Client"
593
+ ) ;
549
594
550
595
let invited_room =
551
596
client. get_room ( invited_rom_id) . expect ( "We should have access to our invited room now" ) ;
@@ -555,7 +600,21 @@ mod test {
555
600
"We should not accept a bundle if we didn't join the room."
556
601
) ;
557
602
558
- // TODO: Add more cases here once we figure out the correct acceptance
559
- // rules.
603
+ server. mock_room_join ( invited_rom_id) . ok ( ) . mock_once ( ) . mount ( ) . await ;
604
+
605
+ let room = client
606
+ . join_room_by_id ( invited_rom_id)
607
+ . await
608
+ . expect ( "We should be able to join the invited room" ) ;
609
+
610
+ let details = room
611
+ . invite_acceptance_details ( )
612
+ . expect ( "We should have stored the invite acceptance details" ) ;
613
+ assert_eq ! ( details. inviter, bob_user_id, "We should have recorded that Bob has invited us" ) ;
614
+
615
+ assert ! (
616
+ BundleReceiverTask :: should_accept_bundle( & room, & bundle_info) ,
617
+ "We should accept a bundle if we just joined the room and did so from this very Client object"
618
+ ) ;
560
619
}
561
620
}
0 commit comments