atagen

macltok

public
Star0
Watch0
fa9114fcf75f7bdf1a7cec3b3367d604cf7de472
3
ssh://brewery@pls.lobotomise.me:33/atagen/macltok.git
tests/account.rsRust93 lines3.0 KB
1
#![cfg(feature = "sqlite")]
2
use std::time::{Duration, SystemTime};
3
4
use macltok::{
5
    Command, EngineConfig, Event, LifecycleCommand, PasswordLogin, Session, SessionRecord,
6
    StoreConfig,
7
};
8
use matrix_sdk::{ruma::api::client::sync::sync_events::v5, test_utils::mocks::MatrixMockServer};
9
10
#[tokio::test]
11
async fn password_session_round_trips_through_an_encrypted_store() {
12
    let server = MatrixMockServer::new().await;
13
    server
14
        .mock_versions()
15
        .with_simplified_sliding_sync()
16
        .ok()
17
        .mount()
18
        .await;
19
    server.mock_login().ok().mount().await;
20
    server
21
        .mock_sliding_sync()
22
        .ok(v5::Response::new("1".to_owned()))
23
        .mount()
24
        .await;
25
    let store_path = temporary_store_path();
26
    std::fs::create_dir_all(&store_path).unwrap();
27
    let config = EngineConfig::default().with_initial_history_limit(0);
28
    let session = Session::login_password(
29
        PasswordLogin {
30
            homeserver: server.uri(),
31
            username: "example".into(),
32
            password: "wordpass".into(),
33
            device_display_name: Some("macltok test".into()),
34
            device_id: None,
35
        },
36
        StoreConfig::new(&store_path, "test store passphrase"),
37
    )
38
    .await
39
    .unwrap();
40
    let encoded = serde_json::to_vec(&session.record()).unwrap();
41
    let record: SessionRecord = serde_json::from_slice(&encoded).unwrap();
42
    assert_eq!(
43
        record.homeserver().trim_end_matches('/'),
44
        server.uri().trim_end_matches('/')
45
    );
46
47
    let (engine, handle, mut events) = session.build(config.clone()).await.unwrap();
48
    let running = tokio::spawn(engine.run());
49
    receive_authenticated(&mut events).await;
50
    handle
51
        .send(Command::Lifecycle(LifecycleCommand::Shutdown))
52
        .await
53
        .unwrap();
54
    running.await.unwrap().unwrap();
55
56
    let session = Session::restore(
57
        record,
58
        StoreConfig::new(&store_path, "test store passphrase"),
59
    )
60
    .await
61
    .unwrap();
62
    let (engine, handle, mut events) = session.build(config).await.unwrap();
63
    let running = tokio::spawn(engine.run());
64
    receive_authenticated(&mut events).await;
65
    handle
66
        .send(Command::Lifecycle(LifecycleCommand::Shutdown))
67
        .await
68
        .unwrap();
69
    running.await.unwrap().unwrap();
70
71
    std::fs::remove_dir_all(store_path).unwrap();
72
}
73
74
async fn receive_authenticated(events: &mut macltok::EventStream) {
75
    tokio::time::timeout(Duration::from_secs(2), async {
76
        while let Some(event) = events.recv().await {
77
            if matches!(event, Event::Authenticated { .. }) {
78
                return;
79
            }
80
        }
81
        panic!("event stream closed before authentication");
82
    })
83
    .await
84
    .expect("authentication event did not arrive");
85
}
86
87
fn temporary_store_path() -> std::path::PathBuf {
88
    let nonce = SystemTime::now()
89
        .duration_since(SystemTime::UNIX_EPOCH)
90
        .unwrap()
91
        .as_nanos();
92
    std::env::temp_dir().join(format!("macltok-account-{nonce}"))
93
}