@@ -227,17 +227,18 @@ impl IdentityManager {
227
227
store. get_readonly_device ( & device_keys. user_id , & device_keys. device_id ) . await ?;
228
228
229
229
if let Some ( mut device) = old_device {
230
- if let Err ( e) = device. update_device ( & device_keys) {
231
- warn ! (
232
- user_id = ?device. user_id( ) ,
233
- device_id = ?device. device_id( ) ,
234
- error = ?e,
235
- "Rejecting device update" ,
236
- ) ;
237
-
238
- Ok ( DeviceChange :: None )
239
- } else {
240
- Ok ( DeviceChange :: Updated ( device) )
230
+ match device. update_device ( & device_keys) {
231
+ Err ( e) => {
232
+ warn ! (
233
+ user_id = ?device. user_id( ) ,
234
+ device_id = ?device. device_id( ) ,
235
+ error = ?e,
236
+ "Rejecting device update" ,
237
+ ) ;
238
+ Ok ( DeviceChange :: None )
239
+ }
240
+ Ok ( true ) => Ok ( DeviceChange :: Updated ( device) ) ,
241
+ Ok ( false ) => Ok ( DeviceChange :: None ) ,
241
242
}
242
243
} else {
243
244
match ReadOnlyDevice :: try_from ( & device_keys) {
@@ -1668,6 +1669,67 @@ pub(crate) mod tests {
1668
1669
assert_eq ! ( devices. devices( ) . next( ) . unwrap( ) . device_id( ) , "LVWOVGOXME" ) ;
1669
1670
}
1670
1671
1672
+ #[ async_test]
1673
+ async fn test_invalid_key_response ( ) {
1674
+ let my_user_id = user_id ( ) ;
1675
+ let my_device_id = device_id ( ) ;
1676
+ let manager = manager_test_helper ( my_user_id, my_device_id) . await ;
1677
+
1678
+ // First of all, populate the store with good data
1679
+ let ( reqid, _) = manager. build_key_query_for_users ( vec ! [ user_id( ) ] ) ;
1680
+ let ( device_changes, identity_changes) =
1681
+ manager. receive_keys_query_response ( & reqid, & own_key_query ( ) ) . await . unwrap ( ) ;
1682
+ assert_eq ! ( device_changes. new. len( ) , 1 ) ;
1683
+ let test_device_id = device_changes. new . first ( ) . unwrap ( ) . device_id ( ) . to_owned ( ) ;
1684
+ use crate :: store:: Changes ;
1685
+ let changes =
1686
+ Changes { devices : device_changes, identities : identity_changes, ..Changes :: default ( ) } ;
1687
+ manager. store . save_changes ( changes) . await . unwrap ( ) ;
1688
+
1689
+ // Now provide an invalid update
1690
+ let ( reqid, _) = manager. build_key_query_for_users ( vec ! [ my_user_id] ) ;
1691
+ let response_data = matrix_sdk_test:: response_from_file ( & json ! ( {
1692
+ "device_keys" : {
1693
+ my_user_id: {
1694
+ test_device_id. as_str( ) : {
1695
+ "algorithms" : [
1696
+ "m.olm.v1.curve25519-aes-sha2" ,
1697
+ ] ,
1698
+ "device_id" : test_device_id. as_str( ) ,
1699
+ "keys" : {
1700
+ format!( "curve25519:{}" , test_device_id) : "wnip2tbJBJxrFayC88NNJpm61TeSNgYcqBH4T9yEDhU" ,
1701
+ format!( "ed25519:{}" , test_device_id) : "lQ+eshkhgKoo+qp9Qgnj3OX5PBoWMU5M9zbuEevwYqE"
1702
+ } ,
1703
+ "signatures" : {
1704
+ my_user_id: {
1705
+ // Not a valid signature.
1706
+ format!( "ed25519:{}" , test_device_id) : "imadethisup" ,
1707
+ }
1708
+ } ,
1709
+ "user_id" : my_user_id,
1710
+ }
1711
+ }
1712
+ }
1713
+ } ) ) ;
1714
+ let response =
1715
+ ruma:: api:: client:: keys:: get_keys:: v3:: Response :: try_from_http_response ( response_data)
1716
+ . expect ( "Can't parse the `/keys/upload` response" ) ;
1717
+
1718
+ let ( device_changes, identity_changes) =
1719
+ manager. receive_keys_query_response ( & reqid, & response) . await . unwrap ( ) ;
1720
+
1721
+ // The result should be empty
1722
+ assert_eq ! ( device_changes. new. len( ) , 0 ) ;
1723
+ assert_eq ! ( device_changes. changed. len( ) , 0 ) ;
1724
+ assert_eq ! ( device_changes. deleted. len( ) , 0 ) ;
1725
+ assert_eq ! ( identity_changes. new. len( ) , 0 ) ;
1726
+
1727
+ // And the device should not have been updated.
1728
+ let device =
1729
+ manager. store . get_user_devices ( my_user_id) . await . unwrap ( ) . get ( & test_device_id) . unwrap ( ) ;
1730
+ assert_eq ! ( device. algorithms( ) . len( ) , 2 ) ;
1731
+ }
1732
+
1671
1733
#[ async_test]
1672
1734
async fn test_devices_stream ( ) {
1673
1735
let manager = manager_test_helper ( user_id ( ) , device_id ( ) ) . await ;
@@ -1723,18 +1785,15 @@ pub(crate) mod tests {
1723
1785
manager. as_ref ( ) . unwrap ( ) . build_key_query_for_users ( vec ! [ user_id( ) ] ) ;
1724
1786
1725
1787
// A second `/keys/query` response with the same result shouldn't fire a change
1726
- // notification: the identity should be unchanged.
1788
+ // notification: the identity and device should be unchanged.
1727
1789
manager
1728
1790
. as_ref ( )
1729
1791
. unwrap ( )
1730
1792
. receive_keys_query_response ( & new_request_id, & own_key_query ( ) )
1731
1793
. await
1732
1794
. unwrap ( ) ;
1733
1795
1734
- let ( identity_update_2, _) = assert_ready ! ( stream) ;
1735
- assert_eq ! ( identity_update_2. new. len( ) , 0 ) ;
1736
- assert_eq ! ( identity_update_2. changed. len( ) , 0 ) ;
1737
- assert_eq ! ( identity_update_2. unchanged. len( ) , 1 ) ;
1796
+ assert_pending ! ( stream) ;
1738
1797
1739
1798
// dropping the manager (and hence dropping the store) should close the stream
1740
1799
manager. take ( ) ;
0 commit comments