@@ -819,6 +819,7 @@ impl GossipMachine {
819819 //
820820 // So we put the secret into our inbox. Later users can inspect the contents of
821821 // the inbox and decide if they want to activate the backup.
822+ info ! ( "Received a backup recovery key, storing it into the secret inbox." ) ;
822823 changes. secrets . push ( secret) ;
823824 }
824825
@@ -1044,8 +1045,6 @@ mod tests {
10441045 serde:: Raw ,
10451046 user_id, DeviceId , RoomId , UserId ,
10461047 } ;
1047- #[ cfg( feature = "automatic-room-key-forwarding" ) ]
1048- use serde:: { de:: DeserializeOwned , Serialize } ;
10491048 use serde_json:: json;
10501049 use tokio:: sync:: Mutex ;
10511050
@@ -1054,16 +1053,14 @@ mod tests {
10541053 use crate :: {
10551054 gossiping:: KeyForwardDecision ,
10561055 olm:: OutboundGroupSession ,
1057- store:: Changes ,
10581056 types:: {
10591057 events:: {
10601058 forwarded_room_key:: ForwardedRoomKeyContent , olm_v1:: AnyDecryptedOlmEvent ,
1061- olm_v1:: DecryptedOlmV1Event , room:: encrypted:: EncryptedToDeviceEvent , EventType ,
1062- ToDeviceEvent ,
1059+ olm_v1:: DecryptedOlmV1Event ,
10631060 } ,
10641061 EventEncryptionAlgorithm ,
10651062 } ,
1066- EncryptionSettings , OutgoingRequest , OutgoingRequests ,
1063+ EncryptionSettings , OutgoingRequests ,
10671064 } ;
10681065 use crate :: {
10691066 identities:: { LocalTrust , ReadOnlyDevice } ,
@@ -1073,6 +1070,8 @@ mod tests {
10731070 types:: events:: room:: encrypted:: { EncryptedEvent , RoomEncryptedEventContent } ,
10741071 verification:: VerificationMachine ,
10751072 } ;
1073+ #[ cfg( any( feature = "automatic-room-key-forwarding" , feature = "backups_v1" ) ) ]
1074+ use crate :: { store:: Changes , types:: events:: room:: encrypted:: EncryptedToDeviceEvent } ;
10761075
10771076 fn alice_id ( ) -> & ' static UserId {
10781077 user_id ! ( "@alice:example.org" )
@@ -1226,10 +1225,10 @@ mod tests {
12261225 ( alice_machine, alice_account, group_session, bob_machine)
12271226 }
12281227
1229- #[ cfg( feature = "automatic-room-key-forwarding" ) ]
1228+ #[ cfg( any ( feature = "automatic-room-key-forwarding" , feature = "backups_v1" ) ) ]
12301229 fn extract_content < ' a > (
12311230 recipient : & UserId ,
1232- request : & ' a OutgoingRequest ,
1231+ request : & ' a crate :: OutgoingRequest ,
12331232 ) -> & ' a Raw < ruma:: events:: AnyToDeviceEventContent > {
12341233 request
12351234 . request ( )
@@ -1259,21 +1258,24 @@ mod tests {
12591258 }
12601259 }
12611260
1262- #[ cfg( feature = "automatic-room-key-forwarding" ) ]
1261+ #[ cfg( any ( feature = "automatic-room-key-forwarding" , feature = "backups_v1" ) ) ]
12631262 fn request_to_event < C > (
12641263 recipient : & UserId ,
12651264 sender : & UserId ,
1266- request : & OutgoingRequest ,
1267- ) -> ToDeviceEvent < C >
1265+ request : & crate :: OutgoingRequest ,
1266+ ) -> crate :: types :: events :: ToDeviceEvent < C >
12681267 where
1269- C : EventType + DeserializeOwned + Serialize + std:: fmt:: Debug ,
1268+ C : crate :: types:: events:: EventType
1269+ + serde:: de:: DeserializeOwned
1270+ + serde:: ser:: Serialize
1271+ + std:: fmt:: Debug ,
12701272 {
12711273 let content = extract_content ( recipient, request) ;
1272- let content: C = content
1273- . deserialize_as ( )
1274- . expect ( "We can always deserialize the to-device event content" ) ;
1274+ let content: C = content. deserialize_as ( ) . unwrap_or_else ( |_| {
1275+ panic ! ( "We can always deserialize the to-device event content {content:?}" )
1276+ } ) ;
12751277
1276- ToDeviceEvent :: new ( sender. to_owned ( ) , content)
1278+ crate :: types :: events :: ToDeviceEvent :: new ( sender. to_owned ( ) , content)
12771279 }
12781280
12791281 #[ async_test]
@@ -1751,6 +1753,88 @@ mod tests {
17511753 assert ! ( !alice_machine. inner. outgoing_requests. is_empty( ) ) ;
17521754 }
17531755
1756+ #[ async_test]
1757+ #[ cfg( feature = "backups_v1" ) ]
1758+ async fn secret_broadcasting ( ) {
1759+ use futures_util:: { pin_mut, FutureExt } ;
1760+ use ruma:: api:: client:: to_device:: send_event_to_device:: v3:: Response as ToDeviceResponse ;
1761+ use serde_json:: value:: to_raw_value;
1762+ use tokio_stream:: StreamExt ;
1763+
1764+ use crate :: machine:: tests:: get_machine_pair_with_setup_sessions;
1765+
1766+ let alice_id = user_id ! ( "@alice:localhost" ) ;
1767+
1768+ let ( alice_machine, bob_machine) =
1769+ get_machine_pair_with_setup_sessions ( alice_id, alice_id, false ) . await ;
1770+
1771+ let key_requests = GossipMachine :: request_missing_secrets (
1772+ bob_machine. user_id ( ) ,
1773+ vec ! [ SecretName :: RecoveryKey ] ,
1774+ ) ;
1775+ let mut changes = Changes :: default ( ) ;
1776+ let request_id = key_requests. first ( ) . unwrap ( ) . request_id . to_owned ( ) ;
1777+ changes. key_requests = key_requests;
1778+ bob_machine. store ( ) . save_changes ( changes) . await . unwrap ( ) ;
1779+ for request in bob_machine. outgoing_requests ( ) . await . unwrap ( ) {
1780+ bob_machine
1781+ . mark_request_as_sent ( request. request_id ( ) , & ToDeviceResponse :: new ( ) )
1782+ . await
1783+ . unwrap ( ) ;
1784+ }
1785+
1786+ let event = RumaToDeviceEvent {
1787+ sender : alice_machine. user_id ( ) . to_owned ( ) ,
1788+ content : ToDeviceSecretRequestEventContent :: new (
1789+ RequestAction :: Request ( SecretName :: RecoveryKey ) ,
1790+ bob_machine. device_id ( ) . to_owned ( ) ,
1791+ request_id,
1792+ ) ,
1793+ } ;
1794+
1795+ let bob_device = alice_machine
1796+ . get_device ( alice_id, bob_machine. device_id ( ) , None )
1797+ . await
1798+ . unwrap ( )
1799+ . unwrap ( ) ;
1800+ let alice_device = bob_machine
1801+ . get_device ( alice_id, alice_machine. device_id ( ) , None )
1802+ . await
1803+ . unwrap ( )
1804+ . unwrap ( ) ;
1805+
1806+ // We need a trusted device, otherwise we won't serve nor accept secrets.
1807+ bob_device. set_trust_state ( LocalTrust :: Verified ) ;
1808+ alice_device. set_trust_state ( LocalTrust :: Verified ) ;
1809+ alice_machine. store ( ) . save_devices ( & [ bob_device. inner ] ) . await . unwrap ( ) ;
1810+ bob_machine. store ( ) . save_devices ( & [ alice_device. inner ] ) . await . unwrap ( ) ;
1811+
1812+ let recovery_key = crate :: store:: RecoveryKey :: new ( ) . unwrap ( ) ;
1813+ alice_machine. backup_machine ( ) . save_recovery_key ( Some ( recovery_key) , None ) . await . unwrap ( ) ;
1814+ alice_machine. inner . key_request_machine . receive_incoming_secret_request ( & event) ;
1815+ alice_machine. inner . key_request_machine . collect_incoming_key_requests ( ) . await . unwrap ( ) ;
1816+
1817+ let requests =
1818+ alice_machine. inner . key_request_machine . outgoing_to_device_requests ( ) . await . unwrap ( ) ;
1819+
1820+ assert_eq ! ( requests. len( ) , 1 ) ;
1821+ let request = requests. first ( ) . expect ( "We should have an outgoing to-device request" ) ;
1822+
1823+ let event: EncryptedToDeviceEvent =
1824+ request_to_event ( bob_machine. user_id ( ) , alice_machine. user_id ( ) , request) ;
1825+ let event = Raw :: from_json ( to_raw_value ( & event) . unwrap ( ) ) ;
1826+
1827+ let stream = bob_machine. store ( ) . secrets_stream ( ) ;
1828+ pin_mut ! ( stream) ;
1829+
1830+ bob_machine
1831+ . receive_sync_changes ( vec ! [ event] , & Default :: default ( ) , & Default :: default ( ) , None )
1832+ . await
1833+ . unwrap ( ) ;
1834+
1835+ stream. next ( ) . now_or_never ( ) . expect ( "The broadcaster should have sent out the secret" ) ;
1836+ }
1837+
17541838 #[ async_test]
17551839 #[ cfg( feature = "automatic-room-key-forwarding" ) ]
17561840 async fn key_share_cycle_without_session ( ) {
0 commit comments