@@ -27,6 +27,7 @@ use tracing::{debug, instrument, trace};
2727use super :: OutboundGroupSession ;
2828use crate :: {
2929 error:: { OlmResult , SessionRecipientCollectionError } ,
30+ olm:: ShareInfo ,
3031 store:: Store ,
3132 DeviceData , EncryptionSettings , LocalTrust , OlmError , OwnUserIdentityData , UserIdentityData ,
3233} ;
@@ -433,7 +434,11 @@ fn is_session_overshared_for_user(
433434 } ;
434435
435436 // Devices that received this session
436- let shared: BTreeSet < & DeviceId > = shared. keys ( ) . map ( |d| d. as_ref ( ) ) . collect ( ) ;
437+ let shared: BTreeSet < & DeviceId > = shared
438+ . iter ( )
439+ . filter ( |( _, info) | matches ! ( info, ShareInfo :: Shared ( _) ) )
440+ . map ( |( d, _) | d. as_ref ( ) )
441+ . collect ( ) ;
437442
438443 // The set difference between
439444 //
@@ -2095,9 +2100,55 @@ mod tests {
20952100 let machine = test_machine ( ) . await ;
20962101 import_known_users_to_test_machine ( & machine) . await ;
20972102
2098- let fake_room_id = room_id ! ( "!roomid:localhost" ) ;
20992103 let encryption_settings = all_devices_strategy_settings ( ) ;
2104+ let group_session = create_test_outbound_group_session ( & machine, & encryption_settings) ;
2105+ let sender_key = machine. identity_keys ( ) . curve25519 ;
2106+
2107+ group_session
2108+ . mark_shared_with (
2109+ KeyDistributionTestData :: dan_id ( ) ,
2110+ KeyDistributionTestData :: dan_signed_device_id ( ) ,
2111+ sender_key,
2112+ )
2113+ . await ;
2114+ group_session
2115+ . mark_shared_with (
2116+ KeyDistributionTestData :: dan_id ( ) ,
2117+ KeyDistributionTestData :: dan_unsigned_device_id ( ) ,
2118+ sender_key,
2119+ )
2120+ . await ;
2121+
2122+ // Try to share again after dan has removed one of his devices
2123+ let keys_query = KeyDistributionTestData :: dan_keys_query_response_device_loggedout ( ) ;
2124+ machine. mark_request_as_sent ( & TransactionId :: new ( ) , & keys_query) . await . unwrap ( ) ;
21002125
2126+ // share again
2127+ let share_result = collect_session_recipients (
2128+ machine. store ( ) ,
2129+ vec ! [ KeyDistributionTestData :: dan_id( ) ] . into_iter ( ) ,
2130+ & encryption_settings,
2131+ & group_session,
2132+ )
2133+ . await
2134+ . unwrap ( ) ;
2135+
2136+ assert ! ( share_result. should_rotate) ;
2137+ }
2138+
2139+ /// Test that the session is not rotated if a devices is removed
2140+ /// but was already withheld from receiving the session.
2141+ #[ async_test]
2142+ async fn test_should_not_rotate_if_keys_were_withheld ( ) {
2143+ let machine = test_machine ( ) . await ;
2144+ import_known_users_to_test_machine ( & machine) . await ;
2145+
2146+ let encryption_settings = all_devices_strategy_settings ( ) ;
2147+ let group_session = create_test_outbound_group_session ( & machine, & encryption_settings) ;
2148+ let fake_room_id = group_session. room_id ( ) ;
2149+
2150+ // Because we don't have Olm sessions initialized, this will contain
2151+ // withheld requests for both of Dan's devices
21012152 let requests = machine
21022153 . share_room_key (
21032154 fake_room_id,
@@ -2115,13 +2166,11 @@ mod tests {
21152166 . await
21162167 . unwrap ( ) ;
21172168 }
2169+
21182170 // Try to share again after dan has removed one of his devices
21192171 let keys_query = KeyDistributionTestData :: dan_keys_query_response_device_loggedout ( ) ;
2120- let txn_id = TransactionId :: new ( ) ;
2121- machine. mark_request_as_sent ( & txn_id, & keys_query) . await . unwrap ( ) ;
2172+ machine. mark_request_as_sent ( & TransactionId :: new ( ) , & keys_query) . await . unwrap ( ) ;
21222173
2123- let group_session =
2124- machine. store ( ) . get_outbound_group_session ( fake_room_id) . await . unwrap ( ) . unwrap ( ) ;
21252174 // share again
21262175 let share_result = collect_session_recipients (
21272176 machine. store ( ) ,
@@ -2132,7 +2181,7 @@ mod tests {
21322181 . await
21332182 . unwrap ( ) ;
21342183
2135- assert ! ( share_result. should_rotate) ;
2184+ assert ! ( ! share_result. should_rotate) ;
21362185 }
21372186
21382187 /// Common setup for tests which require a verified user to have unsigned
0 commit comments