Skip to content

Commit b3c1ca1

Browse files
committed
Use the invite details when deciding if we should accept a bundle
1 parent ce66ee4 commit b3c1ca1

File tree

2 files changed

+80
-22
lines changed

2 files changed

+80
-22
lines changed

crates/matrix-sdk/src/encryption/tasks.rs

Lines changed: 79 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ use std::{collections::BTreeMap, sync::Arc, time::Duration};
1616

1717
use futures_core::Stream;
1818
use futures_util::{pin_mut, StreamExt};
19-
use matrix_sdk_base::{crypto::store::types::RoomKeyBundleInfo, RoomState};
19+
use matrix_sdk_base::{
20+
crypto::store::types::RoomKeyBundleInfo, InviteAcceptanceDetails, RoomState,
21+
};
2022
use matrix_sdk_common::failures_cache::FailuresCache;
2123
use ruma::{
2224
events::room::encrypted::{EncryptedEventScheme, OriginalSyncRoomEncryptedEvent},
@@ -441,20 +443,40 @@ impl BundleReceiverTask {
441443
}
442444
}
443445

444-
fn should_accept_bundle(room: &Room, _bundle_info: &RoomKeyBundleInfo) -> bool {
445-
// TODO: Check that the person that invited us to this room is the same as the
446-
// sender, of the bundle. Otherwise don't ignore the bundle.
447-
// TODO: Check that we joined the room "recently". (How do you do this if you
448-
// accept the invite on another client? I guess we remember when the transition
449-
// from Invited to Joined happened, but can't the server force us into a joined
450-
// state if we do this?
451-
room.state() == RoomState::Joined
446+
fn should_accept_bundle(room: &Room, bundle_info: &RoomKeyBundleInfo) -> bool {
447+
// We accept historic room key bundles up to one day after we have accepted an
448+
// invite.
449+
const DAY: Duration = Duration::from_secs(24 * 60 * 60);
450+
451+
// If we don't have any invite acceptance details, then this client wasn't the
452+
// one that accepted the invite.
453+
let Some(InviteAcceptanceDetails { invite_accepted_at, inviter }) =
454+
room.invite_acceptance_details()
455+
else {
456+
return false;
457+
};
458+
459+
let state = room.state();
460+
let elapsed_since_join = invite_accepted_at.to_system_time().and_then(|t| t.elapsed().ok());
461+
let bundle_sender = &bundle_info.sender;
462+
463+
match (state, elapsed_since_join) {
464+
(RoomState::Joined, Some(elapsed_since_join)) => {
465+
elapsed_since_join < DAY && bundle_sender == &inviter
466+
}
467+
(RoomState::Joined, None) => false,
468+
(RoomState::Left | RoomState::Invited | RoomState::Knocked | RoomState::Banned, _) => {
469+
false
470+
}
471+
}
452472
}
453473
}
454474

455475
#[cfg(all(test, not(target_family = "wasm")))]
456476
mod test {
457-
use matrix_sdk_test::{async_test, InvitedRoomBuilder, JoinedRoomBuilder};
477+
use matrix_sdk_test::{
478+
async_test, event_factory::EventFactory, InvitedRoomBuilder, JoinedRoomBuilder,
479+
};
458480
use ruma::{event_id, room_id, user_id};
459481
use serde_json::json;
460482
use wiremock::MockServer;
@@ -524,28 +546,51 @@ mod test {
524546
#[async_test]
525547
async fn test_should_accept_bundle() {
526548
let server = MatrixMockServer::new().await;
527-
let client = server.client_builder().logged_in_with_oauth().build().await;
528549

529-
let user_id = user_id!("@alice:localhost");
550+
let alice_user_id = user_id!("@alice:localhost");
551+
let bob_user_id = user_id!("@bob:localhost");
530552
let joined_room_id = room_id!("!joined:localhost");
531553
let invited_rom_id = room_id!("!invited:localhost");
532554

555+
let client = server
556+
.client_builder()
557+
.logged_in_with_token("ABCD".to_owned(), alice_user_id.into(), "DEVICEID".into())
558+
.build()
559+
.await;
560+
561+
let event_factory = EventFactory::new().room(invited_rom_id);
562+
let bob_member_event = event_factory.member(bob_user_id).into_raw_timeline();
563+
let alice_member_event =
564+
event_factory.member(bob_user_id).invited(alice_user_id).into_raw_timeline();
565+
533566
server
534567
.mock_sync()
535568
.ok_and_run(&client, |builder| {
536-
builder
537-
.add_joined_room(JoinedRoomBuilder::new(joined_room_id))
538-
.add_invited_room(InvitedRoomBuilder::new(invited_rom_id));
569+
builder.add_joined_room(JoinedRoomBuilder::new(joined_room_id)).add_invited_room(
570+
InvitedRoomBuilder::new(invited_rom_id)
571+
.add_state_event(bob_member_event.cast())
572+
.add_state_event(alice_member_event.cast()),
573+
);
539574
})
540575
.await;
541576

542577
let room =
543578
client.get_room(joined_room_id).expect("We should have access to our joined room now");
544579

545-
let bundle_info =
546-
RoomKeyBundleInfo { sender: user_id.to_owned(), room_id: joined_room_id.to_owned() };
580+
assert!(
581+
room.invite_acceptance_details().is_none(),
582+
"We shouldn't have any invite acceptance details if we didn't join the room on this Client"
583+
);
584+
585+
let bundle_info = RoomKeyBundleInfo {
586+
sender: bob_user_id.to_owned(),
587+
room_id: joined_room_id.to_owned(),
588+
};
547589

548-
assert!(BundleReceiverTask::should_accept_bundle(&room, &bundle_info));
590+
assert!(
591+
!BundleReceiverTask::should_accept_bundle(&room, &bundle_info),
592+
"We should not acceept a bundle if we did not join the room from this Client"
593+
);
549594

550595
let invited_room =
551596
client.get_room(invited_rom_id).expect("We should have access to our invited room now");
@@ -555,7 +600,21 @@ mod test {
555600
"We should not accept a bundle if we didn't join the room."
556601
);
557602

558-
// TODO: Add more cases here once we figure out the correct acceptance
559-
// rules.
603+
server.mock_room_join(invited_rom_id).ok().mock_once().mount().await;
604+
605+
let room = client
606+
.join_room_by_id(invited_rom_id)
607+
.await
608+
.expect("We should be able to join the invited room");
609+
610+
let details = room
611+
.invite_acceptance_details()
612+
.expect("We should have stored the invite acceptance details");
613+
assert_eq!(details.inviter, bob_user_id, "We should have recorded that Bob has invited us");
614+
615+
assert!(
616+
BundleReceiverTask::should_accept_bundle(&room, &bundle_info),
617+
"We should accept a bundle if we just joined the room and did so from this very Client object"
618+
);
560619
}
561620
}

testing/matrix-sdk-test/src/sync_builder/invited_room.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use ruma::{
33
events::AnyStrippedStateEvent, serde::Raw,
44
};
55

6-
use super::StrippedStateTestEvent;
76
use crate::DEFAULT_TEST_ROOM_ID;
87

98
pub struct InvitedRoomBuilder {
@@ -26,7 +25,7 @@ impl InvitedRoomBuilder {
2625
}
2726

2827
/// Add an event to the state.
29-
pub fn add_state_event(mut self, event: StrippedStateTestEvent) -> Self {
28+
pub fn add_state_event(mut self, event: impl Into<Raw<AnyStrippedStateEvent>>) -> Self {
3029
self.inner.invite_state.events.push(event.into());
3130
self
3231
}

0 commit comments

Comments
 (0)