Skip to content

Commit

Permalink
Merge branch 'main' into rav/fix_wait_if_user_pending
Browse files Browse the repository at this point in the history
  • Loading branch information
poljar committed Mar 14, 2023
2 parents e1c6ac9 + 4041c87 commit 9880619
Show file tree
Hide file tree
Showing 51 changed files with 1,489 additions and 445 deletions.
16 changes: 9 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ eyeball = "0.4.0"
eyeball-im = "0.1.0"
futures-util = { version = "0.3.26", default-features = false, features = ["alloc"] }
http = "0.2.6"
ruma = { git = "https://github.com/ruma/ruma", rev = "543c03f8f2d0f5a357b6be41cc0e166aa58cce63", features = ["client-api-c"] }
ruma-common = { git = "https://github.com/ruma/ruma", rev = "543c03f8f2d0f5a357b6be41cc0e166aa58cce63" }
ruma = { git = "https://github.com/ruma/ruma", rev = "a399a4017a9f0b249ce848a652f2e4fe65435eaf", features = ["client-api-c"] }
ruma-common = { git = "https://github.com/ruma/ruma", rev = "a399a4017a9f0b249ce848a652f2e4fe65435eaf" }
once_cell = "1.16.0"
serde = "1.0.151"
serde_html_form = "0.2.0"
Expand Down
144 changes: 131 additions & 13 deletions bindings/matrix-sdk-crypto-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use matrix_sdk_common::deserialized_responses::VerificationState;
use matrix_sdk_crypto::{
backups::SignatureState,
olm::{IdentityKeys, InboundGroupSession, Session},
store::{Changes, CryptoStore},
store::{Changes, CryptoStore, RoomSettings as RustRoomSettings},
types::{EventEncryptionAlgorithm as RustEventEncryptionAlgorithm, SigningKey},
EncryptionSettings as RustEncryptionSettings, LocalTrust,
};
Expand Down Expand Up @@ -75,6 +75,8 @@ pub struct MigrationData {
cross_signing: CrossSigningKeyExport,
/// The list of users that the Rust SDK should track.
tracked_users: Vec<String>,
/// Map of room settings
room_settings: HashMap<String, RoomSettings>,
}

/// Struct collecting data that is important to migrate sessions to the rust-sdk
Expand Down Expand Up @@ -296,13 +298,20 @@ async fn migrate_data(
processed_steps += 1;
listener(processed_steps, total_steps);

let mut room_settings = HashMap::new();
for (room_id, settings) in data.room_settings {
let room_id = RoomId::parse(room_id)?;
room_settings.insert(room_id, settings.into());
}

let changes = Changes {
account: Some(account),
private_identity: Some(cross_signing),
sessions,
inbound_group_sessions,
recovery_key,
backup_version: data.backup_version,
room_settings,
..Default::default()
};

Expand Down Expand Up @@ -471,6 +480,45 @@ fn collect_sessions(
Ok((sessions, inbound_group_sessions))
}

/// Migrate room settings, including room algorithm and whether to block
/// untrusted devices from legacy store to Sqlite store.
///
/// Note that this method should only be used if a client has already migrated
/// account data via [migrate](#method.migrate) method, which did not include
/// room settings. For a brand new migration, the [migrate](#method.migrate)
/// method will take care of room settings automatically, if provided.
///
/// # Arguments
///
/// * `room_settings` - Map of room settings
///
/// * `path` - The path where the Sqlite store should be created.
///
/// * `passphrase` - The passphrase that should be used to encrypt the data at
/// rest in the Sqlite store. **Warning**, if no passphrase is given, the store
/// and all its data will remain unencrypted.
pub fn migrate_room_settings(
room_settings: HashMap<String, RoomSettings>,
path: &str,
passphrase: Option<String>,
) -> anyhow::Result<()> {
let runtime = Runtime::new()?;
runtime.block_on(async move {
let store = SqliteCryptoStore::open(path, passphrase.as_deref()).await?;

let mut rust_settings = HashMap::new();
for (room_id, settings) in room_settings {
let room_id = RoomId::parse(room_id)?;
rust_settings.insert(room_id, settings.into());
}

let changes = Changes { room_settings: rust_settings, ..Default::default() };
store.save_changes(changes).await?;

Ok(())
})
}

/// Callback that will be passed over the FFI to report progress
pub trait ProgressListener {
/// The callback that should be called on the Rust side
Expand All @@ -490,6 +538,7 @@ impl<T: Fn(i32, i32)> ProgressListener for T {
}

/// An encryption algorithm to be used to encrypt messages sent to a room.
#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub enum EventEncryptionAlgorithm {
/// Olm version 1 using Curve25519, AES-256, and SHA-256.
OlmV1Curve25519AesSha2,
Expand All @@ -500,12 +549,22 @@ pub enum EventEncryptionAlgorithm {
impl From<EventEncryptionAlgorithm> for RustEventEncryptionAlgorithm {
fn from(a: EventEncryptionAlgorithm) -> Self {
match a {
EventEncryptionAlgorithm::OlmV1Curve25519AesSha2 => {
RustEventEncryptionAlgorithm::OlmV1Curve25519AesSha2
}
EventEncryptionAlgorithm::MegolmV1AesSha2 => {
RustEventEncryptionAlgorithm::MegolmV1AesSha2
EventEncryptionAlgorithm::OlmV1Curve25519AesSha2 => Self::OlmV1Curve25519AesSha2,
EventEncryptionAlgorithm::MegolmV1AesSha2 => Self::MegolmV1AesSha2,
}
}
}

impl TryFrom<RustEventEncryptionAlgorithm> for EventEncryptionAlgorithm {
type Error = serde_json::Error;

fn try_from(value: RustEventEncryptionAlgorithm) -> Result<Self, Self::Error> {
match value {
RustEventEncryptionAlgorithm::OlmV1Curve25519AesSha2 => {
Ok(Self::OlmV1Curve25519AesSha2)
}
RustEventEncryptionAlgorithm::MegolmV1AesSha2 => Ok(Self::MegolmV1AesSha2),
_ => Err(serde::de::Error::custom(format!("Unsupported algorithm {value}"))),
}
}
}
Expand Down Expand Up @@ -540,10 +599,10 @@ pub enum HistoryVisibility {
impl From<HistoryVisibility> for RustHistoryVisibility {
fn from(h: HistoryVisibility) -> Self {
match h {
HistoryVisibility::Invited => RustHistoryVisibility::Invited,
HistoryVisibility::Joined => RustHistoryVisibility::Joined,
HistoryVisibility::Shared => RustHistoryVisibility::Shared,
HistoryVisibility::WorldReadable => RustHistoryVisibility::Shared,
HistoryVisibility::Invited => Self::Invited,
HistoryVisibility::Joined => Self::Joined,
HistoryVisibility::Shared => Self::Shared,
HistoryVisibility::WorldReadable => Self::Shared,
}
}
}
Expand Down Expand Up @@ -709,6 +768,34 @@ impl From<matrix_sdk_crypto::CrossSigningStatus> for CrossSigningStatus {
}
}

/// Room encryption settings which are modified by state events or user options
#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct RoomSettings {
/// The encryption algorithm that should be used in the room.
pub algorithm: EventEncryptionAlgorithm,
/// Should untrusted devices receive the room key, or should they be
/// excluded from the conversation.
pub only_allow_trusted_devices: bool,
}

impl TryFrom<RustRoomSettings> for RoomSettings {
type Error = serde_json::Error;

fn try_from(value: RustRoomSettings) -> Result<Self, Self::Error> {
let algorithm = value.algorithm.try_into()?;
Ok(Self { algorithm, only_allow_trusted_devices: value.only_allow_trusted_devices })
}
}

impl From<RoomSettings> for RustRoomSettings {
fn from(value: RoomSettings) -> Self {
Self {
algorithm: value.algorithm.into(),
only_allow_trusted_devices: value.only_allow_trusted_devices,
}
}
}

fn parse_user_id(user_id: &str) -> Result<OwnedUserId, CryptoStoreError> {
ruma::UserId::parse(user_id).map_err(|e| CryptoStoreError::InvalidUserId(user_id.to_owned(), e))
}
Expand All @@ -725,7 +812,7 @@ mod uniffi_types {
RequestVerificationResult, StartSasResult, Verification, VerificationRequest,
},
BackupKeys, CrossSigningKeyExport, CrossSigningStatus, DecryptedEvent, EncryptionSettings,
RoomKeyCounts,
EventEncryptionAlgorithm, RoomKeyCounts, RoomSettings,
};
}

Expand All @@ -736,7 +823,7 @@ mod test {
use tempfile::tempdir;

use super::MigrationData;
use crate::{migrate, OlmMachine};
use crate::{migrate, EventEncryptionAlgorithm, OlmMachine, RoomSettings};

#[test]
fn android_migration() -> Result<()> {
Expand Down Expand Up @@ -819,7 +906,17 @@ mod test {
"@this-is-me:matrix.org",
"@Amandine:matrix.org",
"@ganfra:matrix.org"
]
],
"room_settings": {
"!AZkqtjvtwPAuyNOXEt:matrix.org": {
"algorithm": "OlmV1Curve25519AesSha2",
"only_allow_trusted_devices": true
},
"!CWLUCoEWXSFyTCOtfL:matrix.org": {
"algorithm": "MegolmV1AesSha2",
"only_allow_trusted_devices": false
},
}
});

let migration_data: MigrationData = serde_json::from_value(data)?;
Expand Down Expand Up @@ -848,6 +945,27 @@ mod test {
let backup_keys = machine.get_backup_keys()?;
assert!(backup_keys.is_some());

let settings1 = machine.get_room_settings("!AZkqtjvtwPAuyNOXEt:matrix.org".into())?;
assert_eq!(
Some(RoomSettings {
algorithm: EventEncryptionAlgorithm::OlmV1Curve25519AesSha2,
only_allow_trusted_devices: true
}),
settings1
);

let settings2 = machine.get_room_settings("!CWLUCoEWXSFyTCOtfL:matrix.org".into())?;
assert_eq!(
Some(RoomSettings {
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
only_allow_trusted_devices: false
}),
settings2
);

let settings3 = machine.get_room_settings("!XYZ:matrix.org".into())?;
assert!(settings3.is_none());

Ok(())
}
}
10 changes: 7 additions & 3 deletions bindings/matrix-sdk-crypto-ffi/src/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,13 @@ pub struct LoggerWrapper {
pub fn set_logger(logger: Box<dyn Logger>) {
let logger = LoggerWrapper { inner: Arc::new(Mutex::new(logger)) };

let filter = EnvFilter::from_default_env().add_directive(
"matrix_sdk_crypto=trace".parse().expect("Can't parse logging filter directive"),
);
let filter = EnvFilter::from_default_env()
.add_directive(
"matrix_sdk_crypto=trace".parse().expect("Can't parse logging filter directive"),
)
.add_directive(
"matrix_sdk_sqlite=debug".parse().expect("Can't parse logging filter directive"),
);

let _ = tracing_subscriber::fmt()
.with_writer(logger)
Expand Down
Loading

0 comments on commit 9880619

Please sign in to comment.