Skip to content

Commit 3dec91a

Browse files
committed
feat(labs): add create room ability to multiverse
Signed-off-by: Skye Elliot <[email protected]>
1 parent 4a30a16 commit 3dec91a

File tree

6 files changed

+97
-16
lines changed

6 files changed

+97
-16
lines changed

crates/matrix-sdk-base/src/response_processors/state_events.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use ruma::{
2525
use serde::Deserialize;
2626
use tracing::warn;
2727

28-
use super::{e2ee, Context};
28+
use super::{Context, e2ee};
2929
use crate::store::BaseStateStore;
3030

3131
/// Collect [`AnySyncStateEvent`].

crates/matrix-sdk-base/src/room/room_info.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -619,10 +619,18 @@ impl RoomInfo {
619619
pub fn encryption_state(&self) -> EncryptionState {
620620
if !self.encryption_state_synced {
621621
EncryptionState::Unknown
622-
} else if self.base_info.encryption.is_some() {
623-
EncryptionState::Encrypted
624622
} else {
625-
EncryptionState::NotEncrypted
623+
self.base_info
624+
.encryption
625+
.as_ref()
626+
.map(|state| {
627+
if state.encrypt_state_events {
628+
EncryptionState::StateEncrypted
629+
} else {
630+
EncryptionState::Encrypted
631+
}
632+
})
633+
.unwrap_or(EncryptionState::NotEncrypted)
626634
}
627635
}
628636

crates/matrix-sdk/src/room/futures.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -408,15 +408,7 @@ impl<'a> SendStateEventRaw<'a> {
408408

409409
/// Returns `true` if the inner event should be encrypted.
410410
async fn should_encrypt(room: &Room, event_type: &str) -> bool {
411-
let olm = room.client.olm_machine().await;
412-
let olm = olm.as_ref().expect("Olm machine was not started.");
413-
414-
// Lookup room settings and check encryptiong state.
415-
let Ok(Some(settings)) = olm.room_settings(room.room_id()).await else {
416-
trace!("Sending plaintext event as the room is NOT encrypted.");
417-
return false;
418-
};
419-
if !settings.encrypt_state_events {
411+
if !room.encryption_state().is_state_encrypted() {
420412
trace!("Sending plaintext event as the room does NOT support encrypted state events.");
421413
return false;
422414
}

crates/matrix-sdk/src/room/mod.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,6 +1959,48 @@ impl Room {
19591959
Ok(())
19601960
}
19611961

1962+
/// Enable End-to-end encryption in this room, with experimental encrypted state events.
1963+
#[instrument(skip_all)]
1964+
pub async fn enable_encryption_with_state(&self) -> Result<()> {
1965+
use ruma::{
1966+
events::room::encryption::RoomEncryptionEventContent, EventEncryptionAlgorithm,
1967+
};
1968+
const SYNC_WAIT_TIME: Duration = Duration::from_secs(3);
1969+
1970+
if !self.latest_encryption_state().await?.is_encrypted() {
1971+
let content =
1972+
RoomEncryptionEventContent::new(EventEncryptionAlgorithm::MegolmV1AesSha2)
1973+
.with_encrypted_state();
1974+
self.send_state_event(content).await?;
1975+
1976+
// TODO do we want to return an error here if we time out? This
1977+
// could be quite useful if someone wants to enable encryption and
1978+
// send a message right after it's enabled.
1979+
_ = timeout(self.client.inner.sync_beat.listen(), SYNC_WAIT_TIME).await;
1980+
1981+
// If after waiting for a sync, we don't have the encryption state we expect,
1982+
// assume the local encryption state is incorrect; this will cause
1983+
// the SDK to re-request it later for confirmation, instead of
1984+
// assuming it's sync'd and correct (and not encrypted).
1985+
let _sync_lock = self.client.base_client().sync_lock().lock().await;
1986+
if !self.inner.encryption_state().is_state_encrypted() {
1987+
debug!("still not marked as encrypted, marking encryption state as missing");
1988+
1989+
let mut room_info = self.clone_info();
1990+
room_info.mark_encryption_state_missing();
1991+
let mut changes = StateChanges::default();
1992+
changes.add_room(room_info.clone());
1993+
1994+
self.client.state_store().save_changes(&changes).await?;
1995+
self.set_room_info(room_info, RoomInfoNotableUpdateReasons::empty());
1996+
} else {
1997+
debug!("room successfully marked as encrypted");
1998+
}
1999+
}
2000+
2001+
Ok(())
2002+
}
2003+
19622004
/// Share a room key with users in the given room.
19632005
///
19642006
/// This will create Olm sessions with all the users/device pairs in the

labs/multiverse/src/widgets/room_view/input.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,22 @@ struct Cli {
1414

1515
#[derive(Debug, Subcommand)]
1616
pub enum Command {
17-
Invite { user_id: String },
17+
Create {
18+
name: String,
19+
#[clap(long)]
20+
encrypted: bool,
21+
#[clap(long)]
22+
state_encrypted: bool,
23+
},
24+
Invite {
25+
user_id: String,
26+
},
1827
Leave,
1928
Subscribe,
2029
Unsubscribe,
21-
Rename { to: String },
30+
Rename {
31+
to: String,
32+
},
2233
}
2334

2435
pub enum MessageOrCommand {

labs/multiverse/src/widgets/room_view/mod.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ use matrix_sdk::{
1010
locks::Mutex,
1111
ruma::{
1212
OwnedEventId, OwnedRoomId, RoomId, UserId,
13-
api::client::receipt::create_receipt::v3::ReceiptType,
13+
api::client::{
14+
receipt::create_receipt::v3::ReceiptType,
15+
room::create_room::v3::Request as CreateRoomRequest,
16+
},
17+
assign,
1418
events::room::message::RoomMessageEventContent,
1519
},
1620
store::ThreadStatus,
@@ -447,6 +451,27 @@ impl RoomView {
447451
}
448452
}
449453

454+
async fn create_room(&mut self, name: String, encrypted: bool, state_encrypted: bool) {
455+
// Create a room in the internal store
456+
let room = self
457+
.client
458+
.create_room(assign!(CreateRoomRequest::new(), {
459+
name: Some(name),
460+
invite: vec![],
461+
is_direct: false,
462+
}))
463+
.await
464+
.unwrap();
465+
466+
// Enable encryption
467+
if encrypted && !state_encrypted {
468+
room.enable_encryption().await.unwrap();
469+
}
470+
if state_encrypted {
471+
room.enable_encryption_with_state().await.unwrap();
472+
}
473+
}
474+
450475
async fn invite_member(&mut self, user_id: &str) {
451476
self.call_with_room(async move |room, status_handle| {
452477
let user_id = match UserId::parse_with_server_name(
@@ -565,6 +590,9 @@ impl RoomView {
565590

566591
async fn handle_command(&mut self, command: input::Command) {
567592
match command {
593+
input::Command::Create { name, encrypted, state_encrypted } => {
594+
self.create_room(name, encrypted, state_encrypted).await
595+
}
568596
input::Command::Invite { user_id } => self.invite_member(&user_id).await,
569597
input::Command::Leave => self.leave_room().await,
570598
input::Command::Subscribe => self.subscribe_thread().await,

0 commit comments

Comments
 (0)