mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2025-12-24 00:01:03 -05:00
tests: Add an encrypted snapshot of a SQLite db for regression tests
This commit is contained in:
@@ -1404,11 +1404,14 @@ impl CryptoStore for SqliteCryptoStore {
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use matrix_sdk_common::deserialized_responses::WithheldCode;
|
||||
use matrix_sdk_crypto::{
|
||||
cryptostore_integration_tests, cryptostore_integration_tests_time, store::CryptoStore,
|
||||
cryptostore_integration_tests, cryptostore_integration_tests_time, olm::SenderDataType,
|
||||
store::CryptoStore,
|
||||
};
|
||||
use matrix_sdk_test::async_test;
|
||||
use once_cell::sync::Lazy;
|
||||
use ruma::{device_id, room_id, user_id};
|
||||
use similar_asserts::assert_eq;
|
||||
use tempfile::{tempdir, TempDir};
|
||||
use tokio::fs;
|
||||
@@ -1424,11 +1427,11 @@ mod tests {
|
||||
database: SqliteCryptoStore,
|
||||
}
|
||||
|
||||
async fn get_test_db() -> TestDb {
|
||||
async fn get_test_db(data_path: &str, passphrase: Option<&str>) -> TestDb {
|
||||
let db_name = "matrix-sdk-crypto.sqlite3";
|
||||
|
||||
let manifest_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("../..");
|
||||
let database_path = manifest_path.join("testing/data/storage").join(db_name);
|
||||
let database_path = manifest_path.join(data_path).join(db_name);
|
||||
|
||||
let tmpdir = tempdir().unwrap();
|
||||
let destination = tmpdir.path().join(db_name);
|
||||
@@ -1436,8 +1439,9 @@ mod tests {
|
||||
// Copy the test database to the tempdir so our test runs are idempotent.
|
||||
std::fs::copy(&database_path, destination).unwrap();
|
||||
|
||||
let database =
|
||||
SqliteCryptoStore::open(tmpdir.path(), None).await.expect("Can't open the test store");
|
||||
let database = SqliteCryptoStore::open(tmpdir.path(), passphrase)
|
||||
.await
|
||||
.expect("Can't open the test store");
|
||||
|
||||
TestDb { _dir: tmpdir, database }
|
||||
}
|
||||
@@ -1446,7 +1450,7 @@ mod tests {
|
||||
/// pre-filled database, or in other words use a test vector for this.
|
||||
#[async_test]
|
||||
async fn test_open_test_vector_store() {
|
||||
let TestDb { _dir: _, database } = get_test_db().await;
|
||||
let TestDb { _dir: _, database } = get_test_db("testing/data/storage", None).await;
|
||||
|
||||
let account = database
|
||||
.load_account()
|
||||
@@ -1508,6 +1512,277 @@ mod tests {
|
||||
assert_eq!(master_key.to_base64(), "iCUEtB1RwANeqRa5epDrblLk4mer/36sylwQ5hYY3oE");
|
||||
}
|
||||
|
||||
/// Test that we didn't regress in our storage layer by loading data from a
|
||||
/// pre-filled database, or in other words use a test vector for this.
|
||||
#[async_test]
|
||||
async fn test_open_test_vector_encrypted_store() {
|
||||
let TestDb { _dir: _, database } = get_test_db(
|
||||
"testing/data/storage/alice",
|
||||
Some(concat!(
|
||||
"/rCia2fYAJ+twCZ1Xm2mxFCYcmJdyzkdJjwtgXsziWpYS/UeNxnixuSieuwZXm+x1VsJHmWpl",
|
||||
"H+QIQBZpEGZtC9/S/l8xK+WOCesmET0o6yJ/KP73ofDtjBlnNpPwuHLKFpyTbyicpCgQ4UT+5E",
|
||||
"UBuJ08TY9Ujdf1D13k5kr5tSZUefDKKCuG1fCRqlU8ByRas1PMQsZxT2W8t7QgBrQiiGmhpo/O",
|
||||
"Ti4hfx97GOxncKcxTzppiYQNoHs/f15+XXQD7/oiCcqRIuUlXNsU6hRpFGmbYx2Pi1eyQViQCt",
|
||||
"B5dAEiSD0N8U81wXYnpynuTPtnL+hfnOJIn7Sy7mkERQeKg"
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
let account = database
|
||||
.load_account()
|
||||
.await
|
||||
.unwrap()
|
||||
.expect("The test database is prefilled with data, we should find an account");
|
||||
|
||||
let user_id = account.user_id();
|
||||
let device_id = account.device_id();
|
||||
|
||||
assert_eq!(
|
||||
user_id.as_str(),
|
||||
"@alice:localhost",
|
||||
"The user ID should match to the one we expect."
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
device_id.as_str(),
|
||||
"JVVORTHFXY",
|
||||
"The device ID should match to the one we expect."
|
||||
);
|
||||
|
||||
let tracked_users =
|
||||
database.load_tracked_users().await.expect("Should be tracking some users");
|
||||
|
||||
assert_eq!(tracked_users.len(), 6);
|
||||
|
||||
let known_users = vec![
|
||||
user_id!("@alice:localhost"),
|
||||
user_id!("@dehydration3:localhost"),
|
||||
user_id!("@eve:localhost"),
|
||||
user_id!("@bob:localhost"),
|
||||
user_id!("@malo:localhost"),
|
||||
user_id!("@carl:localhost"),
|
||||
];
|
||||
|
||||
// load the identities
|
||||
for user_id in known_users {
|
||||
database.get_user_identity(user_id).await.expect("Should load this identity").unwrap();
|
||||
}
|
||||
|
||||
let carl_identity =
|
||||
database.get_user_identity(user_id!("@carl:localhost")).await.unwrap().unwrap();
|
||||
|
||||
assert_eq!(
|
||||
carl_identity.master_key().get_first_key().unwrap().to_base64(),
|
||||
"CdhKYYDeBDQveOioXEGWhTPCyzc63Irpar3CNyfun2Q"
|
||||
);
|
||||
assert!(!carl_identity.was_previously_verified());
|
||||
|
||||
let bob_identity =
|
||||
database.get_user_identity(user_id!("@bob:localhost")).await.unwrap().unwrap();
|
||||
|
||||
assert_eq!(
|
||||
bob_identity.master_key().get_first_key().unwrap().to_base64(),
|
||||
"COh2GYOJWSjem5QPRCaGp9iWV83IELG1IzLKW2S3pFY"
|
||||
);
|
||||
// Bob is verified so this flag should be set
|
||||
assert!(bob_identity.was_previously_verified());
|
||||
|
||||
let known_devices = vec![
|
||||
(device_id!("OPXQHCZSKW"), user_id!("@alice:localhost")),
|
||||
// a dehydrated one
|
||||
(
|
||||
device_id!("EvW+9IrGR10KVgVeZP25/KaPfx4R86FofVMcaz7VOho"),
|
||||
user_id!("@alice:localhost"),
|
||||
),
|
||||
(device_id!("HEEFRFQENV"), user_id!("@alice:localhost")),
|
||||
(device_id!("JVVORTHFXY"), user_id!("@alice:localhost")),
|
||||
(device_id!("NQUWWSKKHS"), user_id!("@alice:localhost")),
|
||||
(device_id!("ORBLPFYCPG"), user_id!("@alice:localhost")),
|
||||
(device_id!("YXOWENSEGM"), user_id!("@dehydration3:localhost")),
|
||||
(device_id!("VXLFMYCHXC"), user_id!("@bob:localhost")),
|
||||
(device_id!("FDGDQAEWOW"), user_id!("@bob:localhost")),
|
||||
(device_id!("VXLFMYCHXC"), user_id!("@bob:localhost")),
|
||||
(device_id!("FDGDQAEWOW"), user_id!("@bob:localhost")),
|
||||
(device_id!("QKUKWJTTQC"), user_id!("@malo:localhost")),
|
||||
(device_id!("LOUXJECTFG"), user_id!("@malo:localhost")),
|
||||
(device_id!("MKKMAEVLPB"), user_id!("@carl:localhost")),
|
||||
];
|
||||
|
||||
for (device_id, user_id) in known_devices {
|
||||
database.get_device(user_id, device_id).await.expect("Should load the device").unwrap();
|
||||
}
|
||||
|
||||
let known_sender_key_to_session_count = vec![
|
||||
("FfYcYfDF4nWy+LHdK6CEpIMlFAQDORc30WUkghL06kM", 1),
|
||||
("EvW+9IrGR10KVgVeZP25/KaPfx4R86FofVMcaz7VOho", 1),
|
||||
("hAGsoA4a9M6wwEUX5Q1jux1i+tUngLi01n5AmhDoHTY", 1),
|
||||
("aKqtSJymLzuoglWFwPGk1r/Vm2LE2hFESzXxn4RNjRM", 0),
|
||||
("zHK1psCrgeMn0kaz8hcdvA3INyar9jg1yfrSp0p1pHo", 1),
|
||||
("1QmBA316Wj5jIFRwNOti6N6Xh/vW0bsYCcR4uPfy8VQ", 1),
|
||||
("g5ef2vZF3VXgSPyODIeXpyHIRkuthvLhGvd6uwYggWU", 1),
|
||||
("o7hfupPd1VsNkRIvdlH6ujrEJFSKjFCGbxhAd31XxjI", 1),
|
||||
("Z3RxKQLxY7xpP+ZdOGR2SiNE37SrvmRhW7GPu1UGdm8", 1),
|
||||
("GDomaav8NiY3J+dNEeApJm+O0FooJ3IpVaIyJzCN4w4", 1),
|
||||
("7m7fqkHyEr47V5s/KjaxtJMOr3pSHrrns2q2lWpAQi8", 0),
|
||||
("9psAkPUIF8vNbWbnviX3PlwRcaeO53EHJdNtKpTY1X0", 0),
|
||||
("mqanh+ztw5oRtpqYQgLGW864i6NY2zpoKMIlrcyC+Aw", 0),
|
||||
("fJU/TJdbsv7tVbbpHw1Ke73ziElnM32cNhP2WIg4T10", 0),
|
||||
("sUIeFeFcCZoa5IC6nJ6Vrbvztcyx09m8BBg57XKRClg", 1),
|
||||
];
|
||||
|
||||
for (id, count) in known_sender_key_to_session_count {
|
||||
let olm_sessions =
|
||||
database.get_sessions(id).await.expect("Should have some olm sessions");
|
||||
|
||||
println!("### Session id: {:?}", id);
|
||||
assert_eq!(olm_sessions.map_or(0, |v| v.len()), count);
|
||||
}
|
||||
|
||||
let inbound_group_sessions = database.get_inbound_group_sessions().await.unwrap();
|
||||
assert_eq!(inbound_group_sessions.len(), 15);
|
||||
let known_inbound_group_sessions = vec![
|
||||
(
|
||||
"5hNAxrLai3VI0LKBwfh3wLfksfBFWds0W1a5X5/vSXA",
|
||||
room_id!("!SRstFdydzrGwJYtVfm:localhost"),
|
||||
),
|
||||
(
|
||||
"M6d2eU3y54gaYTbvGSlqa/xc1Az35l56Cp9sxzHWO4g",
|
||||
room_id!("!SRstFdydzrGwJYtVfm:localhost"),
|
||||
),
|
||||
(
|
||||
"IrydwXkRk2N2AqUMIVmLL3oJgMq14R9KId0P/uSD100",
|
||||
room_id!("!SRstFdydzrGwJYtVfm:localhost"),
|
||||
),
|
||||
(
|
||||
"Y74+l9jTo7N5UF+GQwdpgJGe4sn1+QtWITq7BxulHIE",
|
||||
room_id!("!SRstFdydzrGwJYtVfm:localhost"),
|
||||
),
|
||||
(
|
||||
"HpJxQR57WbQGdY6w2Q+C16znVvbXGa+JvQdRoMpWbXg",
|
||||
room_id!("!SRstFdydzrGwJYtVfm:localhost"),
|
||||
),
|
||||
(
|
||||
"Xetvi+ydFkZt8dpONGFbEusQb/Chc2V0XlLByZhsbgE",
|
||||
room_id!("!ZIwZcFqZVAYLAqVjfV:localhost"),
|
||||
),
|
||||
(
|
||||
"wv/WN/39akyerIXczTaIpjAuLnwgXKRtbXFSEHiJqxo",
|
||||
room_id!("!ZIwZcFqZVAYLAqVjfV:localhost"),
|
||||
),
|
||||
(
|
||||
"nA4gQwL//Cm8OdlyjABl/jChbPT/cP5V4Sd8iuE6H0s",
|
||||
room_id!("!ZIwZcFqZVAYLAqVjfV:localhost"),
|
||||
),
|
||||
(
|
||||
"bAAgqFeRDTjfEqL6Qf/c9mk55zoNDCSlboAIRd6b0hw",
|
||||
room_id!("!ZIwZcFqZVAYLAqVjfV:localhost"),
|
||||
),
|
||||
(
|
||||
"exPbsMMdGfAG2qmDdFtpAn+koVprfzS0Zip/RA9QRCE",
|
||||
room_id!("!ZIwZcFqZVAYLAqVjfV:localhost"),
|
||||
),
|
||||
(
|
||||
"h+om7oSw/ZV94fcKaoe8FGXJwQXWOfKQfzbGgNWQILI",
|
||||
room_id!("!ZIwZcFqZVAYLAqVjfV:localhost"),
|
||||
),
|
||||
(
|
||||
"ul3VXonpgk4lO2L3fEWubP/nxsTmLHqu5v8ZM9vHEcw",
|
||||
room_id!("!ZIwZcFqZVAYLAqVjfV:localhost"),
|
||||
),
|
||||
(
|
||||
"JXY15UxC3az2mwg8uX4qwgxfvCM4aygiIWMcdNiVQoc",
|
||||
room_id!("!ZIwZcFqZVAYLAqVjfV:localhost"),
|
||||
),
|
||||
(
|
||||
"OGB9lObr9kWUvha9tB5sMfOF/Mztk24JwQz/nwg3iFQ",
|
||||
room_id!("!OgRiTRMaUzLdpCeDBM:localhost"),
|
||||
),
|
||||
(
|
||||
"SFkHcbxjUOYF7mUAYI/oEMDZFaXszQbCN6Jza7iemj0",
|
||||
room_id!("!OgRiTRMaUzLdpCeDBM:localhost"),
|
||||
),
|
||||
];
|
||||
|
||||
// ensure we can load them all
|
||||
for (session_id, room_id) in &known_inbound_group_sessions {
|
||||
database
|
||||
.get_inbound_group_session(room_id, session_id)
|
||||
.await
|
||||
.expect("Should be able to load inbound group session")
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let bob_sender_verified = database
|
||||
.get_inbound_group_session(
|
||||
room_id!("!ZIwZcFqZVAYLAqVjfV:localhost"),
|
||||
"exPbsMMdGfAG2qmDdFtpAn+koVprfzS0Zip/RA9QRCE",
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(bob_sender_verified.sender_data.to_type(), SenderDataType::SenderVerified);
|
||||
assert!(bob_sender_verified.backed_up());
|
||||
assert!(!bob_sender_verified.has_been_imported());
|
||||
|
||||
let alice_unknown_device = database
|
||||
.get_inbound_group_session(
|
||||
room_id!("!SRstFdydzrGwJYtVfm:localhost"),
|
||||
"IrydwXkRk2N2AqUMIVmLL3oJgMq14R9KId0P/uSD100",
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(alice_unknown_device.sender_data.to_type(), SenderDataType::UnknownDevice);
|
||||
assert!(alice_unknown_device.backed_up());
|
||||
assert!(alice_unknown_device.has_been_imported());
|
||||
|
||||
let carl_tofu_session = database
|
||||
.get_inbound_group_session(
|
||||
room_id!("!OgRiTRMaUzLdpCeDBM:localhost"),
|
||||
"OGB9lObr9kWUvha9tB5sMfOF/Mztk24JwQz/nwg3iFQ",
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(carl_tofu_session.sender_data.to_type(), SenderDataType::SenderUnverified);
|
||||
assert!(carl_tofu_session.backed_up());
|
||||
assert!(!carl_tofu_session.has_been_imported());
|
||||
|
||||
// Load outbound sessions
|
||||
database
|
||||
.get_outbound_group_session(room_id!("!OgRiTRMaUzLdpCeDBM:localhost"))
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
database
|
||||
.get_outbound_group_session(room_id!("!ZIwZcFqZVAYLAqVjfV:localhost"))
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
database
|
||||
.get_outbound_group_session(room_id!("!SRstFdydzrGwJYtVfm:localhost"))
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
let withheld_info = database
|
||||
.get_withheld_info(
|
||||
room_id!("!OgRiTRMaUzLdpCeDBM:localhost"),
|
||||
"SASgZ+EklvAF4QxJclMlDRlmL0fAMjAJJIKFMdb4Ht0",
|
||||
)
|
||||
.await
|
||||
.expect("This session should be withheld")
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(withheld_info.content.withheld_code(), WithheldCode::Unverified);
|
||||
|
||||
let backup_keys = database.load_backup_keys().await.expect("backup key should be cached");
|
||||
assert_eq!(backup_keys.backup_version.unwrap(), "6");
|
||||
assert!(backup_keys.decryption_key.is_some());
|
||||
}
|
||||
async fn get_store(
|
||||
name: &str,
|
||||
passphrase: Option<&str>,
|
||||
|
||||
8
testing/data/storage/alice/README.md
Normal file
8
testing/data/storage/alice/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
This database was built using a developer build of EXA using a localhost synapse.
|
||||
Contains several olm sessions, megolm sessions, identities.
|
||||
Used as a snapshot to test migrations to futures versions.
|
||||
The database file is exported using the Android Studio `Device Explorer` tool (in `files/sessions/xxx`).
|
||||
In order to get the passphrase a breakpoint must be added in the ClientBuilder to get it.
|
||||
Passphrase: `/rCia2fYAJ+twCZ1Xm2mxFCYcmJdyzkdJjwtgXsziWpYS/UeNxnixuSieuwZXm+x1VsJHmWplH+QIQBZpEGZtC9/S/l8xK+WOCesmET0o6yJ/KP73ofDtjBlnNpPwuHLKFpyTbyicpCgQ4UT+5EUBuJ08TY9Ujdf1D13k5kr5tSZUefDKKCuG1fCRqlU8ByRas1PMQsZxT2W8t7QgBrQiiGmhpo/OTi4hfx97GOxncKcxTzppiYQNoHs/f15+XXQD7/oiCcqRIuUlXNsU6hRpFGmbYx2Pi1eyQViQCtB5dAEiSD0N8U81wXYnpynuTPtnL+hfnOJIn7Sy7mkERQeKg`
|
||||
|
||||
Username is @alice:localhost
|
||||
BIN
testing/data/storage/alice/matrix-sdk-crypto.sqlite3
Normal file
BIN
testing/data/storage/alice/matrix-sdk-crypto.sqlite3
Normal file
Binary file not shown.
Reference in New Issue
Block a user