@@ -506,8 +506,7 @@ impl SlidingSync {
506
506
// re-downloaded if the `since` token is `None`, otherwise it's easy to miss
507
507
// device lists updates that happened between the previous request and the new
508
508
// “initial” request.
509
- #[ cfg( feature = "e2e-encryption" ) ]
510
- if pos. is_none ( ) && self . inner . version . is_native ( ) {
509
+ if pos. is_none ( ) && self . inner . version . is_native ( ) && self . is_e2ee_enabled ( ) {
511
510
let olm_machine = self . inner . client . olm_machine ( ) . await ;
512
511
let olm_machine = olm_machine. as_ref ( ) . ok_or ( Error :: NoOlmMachine ) ?;
513
512
olm_machine. mark_all_tracked_users_as_dirty ( ) . await ?;
@@ -865,15 +864,9 @@ enum SlidingSyncInternalMessage {
865
864
866
865
#[ cfg( any( test, feature = "testing" ) ) ]
867
866
impl SlidingSync {
868
- /// Get a copy of the `pos` value.
869
- pub fn pos ( & self ) -> Option < String > {
870
- let position_lock = self . inner . position . blocking_lock ( ) ;
871
- position_lock. pos . clone ( )
872
- }
873
-
874
867
/// Set a new value for `pos`.
875
- pub fn set_pos ( & self , new_pos : String ) {
876
- let mut position_lock = self . inner . position . blocking_lock ( ) ;
868
+ pub async fn set_pos ( & self , new_pos : String ) {
869
+ let mut position_lock = self . inner . position . lock ( ) . await ;
877
870
position_lock. pos = Some ( new_pos) ;
878
871
}
879
872
@@ -1684,6 +1677,153 @@ mod tests {
1684
1677
Ok ( ( ) )
1685
1678
}
1686
1679
1680
+ // With MSC4186, with the `e2ee` extension enabled, if a request has no `pos`,
1681
+ // all the tracked users by the `OlmMachine` must be marked as dirty, i.e.
1682
+ // `/key/query` requests must be sent. See the code to see the details.
1683
+ //
1684
+ // This test is asserting that.
1685
+ #[ async_test]
1686
+ #[ cfg( feature = "e2e-encryption" ) ]
1687
+ async fn test_no_pos_with_e2ee_marks_all_tracked_users_as_dirty ( ) -> anyhow:: Result < ( ) > {
1688
+ use matrix_sdk_base:: crypto:: { IncomingResponse , OutgoingRequests } ;
1689
+ use matrix_sdk_test:: ruma_response_from_json;
1690
+ use ruma:: user_id;
1691
+
1692
+ let server = MockServer :: start ( ) . await ;
1693
+ let client = logged_in_client ( Some ( server. uri ( ) ) ) . await ;
1694
+
1695
+ let alice = user_id ! ( "@alice:localhost" ) ;
1696
+ let bob = user_id ! ( "@bob:localhost" ) ;
1697
+ let me = user_id ! ( "@example:localhost" ) ;
1698
+
1699
+ // Track and mark users are not dirty, so that we can check they are “dirty”
1700
+ // after that. Dirty here means that a `/key/query` must be sent.
1701
+ {
1702
+ let olm_machine = client. olm_machine ( ) . await ;
1703
+ let olm_machine = olm_machine. as_ref ( ) . unwrap ( ) ;
1704
+
1705
+ olm_machine. update_tracked_users ( [ alice, bob] ) . await ?;
1706
+
1707
+ // Assert requests.
1708
+ let outgoing_requests = olm_machine. outgoing_requests ( ) . await ?;
1709
+
1710
+ assert_eq ! ( outgoing_requests. len( ) , 2 ) ;
1711
+ assert_matches ! ( outgoing_requests[ 0 ] . request( ) , OutgoingRequests :: KeysUpload ( _) ) ;
1712
+ assert_matches ! ( outgoing_requests[ 1 ] . request( ) , OutgoingRequests :: KeysQuery ( _) ) ;
1713
+
1714
+ // Fake responses.
1715
+ olm_machine
1716
+ . mark_request_as_sent (
1717
+ outgoing_requests[ 0 ] . request_id ( ) ,
1718
+ IncomingResponse :: KeysUpload ( & ruma_response_from_json ( & json ! ( {
1719
+ "one_time_key_counts" : { }
1720
+ } ) ) ) ,
1721
+ )
1722
+ . await ?;
1723
+
1724
+ olm_machine
1725
+ . mark_request_as_sent (
1726
+ outgoing_requests[ 1 ] . request_id ( ) ,
1727
+ IncomingResponse :: KeysQuery ( & ruma_response_from_json ( & json ! ( {
1728
+ "device_keys" : {
1729
+ alice: { } ,
1730
+ bob: { } ,
1731
+ }
1732
+ } ) ) ) ,
1733
+ )
1734
+ . await ?;
1735
+
1736
+ // Once more.
1737
+ let outgoing_requests = olm_machine. outgoing_requests ( ) . await ?;
1738
+
1739
+ assert_eq ! ( outgoing_requests. len( ) , 1 ) ;
1740
+ assert_matches ! ( outgoing_requests[ 0 ] . request( ) , OutgoingRequests :: KeysQuery ( _) ) ;
1741
+
1742
+ olm_machine
1743
+ . mark_request_as_sent (
1744
+ outgoing_requests[ 0 ] . request_id ( ) ,
1745
+ IncomingResponse :: KeysQuery ( & ruma_response_from_json ( & json ! ( {
1746
+ "device_keys" : {
1747
+ me: { } ,
1748
+ }
1749
+ } ) ) ) ,
1750
+ )
1751
+ . await ?;
1752
+
1753
+ // No more.
1754
+ let outgoing_requests = olm_machine. outgoing_requests ( ) . await ?;
1755
+
1756
+ assert ! ( outgoing_requests. is_empty( ) ) ;
1757
+ }
1758
+
1759
+ let sync = client
1760
+ . sliding_sync ( "test-slidingsync" ) ?
1761
+ . add_list ( SlidingSyncList :: builder ( "new_list" ) )
1762
+ . with_e2ee_extension ( assign ! ( http:: request:: E2EE :: default ( ) , { enabled: Some ( true ) } ) )
1763
+ . build ( )
1764
+ . await ?;
1765
+
1766
+ // First request: no `pos`.
1767
+ let txn_id = TransactionId :: new ( ) ;
1768
+ let ( _request, _, _) = sync
1769
+ . generate_sync_request ( & mut LazyTransactionId :: from_owned ( txn_id. to_owned ( ) ) )
1770
+ . await ?;
1771
+
1772
+ // Now, tracked users must be dirty.
1773
+ {
1774
+ let olm_machine = client. olm_machine ( ) . await ;
1775
+ let olm_machine = olm_machine. as_ref ( ) . unwrap ( ) ;
1776
+
1777
+ // Assert requests.
1778
+ let outgoing_requests = olm_machine. outgoing_requests ( ) . await ?;
1779
+
1780
+ assert_eq ! ( outgoing_requests. len( ) , 1 ) ;
1781
+ assert_matches ! (
1782
+ outgoing_requests[ 0 ] . request( ) ,
1783
+ OutgoingRequests :: KeysQuery ( request) => {
1784
+ assert!( request. device_keys. contains_key( alice) ) ;
1785
+ assert!( request. device_keys. contains_key( bob) ) ;
1786
+ assert!( request. device_keys. contains_key( me) ) ;
1787
+ }
1788
+ ) ;
1789
+
1790
+ // Fake responses.
1791
+ olm_machine
1792
+ . mark_request_as_sent (
1793
+ outgoing_requests[ 0 ] . request_id ( ) ,
1794
+ IncomingResponse :: KeysQuery ( & ruma_response_from_json ( & json ! ( {
1795
+ "device_keys" : {
1796
+ alice: { } ,
1797
+ bob: { } ,
1798
+ me: { } ,
1799
+ }
1800
+ } ) ) ) ,
1801
+ )
1802
+ . await ?;
1803
+ }
1804
+
1805
+ // Second request: with a `pos` this time.
1806
+ sync. set_pos ( "chocolat" . to_owned ( ) ) . await ;
1807
+
1808
+ let txn_id = TransactionId :: new ( ) ;
1809
+ let ( _request, _, _) = sync
1810
+ . generate_sync_request ( & mut LazyTransactionId :: from_owned ( txn_id. to_owned ( ) ) )
1811
+ . await ?;
1812
+
1813
+ // Tracked users are not marked as dirty.
1814
+ {
1815
+ let olm_machine = client. olm_machine ( ) . await ;
1816
+ let olm_machine = olm_machine. as_ref ( ) . unwrap ( ) ;
1817
+
1818
+ // Assert requests.
1819
+ let outgoing_requests = olm_machine. outgoing_requests ( ) . await ?;
1820
+
1821
+ assert ! ( outgoing_requests. is_empty( ) ) ;
1822
+ }
1823
+
1824
+ Ok ( ( ) )
1825
+ }
1826
+
1687
1827
#[ async_test]
1688
1828
async fn test_unknown_pos_resets_pos_and_sticky_parameters ( ) -> Result < ( ) > {
1689
1829
let server = MockServer :: start ( ) . await ;
0 commit comments