Merge branch 'encryption-info-v2'
commit
d90e112c06
|
@ -81,7 +81,12 @@ async fn login(
|
||||||
let client = &client_ref;
|
let client = &client_ref;
|
||||||
let initial = &initial_ref;
|
let initial = &initial_ref;
|
||||||
|
|
||||||
for event in &response.to_device.events {
|
for event in response
|
||||||
|
.to_device
|
||||||
|
.events
|
||||||
|
.iter()
|
||||||
|
.filter_map(|e| e.deserialize().ok())
|
||||||
|
{
|
||||||
match event {
|
match event {
|
||||||
AnyToDeviceEvent::KeyVerificationStart(e) => {
|
AnyToDeviceEvent::KeyVerificationStart(e) => {
|
||||||
let sas = client
|
let sas = client
|
||||||
|
@ -124,7 +129,12 @@ async fn login(
|
||||||
|
|
||||||
if !initial.load(Ordering::SeqCst) {
|
if !initial.load(Ordering::SeqCst) {
|
||||||
for (_room_id, room_info) in response.rooms.join {
|
for (_room_id, room_info) in response.rooms.join {
|
||||||
for event in room_info.timeline.events {
|
for event in room_info
|
||||||
|
.timeline
|
||||||
|
.events
|
||||||
|
.iter()
|
||||||
|
.filter_map(|e| e.event.deserialize().ok())
|
||||||
|
{
|
||||||
if let AnySyncRoomEvent::Message(event) = event {
|
if let AnySyncRoomEvent::Message(event) = event {
|
||||||
match event {
|
match event {
|
||||||
AnySyncMessageEvent::RoomMessage(m) => {
|
AnySyncMessageEvent::RoomMessage(m) => {
|
||||||
|
|
|
@ -58,7 +58,7 @@ impl WasmBot {
|
||||||
|
|
||||||
for (room_id, room) in response.rooms.join {
|
for (room_id, room) in response.rooms.join {
|
||||||
for event in room.timeline.events {
|
for event in room.timeline.events {
|
||||||
if let AnySyncRoomEvent::Message(AnySyncMessageEvent::RoomMessage(ev)) = event {
|
if let Ok(AnySyncRoomEvent::Message(AnySyncMessageEvent::RoomMessage(ev))) = event.event.deserialize() {
|
||||||
self.on_room_message(&room_id, &ev).await
|
self.on_room_message(&room_id, &ev).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,50 +75,95 @@ impl Handler {
|
||||||
pub(crate) async fn handle_sync(&self, response: &SyncResponse) {
|
pub(crate) async fn handle_sync(&self, response: &SyncResponse) {
|
||||||
for (room_id, room_info) in &response.rooms.join {
|
for (room_id, room_info) in &response.rooms.join {
|
||||||
if let Some(room) = self.get_room(room_id) {
|
if let Some(room) = self.get_room(room_id) {
|
||||||
for event in &room_info.ephemeral.events {
|
for event in room_info
|
||||||
self.handle_ephemeral_event(room.clone(), event).await;
|
.ephemeral
|
||||||
|
.events
|
||||||
|
.iter()
|
||||||
|
.filter_map(|e| e.deserialize().ok())
|
||||||
|
{
|
||||||
|
self.handle_ephemeral_event(room.clone(), &event).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
for event in &room_info.account_data.events {
|
for event in room_info
|
||||||
self.handle_account_data_event(room.clone(), event).await;
|
.account_data
|
||||||
|
.events
|
||||||
|
.iter()
|
||||||
|
.filter_map(|e| e.deserialize().ok())
|
||||||
|
{
|
||||||
|
self.handle_account_data_event(room.clone(), &event).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
for event in &room_info.state.events {
|
for event in room_info
|
||||||
self.handle_state_event(room.clone(), event).await;
|
.state
|
||||||
|
.events
|
||||||
|
.iter()
|
||||||
|
.filter_map(|e| e.deserialize().ok())
|
||||||
|
{
|
||||||
|
self.handle_state_event(room.clone(), &event).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
for event in &room_info.timeline.events {
|
for event in room_info
|
||||||
self.handle_timeline_event(room.clone(), event).await;
|
.timeline
|
||||||
|
.events
|
||||||
|
.iter()
|
||||||
|
.filter_map(|e| e.event.deserialize().ok())
|
||||||
|
{
|
||||||
|
self.handle_timeline_event(room.clone(), &event).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (room_id, room_info) in &response.rooms.leave {
|
for (room_id, room_info) in &response.rooms.leave {
|
||||||
if let Some(room) = self.get_room(room_id) {
|
if let Some(room) = self.get_room(room_id) {
|
||||||
for event in &room_info.account_data.events {
|
for event in room_info
|
||||||
self.handle_account_data_event(room.clone(), event).await;
|
.account_data
|
||||||
|
.events
|
||||||
|
.iter()
|
||||||
|
.filter_map(|e| e.deserialize().ok())
|
||||||
|
{
|
||||||
|
self.handle_account_data_event(room.clone(), &event).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
for event in &room_info.state.events {
|
for event in room_info
|
||||||
self.handle_state_event(room.clone(), event).await;
|
.state
|
||||||
|
.events
|
||||||
|
.iter()
|
||||||
|
.filter_map(|e| e.deserialize().ok())
|
||||||
|
{
|
||||||
|
self.handle_state_event(room.clone(), &event).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
for event in &room_info.timeline.events {
|
for event in room_info
|
||||||
self.handle_timeline_event(room.clone(), event).await;
|
.timeline
|
||||||
|
.events
|
||||||
|
.iter()
|
||||||
|
.filter_map(|e| e.event.deserialize().ok())
|
||||||
|
{
|
||||||
|
self.handle_timeline_event(room.clone(), &event).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (room_id, room_info) in &response.rooms.invite {
|
for (room_id, room_info) in &response.rooms.invite {
|
||||||
if let Some(room) = self.get_room(room_id) {
|
if let Some(room) = self.get_room(room_id) {
|
||||||
for event in &room_info.invite_state.events {
|
for event in room_info
|
||||||
self.handle_stripped_state_event(room.clone(), event).await;
|
.invite_state
|
||||||
|
.events
|
||||||
|
.iter()
|
||||||
|
.filter_map(|e| e.deserialize().ok())
|
||||||
|
{
|
||||||
|
self.handle_stripped_state_event(room.clone(), &event).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for event in &response.presence.events {
|
for event in response
|
||||||
self.on_presence_event(event).await;
|
.presence
|
||||||
|
.events
|
||||||
|
.iter()
|
||||||
|
.filter_map(|e| e.deserialize().ok())
|
||||||
|
{
|
||||||
|
self.on_presence_event(&event).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (room_id, notifications) in &response.notifications {
|
for (room_id, notifications) in &response.notifications {
|
||||||
|
|
|
@ -37,15 +37,13 @@ use matrix_sdk_common::{
|
||||||
use matrix_sdk_common::{
|
use matrix_sdk_common::{
|
||||||
api::r0::{self as api, push::get_notifications::Notification},
|
api::r0::{self as api, push::get_notifications::Notification},
|
||||||
deserialized_responses::{
|
deserialized_responses::{
|
||||||
AccountData, AmbiguityChanges, Ephemeral, InviteState, InvitedRoom, JoinedRoom, LeftRoom,
|
AmbiguityChanges, JoinedRoom, LeftRoom, MemberEvent, MembersResponse, Rooms,
|
||||||
MemberEvent, MembersResponse, Presence, Rooms, State, StrippedMemberEvent, SyncResponse,
|
StrippedMemberEvent, SyncResponse, SyncRoomEvent, Timeline,
|
||||||
Timeline,
|
|
||||||
},
|
},
|
||||||
events::{
|
events::{
|
||||||
presence::PresenceEvent,
|
|
||||||
room::member::{MemberEventContent, MembershipState},
|
room::member::{MemberEventContent, MembershipState},
|
||||||
AnyBasicEvent, AnyStrippedStateEvent, AnySyncRoomEvent, AnySyncStateEvent,
|
AnyBasicEvent, AnyStrippedStateEvent, AnySyncRoomEvent, AnySyncStateEvent, EventContent,
|
||||||
AnyToDeviceEvent, EventContent, EventType, StateEvent,
|
EventType, StateEvent,
|
||||||
},
|
},
|
||||||
identifiers::{RoomId, UserId},
|
identifiers::{RoomId, UserId},
|
||||||
instant::Instant,
|
instant::Instant,
|
||||||
|
@ -432,15 +430,13 @@ impl BaseClient {
|
||||||
let mut push_context = self.get_push_room_context(room, room_info, changes).await?;
|
let mut push_context = self.get_push_room_context(room, room_info, changes).await?;
|
||||||
|
|
||||||
for event in ruma_timeline.events {
|
for event in ruma_timeline.events {
|
||||||
match hoist_room_event_prev_content(&event) {
|
#[allow(unused_mut)]
|
||||||
Ok(mut e) => {
|
let mut event: SyncRoomEvent = event.into();
|
||||||
#[cfg(not(feature = "encryption"))]
|
|
||||||
let raw_event = event;
|
|
||||||
#[cfg(feature = "encryption")]
|
|
||||||
let mut raw_event = event;
|
|
||||||
|
|
||||||
|
match hoist_room_event_prev_content(&event.event) {
|
||||||
|
Ok(e) => {
|
||||||
#[allow(clippy::single_match)]
|
#[allow(clippy::single_match)]
|
||||||
match &mut e {
|
match &e {
|
||||||
AnySyncRoomEvent::State(s) => match s {
|
AnySyncRoomEvent::State(s) => match s {
|
||||||
AnySyncStateEvent::RoomMember(member) => {
|
AnySyncStateEvent::RoomMember(member) => {
|
||||||
if let Ok(member) = MemberEvent::try_from(member.clone()) {
|
if let Ok(member) = MemberEvent::try_from(member.clone()) {
|
||||||
|
@ -478,7 +474,9 @@ impl BaseClient {
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
room_info.handle_state_event(&s.content());
|
room_info.handle_state_event(&s.content());
|
||||||
changes.add_state_event(room_id, s.clone());
|
let raw_event: Raw<AnySyncStateEvent> =
|
||||||
|
Raw::from_json(event.event.clone().into_json());
|
||||||
|
changes.add_state_event(room_id, s.clone(), raw_event);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -487,18 +485,10 @@ impl BaseClient {
|
||||||
encrypted,
|
encrypted,
|
||||||
)) => {
|
)) => {
|
||||||
if let Some(olm) = self.olm_machine().await {
|
if let Some(olm) = self.olm_machine().await {
|
||||||
if let Ok(raw_decrypted) =
|
if let Ok(decrypted) =
|
||||||
olm.decrypt_room_event(encrypted, room_id).await
|
olm.decrypt_room_event(encrypted, room_id).await
|
||||||
{
|
{
|
||||||
match raw_decrypted.deserialize() {
|
event = decrypted;
|
||||||
Ok(decrypted) => {
|
|
||||||
e = decrypted;
|
|
||||||
raw_event = raw_decrypted;
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
warn!("Error deserializing a decrypted event {:?} ", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -517,14 +507,14 @@ impl BaseClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(context) = &push_context {
|
if let Some(context) = &push_context {
|
||||||
let actions = push_rules.get_actions(&raw_event, &context).to_vec();
|
let actions = push_rules.get_actions(&event.event, &context).to_vec();
|
||||||
|
|
||||||
if actions.iter().any(|a| matches!(a, Action::Notify)) {
|
if actions.iter().any(|a| matches!(a, Action::Notify)) {
|
||||||
changes.add_notification(
|
changes.add_notification(
|
||||||
room_id,
|
room_id,
|
||||||
Notification::new(
|
Notification::new(
|
||||||
actions,
|
actions,
|
||||||
raw_event,
|
event.event.clone(),
|
||||||
false,
|
false,
|
||||||
room_id.clone(),
|
room_id.clone(),
|
||||||
SystemTime::now(),
|
SystemTime::now(),
|
||||||
|
@ -537,13 +527,13 @@ impl BaseClient {
|
||||||
// Requires the possibility to associate custom data with events and to
|
// Requires the possibility to associate custom data with events and to
|
||||||
// store them.
|
// store them.
|
||||||
}
|
}
|
||||||
|
|
||||||
timeline.events.push(e);
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("Error deserializing event {:?}", e);
|
warn!("Error deserializing event {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timeline.events.push(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(timeline)
|
Ok(timeline)
|
||||||
|
@ -552,19 +542,17 @@ impl BaseClient {
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
fn handle_invited_state(
|
fn handle_invited_state(
|
||||||
&self,
|
&self,
|
||||||
events: Vec<Raw<AnyStrippedStateEvent>>,
|
events: &[Raw<AnyStrippedStateEvent>],
|
||||||
room_info: &mut RoomInfo,
|
room_info: &mut RoomInfo,
|
||||||
) -> (
|
) -> (
|
||||||
InviteState,
|
|
||||||
BTreeMap<UserId, StrippedMemberEvent>,
|
BTreeMap<UserId, StrippedMemberEvent>,
|
||||||
BTreeMap<String, BTreeMap<String, AnyStrippedStateEvent>>,
|
BTreeMap<String, BTreeMap<String, Raw<AnyStrippedStateEvent>>>,
|
||||||
) {
|
) {
|
||||||
events.into_iter().fold(
|
events.iter().fold(
|
||||||
(InviteState::default(), BTreeMap::new(), BTreeMap::new()),
|
(BTreeMap::new(), BTreeMap::new()),
|
||||||
|(mut state, mut members, mut state_events), e| {
|
|(mut members, mut state_events), raw_event| {
|
||||||
match e.deserialize() {
|
match raw_event.deserialize() {
|
||||||
Ok(e) => {
|
Ok(e) => {
|
||||||
state.events.push(e.clone());
|
|
||||||
|
|
||||||
if let AnyStrippedStateEvent::RoomMember(member) = e {
|
if let AnyStrippedStateEvent::RoomMember(member) = e {
|
||||||
match StrippedMemberEvent::try_from(member) {
|
match StrippedMemberEvent::try_from(member) {
|
||||||
|
@ -581,7 +569,7 @@ impl BaseClient {
|
||||||
state_events
|
state_events
|
||||||
.entry(e.content().event_type().to_owned())
|
.entry(e.content().event_type().to_owned())
|
||||||
.or_insert_with(BTreeMap::new)
|
.or_insert_with(BTreeMap::new)
|
||||||
.insert(e.state_key().to_owned(), e);
|
.insert(e.state_key().to_owned(), raw_event.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -591,7 +579,7 @@ impl BaseClient {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(state, members, state_events)
|
(members, state_events)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -600,10 +588,9 @@ impl BaseClient {
|
||||||
&self,
|
&self,
|
||||||
changes: &mut StateChanges,
|
changes: &mut StateChanges,
|
||||||
ambiguity_cache: &mut AmbiguityCache,
|
ambiguity_cache: &mut AmbiguityCache,
|
||||||
events: Vec<Raw<AnySyncStateEvent>>,
|
events: &[Raw<AnySyncStateEvent>],
|
||||||
room_info: &mut RoomInfo,
|
room_info: &mut RoomInfo,
|
||||||
) -> StoreResult<(State, BTreeSet<UserId>)> {
|
) -> StoreResult<BTreeSet<UserId>> {
|
||||||
let mut state = State::default();
|
|
||||||
let mut members = BTreeMap::new();
|
let mut members = BTreeMap::new();
|
||||||
let mut state_events = BTreeMap::new();
|
let mut state_events = BTreeMap::new();
|
||||||
let mut user_ids = BTreeSet::new();
|
let mut user_ids = BTreeSet::new();
|
||||||
|
@ -611,21 +598,18 @@ impl BaseClient {
|
||||||
|
|
||||||
let room_id = room_info.room_id.clone();
|
let room_id = room_info.room_id.clone();
|
||||||
|
|
||||||
for event in
|
for raw_event in events {
|
||||||
events
|
let event = match hoist_and_deserialize_state_event(raw_event) {
|
||||||
.into_iter()
|
Ok(e) => e,
|
||||||
.filter_map(|e| match hoist_and_deserialize_state_event(&e) {
|
Err(e) => {
|
||||||
Ok(e) => Some(e),
|
|
||||||
Err(err) => {
|
|
||||||
warn!(
|
warn!(
|
||||||
"Couldn't deserialize state event for room {}: {:?} {:#?}",
|
"Couldn't deserialize state event for room {}: {:?} {:#?}",
|
||||||
room_id, err, e
|
room_id, e, raw_event
|
||||||
);
|
);
|
||||||
None
|
continue;
|
||||||
}
|
}
|
||||||
})
|
};
|
||||||
{
|
|
||||||
state.events.push(event.clone());
|
|
||||||
room_info.handle_state_event(&event.content());
|
room_info.handle_state_event(&event.content());
|
||||||
|
|
||||||
if let AnySyncStateEvent::RoomMember(member) = event {
|
if let AnySyncStateEvent::RoomMember(member) = event {
|
||||||
|
@ -659,7 +643,7 @@ impl BaseClient {
|
||||||
state_events
|
state_events
|
||||||
.entry(event.content().event_type().to_owned())
|
.entry(event.content().event_type().to_owned())
|
||||||
.or_insert_with(BTreeMap::new)
|
.or_insert_with(BTreeMap::new)
|
||||||
.insert(event.state_key().to_owned(), event);
|
.insert(event.state_key().to_owned(), raw_event.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,7 +651,7 @@ impl BaseClient {
|
||||||
changes.profiles.insert(room_id.as_ref().clone(), profiles);
|
changes.profiles.insert(room_id.as_ref().clone(), profiles);
|
||||||
changes.state.insert(room_id.as_ref().clone(), state_events);
|
changes.state.insert(room_id.as_ref().clone(), state_events);
|
||||||
|
|
||||||
Ok((state, user_ids))
|
Ok(user_ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_room_account_data(
|
async fn handle_room_account_data(
|
||||||
|
@ -675,27 +659,25 @@ impl BaseClient {
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
events: &[Raw<AnyBasicEvent>],
|
events: &[Raw<AnyBasicEvent>],
|
||||||
changes: &mut StateChanges,
|
changes: &mut StateChanges,
|
||||||
) -> AccountData {
|
|
||||||
let events: Vec<AnyBasicEvent> =
|
|
||||||
events.iter().filter_map(|e| e.deserialize().ok()).collect();
|
|
||||||
|
|
||||||
for event in &events {
|
|
||||||
changes.add_room_account_data(room_id, event.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountData { events }
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_account_data(
|
|
||||||
&self,
|
|
||||||
events: Vec<Raw<AnyBasicEvent>>,
|
|
||||||
changes: &mut StateChanges,
|
|
||||||
) {
|
) {
|
||||||
let events: Vec<AnyBasicEvent> =
|
for raw_event in events {
|
||||||
events.iter().filter_map(|e| e.deserialize().ok()).collect();
|
if let Ok(event) = raw_event.deserialize() {
|
||||||
|
changes.add_room_account_data(room_id, event, raw_event.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for event in &events {
|
async fn handle_account_data(&self, events: &[Raw<AnyBasicEvent>], changes: &mut StateChanges) {
|
||||||
if let AnyBasicEvent::Direct(e) = event {
|
let mut account_data = BTreeMap::new();
|
||||||
|
|
||||||
|
for raw_event in events {
|
||||||
|
let event = if let Ok(e) = raw_event.deserialize() {
|
||||||
|
e
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let AnyBasicEvent::Direct(e) = &event {
|
||||||
for (user_id, rooms) in e.content.iter() {
|
for (user_id, rooms) in e.content.iter() {
|
||||||
for room_id in rooms {
|
for room_id in rooms {
|
||||||
if let Some(room) = changes.room_infos.get_mut(room_id) {
|
if let Some(room) = changes.room_infos.get_mut(room_id) {
|
||||||
|
@ -708,12 +690,9 @@ impl BaseClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let account_data: BTreeMap<String, AnyBasicEvent> = events
|
account_data.insert(event.content().event_type().to_owned(), raw_event.clone());
|
||||||
.into_iter()
|
}
|
||||||
.map(|e| (e.content().event_type().to_owned(), e))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
changes.account_data = account_data;
|
changes.account_data = account_data;
|
||||||
}
|
}
|
||||||
|
@ -769,29 +748,17 @@ impl BaseClient {
|
||||||
// decryptes to-device events, but leaves room events alone.
|
// decryptes to-device events, but leaves room events alone.
|
||||||
// This makes sure that we have the deryption keys for the room
|
// This makes sure that we have the deryption keys for the room
|
||||||
// events at hand.
|
// events at hand.
|
||||||
o.receive_sync_changes(&to_device, &device_lists, &device_one_time_keys_count)
|
o.receive_sync_changes(to_device, &device_lists, &device_one_time_keys_count)
|
||||||
.await?
|
.await?
|
||||||
} else {
|
} else {
|
||||||
to_device
|
to_device
|
||||||
.events
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|e| e.deserialize().ok())
|
|
||||||
.collect::<Vec<AnyToDeviceEvent>>()
|
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#[cfg(not(feature = "encryption"))]
|
|
||||||
let to_device = to_device
|
|
||||||
.events
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|e| e.deserialize().ok())
|
|
||||||
.collect::<Vec<AnyToDeviceEvent>>()
|
|
||||||
.into();
|
|
||||||
|
|
||||||
let mut changes = StateChanges::new(next_batch.clone());
|
let mut changes = StateChanges::new(next_batch.clone());
|
||||||
let mut ambiguity_cache = AmbiguityCache::new(self.store.clone());
|
let mut ambiguity_cache = AmbiguityCache::new(self.store.clone());
|
||||||
|
|
||||||
self.handle_account_data(account_data.events, &mut changes)
|
self.handle_account_data(&account_data.events, &mut changes)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let push_rules = self.get_push_rules(&changes).await?;
|
let push_rules = self.get_push_rules(&changes).await?;
|
||||||
|
@ -809,11 +776,11 @@ impl BaseClient {
|
||||||
room_info.update_summary(&new_info.summary);
|
room_info.update_summary(&new_info.summary);
|
||||||
room_info.set_prev_batch(new_info.timeline.prev_batch.as_deref());
|
room_info.set_prev_batch(new_info.timeline.prev_batch.as_deref());
|
||||||
|
|
||||||
let (state, mut user_ids) = self
|
let mut user_ids = self
|
||||||
.handle_state(
|
.handle_state(
|
||||||
&mut changes,
|
&mut changes,
|
||||||
&mut ambiguity_cache,
|
&mut ambiguity_cache,
|
||||||
new_info.state.events,
|
&new_info.state.events,
|
||||||
&mut room_info,
|
&mut room_info,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -834,8 +801,7 @@ impl BaseClient {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let account_data = self
|
self.handle_room_account_data(&room_id, &new_info.account_data.events, &mut changes)
|
||||||
.handle_room_account_data(&room_id, &new_info.account_data.events, &mut changes)
|
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
|
@ -859,18 +825,15 @@ impl BaseClient {
|
||||||
let notification_count = new_info.unread_notifications.into();
|
let notification_count = new_info.unread_notifications.into();
|
||||||
room_info.update_notification_count(notification_count);
|
room_info.update_notification_count(notification_count);
|
||||||
|
|
||||||
let ephemeral = Ephemeral {
|
|
||||||
events: new_info
|
|
||||||
.ephemeral
|
|
||||||
.events
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|e| e.deserialize().ok())
|
|
||||||
.collect(),
|
|
||||||
};
|
|
||||||
|
|
||||||
new_rooms.join.insert(
|
new_rooms.join.insert(
|
||||||
room_id,
|
room_id,
|
||||||
JoinedRoom::new(timeline, state, account_data, ephemeral, notification_count),
|
JoinedRoom::new(
|
||||||
|
timeline,
|
||||||
|
new_info.state,
|
||||||
|
new_info.account_data,
|
||||||
|
new_info.ephemeral,
|
||||||
|
notification_count,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
changes.add_room(room_info);
|
changes.add_room(room_info);
|
||||||
|
@ -884,11 +847,11 @@ impl BaseClient {
|
||||||
let mut room_info = room.clone_info();
|
let mut room_info = room.clone_info();
|
||||||
room_info.mark_as_left();
|
room_info.mark_as_left();
|
||||||
|
|
||||||
let (state, mut user_ids) = self
|
let mut user_ids = self
|
||||||
.handle_state(
|
.handle_state(
|
||||||
&mut changes,
|
&mut changes,
|
||||||
&mut ambiguity_cache,
|
&mut ambiguity_cache,
|
||||||
new_info.state.events,
|
&new_info.state.events,
|
||||||
&mut room_info,
|
&mut room_info,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -905,14 +868,14 @@ impl BaseClient {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let account_data = self
|
self.handle_room_account_data(&room_id, &new_info.account_data.events, &mut changes)
|
||||||
.handle_room_account_data(&room_id, &new_info.account_data.events, &mut changes)
|
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
changes.add_room(room_info);
|
changes.add_room(room_info);
|
||||||
new_rooms
|
new_rooms.leave.insert(
|
||||||
.leave
|
room_id,
|
||||||
.insert(room_id, LeftRoom::new(timeline, state, account_data));
|
LeftRoom::new(timeline, new_info.state, new_info.account_data),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (room_id, new_info) in rooms.invite {
|
for (room_id, new_info) in rooms.invite {
|
||||||
|
@ -929,31 +892,25 @@ impl BaseClient {
|
||||||
let room = self.store.get_or_create_stripped_room(&room_id).await;
|
let room = self.store.get_or_create_stripped_room(&room_id).await;
|
||||||
let mut room_info = room.clone_info();
|
let mut room_info = room.clone_info();
|
||||||
|
|
||||||
let (state, members, state_events) =
|
let (members, state_events) =
|
||||||
self.handle_invited_state(new_info.invite_state.events, &mut room_info);
|
self.handle_invited_state(&new_info.invite_state.events, &mut room_info);
|
||||||
|
|
||||||
changes.stripped_members.insert(room_id.clone(), members);
|
changes.stripped_members.insert(room_id.clone(), members);
|
||||||
changes.stripped_state.insert(room_id.clone(), state_events);
|
changes.stripped_state.insert(room_id.clone(), state_events);
|
||||||
changes.add_stripped_room(room_info);
|
changes.add_stripped_room(room_info);
|
||||||
|
|
||||||
let room = InvitedRoom {
|
new_rooms.invite.insert(room_id, new_info);
|
||||||
invite_state: state,
|
|
||||||
};
|
|
||||||
|
|
||||||
new_rooms.invite.insert(room_id, room);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let presence: BTreeMap<UserId, PresenceEvent> = presence
|
changes.presence = presence
|
||||||
.events
|
.events
|
||||||
.into_iter()
|
.iter()
|
||||||
.filter_map(|e| {
|
.filter_map(|e| {
|
||||||
let event = e.deserialize().ok()?;
|
let event = e.deserialize().ok()?;
|
||||||
Some((event.sender.clone(), event))
|
Some((event.sender, e.clone()))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
changes.presence = presence;
|
|
||||||
|
|
||||||
changes.ambiguity_maps = ambiguity_cache.cache;
|
changes.ambiguity_maps = ambiguity_cache.cache;
|
||||||
|
|
||||||
self.store.save_changes(&changes).await?;
|
self.store.save_changes(&changes).await?;
|
||||||
|
@ -965,12 +922,8 @@ impl BaseClient {
|
||||||
let response = SyncResponse {
|
let response = SyncResponse {
|
||||||
next_batch,
|
next_batch,
|
||||||
rooms: new_rooms,
|
rooms: new_rooms,
|
||||||
presence: Presence {
|
presence,
|
||||||
events: changes.presence.into_iter().map(|(_, v)| v).collect(),
|
account_data,
|
||||||
},
|
|
||||||
account_data: AccountData {
|
|
||||||
events: changes.account_data.into_iter().map(|(_, e)| e).collect(),
|
|
||||||
},
|
|
||||||
to_device,
|
to_device,
|
||||||
device_lists,
|
device_lists,
|
||||||
device_one_time_keys_count: device_one_time_keys_count
|
device_one_time_keys_count: device_one_time_keys_count
|
||||||
|
@ -1395,14 +1348,17 @@ impl BaseClient {
|
||||||
/// Gets the push rules from `changes` if they have been updated, otherwise get them from the
|
/// Gets the push rules from `changes` if they have been updated, otherwise get them from the
|
||||||
/// store. As a fallback, uses `Ruleset::server_default` if the user is logged in.
|
/// store. As a fallback, uses `Ruleset::server_default` if the user is logged in.
|
||||||
pub async fn get_push_rules(&self, changes: &StateChanges) -> Result<Ruleset> {
|
pub async fn get_push_rules(&self, changes: &StateChanges) -> Result<Ruleset> {
|
||||||
if let Some(AnyBasicEvent::PushRules(event)) =
|
if let Some(AnyBasicEvent::PushRules(event)) = changes
|
||||||
changes.account_data.get(&EventType::PushRules.to_string())
|
.account_data
|
||||||
|
.get(EventType::PushRules.as_str())
|
||||||
|
.and_then(|e| e.deserialize().ok())
|
||||||
{
|
{
|
||||||
Ok(event.content.global.clone())
|
Ok(event.content.global)
|
||||||
} else if let Some(AnyBasicEvent::PushRules(event)) = self
|
} else if let Some(AnyBasicEvent::PushRules(event)) = self
|
||||||
.store
|
.store
|
||||||
.get_account_data_event(EventType::PushRules)
|
.get_account_data_event(EventType::PushRules)
|
||||||
.await?
|
.await?
|
||||||
|
.and_then(|e| e.deserialize().ok())
|
||||||
{
|
{
|
||||||
Ok(event.content.global)
|
Ok(event.content.global)
|
||||||
} else if let Some(session) = self.get_session().await {
|
} else if let Some(session) = self.get_session().await {
|
||||||
|
@ -1451,12 +1407,14 @@ impl BaseClient {
|
||||||
.get(room_id)
|
.get(room_id)
|
||||||
.and_then(|types| types.get(EventType::RoomPowerLevels.as_str()))
|
.and_then(|types| types.get(EventType::RoomPowerLevels.as_str()))
|
||||||
.and_then(|events| events.get(""))
|
.and_then(|events| events.get(""))
|
||||||
|
.and_then(|e| e.deserialize().ok())
|
||||||
{
|
{
|
||||||
event.content.clone()
|
event.content
|
||||||
} else if let Some(AnySyncStateEvent::RoomPowerLevels(event)) = self
|
} else if let Some(AnySyncStateEvent::RoomPowerLevels(event)) = self
|
||||||
.store
|
.store
|
||||||
.get_state_event(room_id, EventType::RoomPowerLevels, "")
|
.get_state_event(room_id, EventType::RoomPowerLevels, "")
|
||||||
.await?
|
.await?
|
||||||
|
.and_then(|e| e.deserialize().ok())
|
||||||
{
|
{
|
||||||
event.content
|
event.content
|
||||||
} else {
|
} else {
|
||||||
|
@ -1504,8 +1462,9 @@ impl BaseClient {
|
||||||
.get(room_id)
|
.get(room_id)
|
||||||
.and_then(|types| types.get(EventType::RoomPowerLevels.as_str()))
|
.and_then(|types| types.get(EventType::RoomPowerLevels.as_str()))
|
||||||
.and_then(|events| events.get(""))
|
.and_then(|events| events.get(""))
|
||||||
|
.and_then(|e| e.deserialize().ok())
|
||||||
{
|
{
|
||||||
let room_power_levels = event.content.clone();
|
let room_power_levels = event.content;
|
||||||
|
|
||||||
push_rules.users_power_levels = room_power_levels.users;
|
push_rules.users_power_levels = room_power_levels.users;
|
||||||
push_rules.default_power_level = room_power_levels.users_default;
|
push_rules.default_power_level = room_power_levels.users_default;
|
||||||
|
|
|
@ -393,7 +393,11 @@ impl Room {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
|
|
||||||
let presence = self.store.get_presence_event(user_id).await?;
|
let presence = self
|
||||||
|
.store
|
||||||
|
.get_presence_event(user_id)
|
||||||
|
.await?
|
||||||
|
.and_then(|e| e.deserialize().ok());
|
||||||
let profile = self.store.get_profile(self.room_id(), user_id).await?;
|
let profile = self.store.get_profile(self.room_id(), user_id).await?;
|
||||||
let max_power_level = self.max_power_level();
|
let max_power_level = self.max_power_level();
|
||||||
let is_room_creator = self
|
let is_room_creator = self
|
||||||
|
@ -410,6 +414,7 @@ impl Room {
|
||||||
.store
|
.store
|
||||||
.get_state_event(self.room_id(), EventType::RoomPowerLevels, "")
|
.get_state_event(self.room_id(), EventType::RoomPowerLevels, "")
|
||||||
.await?
|
.await?
|
||||||
|
.and_then(|e| e.deserialize().ok())
|
||||||
.and_then(|e| {
|
.and_then(|e| {
|
||||||
if let AnySyncStateEvent::RoomPowerLevels(e) = e {
|
if let AnySyncStateEvent::RoomPowerLevels(e) = e {
|
||||||
Some(e)
|
Some(e)
|
||||||
|
|
|
@ -23,10 +23,11 @@ use matrix_sdk_common::{
|
||||||
events::{
|
events::{
|
||||||
presence::PresenceEvent,
|
presence::PresenceEvent,
|
||||||
room::member::{MemberEventContent, MembershipState},
|
room::member::{MemberEventContent, MembershipState},
|
||||||
AnyBasicEvent, AnyStrippedStateEvent, AnySyncStateEvent, EventContent, EventType,
|
AnyBasicEvent, AnyStrippedStateEvent, AnySyncStateEvent, EventType,
|
||||||
},
|
},
|
||||||
identifiers::{RoomId, UserId},
|
identifiers::{RoomId, UserId},
|
||||||
instant::Instant,
|
instant::Instant,
|
||||||
|
Raw,
|
||||||
};
|
};
|
||||||
|
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
@ -39,7 +40,7 @@ use super::{Result, RoomInfo, StateChanges, StateStore};
|
||||||
pub struct MemoryStore {
|
pub struct MemoryStore {
|
||||||
sync_token: Arc<RwLock<Option<String>>>,
|
sync_token: Arc<RwLock<Option<String>>>,
|
||||||
filters: Arc<DashMap<String, String>>,
|
filters: Arc<DashMap<String, String>>,
|
||||||
account_data: Arc<DashMap<String, AnyBasicEvent>>,
|
account_data: Arc<DashMap<String, Raw<AnyBasicEvent>>>,
|
||||||
members: Arc<DashMap<RoomId, DashMap<UserId, MemberEvent>>>,
|
members: Arc<DashMap<RoomId, DashMap<UserId, MemberEvent>>>,
|
||||||
profiles: Arc<DashMap<RoomId, DashMap<UserId, MemberEventContent>>>,
|
profiles: Arc<DashMap<RoomId, DashMap<UserId, MemberEventContent>>>,
|
||||||
display_names: Arc<DashMap<RoomId, DashMap<String, BTreeSet<UserId>>>>,
|
display_names: Arc<DashMap<RoomId, DashMap<String, BTreeSet<UserId>>>>,
|
||||||
|
@ -47,14 +48,14 @@ pub struct MemoryStore {
|
||||||
invited_user_ids: Arc<DashMap<RoomId, DashSet<UserId>>>,
|
invited_user_ids: Arc<DashMap<RoomId, DashSet<UserId>>>,
|
||||||
room_info: Arc<DashMap<RoomId, RoomInfo>>,
|
room_info: Arc<DashMap<RoomId, RoomInfo>>,
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
room_state: Arc<DashMap<RoomId, DashMap<String, DashMap<String, AnySyncStateEvent>>>>,
|
room_state: Arc<DashMap<RoomId, DashMap<String, DashMap<String, Raw<AnySyncStateEvent>>>>>,
|
||||||
room_account_data: Arc<DashMap<RoomId, DashMap<String, AnyBasicEvent>>>,
|
room_account_data: Arc<DashMap<RoomId, DashMap<String, Raw<AnyBasicEvent>>>>,
|
||||||
stripped_room_info: Arc<DashMap<RoomId, RoomInfo>>,
|
stripped_room_info: Arc<DashMap<RoomId, RoomInfo>>,
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
stripped_room_state:
|
stripped_room_state:
|
||||||
Arc<DashMap<RoomId, DashMap<String, DashMap<String, AnyStrippedStateEvent>>>>,
|
Arc<DashMap<RoomId, DashMap<String, DashMap<String, Raw<AnyStrippedStateEvent>>>>>,
|
||||||
stripped_members: Arc<DashMap<RoomId, DashMap<UserId, StrippedMemberEvent>>>,
|
stripped_members: Arc<DashMap<RoomId, DashMap<UserId, StrippedMemberEvent>>>,
|
||||||
presence: Arc<DashMap<UserId, PresenceEvent>>,
|
presence: Arc<DashMap<UserId, Raw<PresenceEvent>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MemoryStore {
|
impl MemoryStore {
|
||||||
|
@ -176,14 +177,14 @@ impl MemoryStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (room, event_types) in &changes.state {
|
for (room, event_types) in &changes.state {
|
||||||
for events in event_types.values() {
|
for (event_type, events) in event_types {
|
||||||
for event in events.values() {
|
for (state_key, event) in events {
|
||||||
self.room_state
|
self.room_state
|
||||||
.entry(room.clone())
|
.entry(room.clone())
|
||||||
.or_insert_with(DashMap::new)
|
.or_insert_with(DashMap::new)
|
||||||
.entry(event.content().event_type().to_string())
|
.entry(event_type.to_owned())
|
||||||
.or_insert_with(DashMap::new)
|
.or_insert_with(DashMap::new)
|
||||||
.insert(event.state_key().to_string(), event.clone());
|
.insert(state_key.to_owned(), event.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,14 +212,14 @@ impl MemoryStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (room, event_types) in &changes.stripped_state {
|
for (room, event_types) in &changes.stripped_state {
|
||||||
for events in event_types.values() {
|
for (event_type, events) in event_types {
|
||||||
for event in events.values() {
|
for (state_key, event) in events {
|
||||||
self.stripped_room_state
|
self.stripped_room_state
|
||||||
.entry(room.clone())
|
.entry(room.clone())
|
||||||
.or_insert_with(DashMap::new)
|
.or_insert_with(DashMap::new)
|
||||||
.entry(event.content().event_type().to_string())
|
.entry(event_type.to_owned())
|
||||||
.or_insert_with(DashMap::new)
|
.or_insert_with(DashMap::new)
|
||||||
.insert(event.state_key().to_string(), event.clone());
|
.insert(state_key.to_owned(), event.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,7 +229,7 @@ impl MemoryStore {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_presence_event(&self, user_id: &UserId) -> Result<Option<PresenceEvent>> {
|
async fn get_presence_event(&self, user_id: &UserId) -> Result<Option<Raw<PresenceEvent>>> {
|
||||||
#[allow(clippy::map_clone)]
|
#[allow(clippy::map_clone)]
|
||||||
Ok(self.presence.get(user_id).map(|p| p.clone()))
|
Ok(self.presence.get(user_id).map(|p| p.clone()))
|
||||||
}
|
}
|
||||||
|
@ -238,7 +239,7 @@ impl MemoryStore {
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
event_type: EventType,
|
event_type: EventType,
|
||||||
state_key: &str,
|
state_key: &str,
|
||||||
) -> Result<Option<AnySyncStateEvent>> {
|
) -> Result<Option<Raw<AnySyncStateEvent>>> {
|
||||||
#[allow(clippy::map_clone)]
|
#[allow(clippy::map_clone)]
|
||||||
Ok(self.room_state.get(room_id).and_then(|e| {
|
Ok(self.room_state.get(room_id).and_then(|e| {
|
||||||
e.get(event_type.as_ref())
|
e.get(event_type.as_ref())
|
||||||
|
@ -304,7 +305,10 @@ impl MemoryStore {
|
||||||
self.stripped_room_info.iter().map(|r| r.clone()).collect()
|
self.stripped_room_info.iter().map(|r| r.clone()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_account_data_event(&self, event_type: EventType) -> Result<Option<AnyBasicEvent>> {
|
async fn get_account_data_event(
|
||||||
|
&self,
|
||||||
|
event_type: EventType,
|
||||||
|
) -> Result<Option<Raw<AnyBasicEvent>>> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.account_data
|
.account_data
|
||||||
.get(event_type.as_ref())
|
.get(event_type.as_ref())
|
||||||
|
@ -331,7 +335,7 @@ impl StateStore for MemoryStore {
|
||||||
self.get_sync_token().await
|
self.get_sync_token().await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_presence_event(&self, user_id: &UserId) -> Result<Option<PresenceEvent>> {
|
async fn get_presence_event(&self, user_id: &UserId) -> Result<Option<Raw<PresenceEvent>>> {
|
||||||
self.get_presence_event(user_id).await
|
self.get_presence_event(user_id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +344,7 @@ impl StateStore for MemoryStore {
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
event_type: EventType,
|
event_type: EventType,
|
||||||
state_key: &str,
|
state_key: &str,
|
||||||
) -> Result<Option<AnySyncStateEvent>> {
|
) -> Result<Option<Raw<AnySyncStateEvent>>> {
|
||||||
self.get_state_event(room_id, event_type, state_key).await
|
self.get_state_event(room_id, event_type, state_key).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,7 +397,10 @@ impl StateStore for MemoryStore {
|
||||||
.unwrap_or_default())
|
.unwrap_or_default())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_account_data_event(&self, event_type: EventType) -> Result<Option<AnyBasicEvent>> {
|
async fn get_account_data_event(
|
||||||
|
&self,
|
||||||
|
event_type: EventType,
|
||||||
|
) -> Result<Option<Raw<AnyBasicEvent>>> {
|
||||||
self.get_account_data_event(event_type).await
|
self.get_account_data_event(event_type).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ use matrix_sdk_common::{
|
||||||
},
|
},
|
||||||
identifiers::{RoomId, UserId},
|
identifiers::{RoomId, UserId},
|
||||||
locks::RwLock,
|
locks::RwLock,
|
||||||
AsyncTraitDeps,
|
AsyncTraitDeps, Raw,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "sled_state_store")]
|
#[cfg(feature = "sled_state_store")]
|
||||||
use sled::Db;
|
use sled::Db;
|
||||||
|
@ -114,7 +114,7 @@ pub trait StateStore: AsyncTraitDeps {
|
||||||
///
|
///
|
||||||
/// * `user_id` - The id of the user for which we wish to fetch the presence
|
/// * `user_id` - The id of the user for which we wish to fetch the presence
|
||||||
/// event for.
|
/// event for.
|
||||||
async fn get_presence_event(&self, user_id: &UserId) -> Result<Option<PresenceEvent>>;
|
async fn get_presence_event(&self, user_id: &UserId) -> Result<Option<Raw<PresenceEvent>>>;
|
||||||
|
|
||||||
/// Get a state event out of the state store.
|
/// Get a state event out of the state store.
|
||||||
///
|
///
|
||||||
|
@ -128,7 +128,7 @@ pub trait StateStore: AsyncTraitDeps {
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
event_type: EventType,
|
event_type: EventType,
|
||||||
state_key: &str,
|
state_key: &str,
|
||||||
) -> Result<Option<AnySyncStateEvent>>;
|
) -> Result<Option<Raw<AnySyncStateEvent>>>;
|
||||||
|
|
||||||
/// Get the current profile for the given user in the given room.
|
/// Get the current profile for the given user in the given room.
|
||||||
///
|
///
|
||||||
|
@ -192,7 +192,10 @@ pub trait StateStore: AsyncTraitDeps {
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `event_type` - The event type of the account data event.
|
/// * `event_type` - The event type of the account data event.
|
||||||
async fn get_account_data_event(&self, event_type: EventType) -> Result<Option<AnyBasicEvent>>;
|
async fn get_account_data_event(
|
||||||
|
&self,
|
||||||
|
event_type: EventType,
|
||||||
|
) -> Result<Option<Raw<AnyBasicEvent>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A state store wrapper for the SDK.
|
/// A state store wrapper for the SDK.
|
||||||
|
@ -345,30 +348,33 @@ pub struct StateChanges {
|
||||||
/// A user session, containing an access token and information about the associated user account.
|
/// A user session, containing an access token and information about the associated user account.
|
||||||
pub session: Option<Session>,
|
pub session: Option<Session>,
|
||||||
/// A mapping of event type string to `AnyBasicEvent`.
|
/// A mapping of event type string to `AnyBasicEvent`.
|
||||||
pub account_data: BTreeMap<String, AnyBasicEvent>,
|
pub account_data: BTreeMap<String, Raw<AnyBasicEvent>>,
|
||||||
/// A mapping of `UserId` to `PresenceEvent`.
|
/// A mapping of `UserId` to `PresenceEvent`.
|
||||||
pub presence: BTreeMap<UserId, PresenceEvent>,
|
pub presence: BTreeMap<UserId, Raw<PresenceEvent>>,
|
||||||
|
|
||||||
/// A mapping of `RoomId` to a map of users and their `MemberEvent`.
|
/// A mapping of `RoomId` to a map of users and their `MemberEvent`.
|
||||||
pub members: BTreeMap<RoomId, BTreeMap<UserId, MemberEvent>>,
|
pub members: BTreeMap<RoomId, BTreeMap<UserId, MemberEvent>>,
|
||||||
/// A mapping of `RoomId` to a map of users and their `MemberEventContent`.
|
/// A mapping of `RoomId` to a map of users and their `MemberEventContent`.
|
||||||
pub profiles: BTreeMap<RoomId, BTreeMap<UserId, MemberEventContent>>,
|
pub profiles: BTreeMap<RoomId, BTreeMap<UserId, MemberEventContent>>,
|
||||||
|
|
||||||
pub(crate) ambiguity_maps: BTreeMap<RoomId, BTreeMap<String, BTreeSet<UserId>>>,
|
|
||||||
/// A mapping of `RoomId` to a map of event type string to a state key and `AnySyncStateEvent`.
|
/// A mapping of `RoomId` to a map of event type string to a state key and `AnySyncStateEvent`.
|
||||||
pub state: BTreeMap<RoomId, BTreeMap<String, BTreeMap<String, AnySyncStateEvent>>>,
|
pub state: BTreeMap<RoomId, BTreeMap<String, BTreeMap<String, Raw<AnySyncStateEvent>>>>,
|
||||||
/// A mapping of `RoomId` to a map of event type string to `AnyBasicEvent`.
|
/// A mapping of `RoomId` to a map of event type string to `AnyBasicEvent`.
|
||||||
pub room_account_data: BTreeMap<RoomId, BTreeMap<String, AnyBasicEvent>>,
|
pub room_account_data: BTreeMap<RoomId, BTreeMap<String, Raw<AnyBasicEvent>>>,
|
||||||
/// A map of `RoomId` to `RoomInfo`.
|
/// A map of `RoomId` to `RoomInfo`.
|
||||||
pub room_infos: BTreeMap<RoomId, RoomInfo>,
|
pub room_infos: BTreeMap<RoomId, RoomInfo>,
|
||||||
|
|
||||||
/// A mapping of `RoomId` to a map of event type to a map of state key to `AnyStrippedStateEvent`.
|
/// A mapping of `RoomId` to a map of event type to a map of state key to `AnyStrippedStateEvent`.
|
||||||
pub stripped_state: BTreeMap<RoomId, BTreeMap<String, BTreeMap<String, AnyStrippedStateEvent>>>,
|
pub stripped_state:
|
||||||
|
BTreeMap<RoomId, BTreeMap<String, BTreeMap<String, Raw<AnyStrippedStateEvent>>>>,
|
||||||
/// A mapping of `RoomId` to a map of users and their `StrippedMemberEvent`.
|
/// A mapping of `RoomId` to a map of users and their `StrippedMemberEvent`.
|
||||||
pub stripped_members: BTreeMap<RoomId, BTreeMap<UserId, StrippedMemberEvent>>,
|
pub stripped_members: BTreeMap<RoomId, BTreeMap<UserId, StrippedMemberEvent>>,
|
||||||
/// A map of `RoomId` to `RoomInfo`.
|
/// A map of `RoomId` to `RoomInfo`.
|
||||||
pub invited_room_info: BTreeMap<RoomId, RoomInfo>,
|
pub invited_room_info: BTreeMap<RoomId, RoomInfo>,
|
||||||
|
|
||||||
|
/// A map from room id to a map of a display name and a set of user ids that
|
||||||
|
/// share that display name in the given room.
|
||||||
|
pub ambiguity_maps: BTreeMap<RoomId, BTreeMap<String, BTreeSet<UserId>>>,
|
||||||
/// A map of `RoomId` to a vector of `Notification`s
|
/// A map of `RoomId` to a vector of `Notification`s
|
||||||
pub notifications: BTreeMap<RoomId, Vec<Notification>>,
|
pub notifications: BTreeMap<RoomId, Vec<Notification>>,
|
||||||
}
|
}
|
||||||
|
@ -383,8 +389,8 @@ impl StateChanges {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the `StateChanges` struct with the given `PresenceEvent`.
|
/// Update the `StateChanges` struct with the given `PresenceEvent`.
|
||||||
pub fn add_presence_event(&mut self, event: PresenceEvent) {
|
pub fn add_presence_event(&mut self, event: PresenceEvent, raw_event: Raw<PresenceEvent>) {
|
||||||
self.presence.insert(event.sender.clone(), event);
|
self.presence.insert(event.sender, raw_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the `StateChanges` struct with the given `RoomInfo`.
|
/// Update the `StateChanges` struct with the given `RoomInfo`.
|
||||||
|
@ -400,27 +406,22 @@ impl StateChanges {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the `StateChanges` struct with the given `AnyBasicEvent`.
|
/// Update the `StateChanges` struct with the given `AnyBasicEvent`.
|
||||||
pub fn add_account_data(&mut self, event: AnyBasicEvent) {
|
pub fn add_account_data(&mut self, event: AnyBasicEvent, raw_event: Raw<AnyBasicEvent>) {
|
||||||
self.account_data
|
self.account_data
|
||||||
.insert(event.content().event_type().to_owned(), event);
|
.insert(event.content().event_type().to_owned(), raw_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the `StateChanges` struct with the given room with a new `AnyBasicEvent`.
|
/// Update the `StateChanges` struct with the given room with a new `AnyBasicEvent`.
|
||||||
pub fn add_room_account_data(&mut self, room_id: &RoomId, event: AnyBasicEvent) {
|
pub fn add_room_account_data(
|
||||||
|
&mut self,
|
||||||
|
room_id: &RoomId,
|
||||||
|
event: AnyBasicEvent,
|
||||||
|
raw_event: Raw<AnyBasicEvent>,
|
||||||
|
) {
|
||||||
self.room_account_data
|
self.room_account_data
|
||||||
.entry(room_id.to_owned())
|
.entry(room_id.to_owned())
|
||||||
.or_insert_with(BTreeMap::new)
|
.or_insert_with(BTreeMap::new)
|
||||||
.insert(event.content().event_type().to_owned(), event);
|
.insert(event.content().event_type().to_owned(), raw_event);
|
||||||
}
|
|
||||||
|
|
||||||
/// Update the `StateChanges` struct with the given room with a new `AnyStrippedStateEvent`.
|
|
||||||
pub fn add_stripped_state_event(&mut self, room_id: &RoomId, event: AnyStrippedStateEvent) {
|
|
||||||
self.stripped_state
|
|
||||||
.entry(room_id.to_owned())
|
|
||||||
.or_insert_with(BTreeMap::new)
|
|
||||||
.entry(event.content().event_type().to_string())
|
|
||||||
.or_insert_with(BTreeMap::new)
|
|
||||||
.insert(event.state_key().to_string(), event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the `StateChanges` struct with the given room with a new `StrippedMemberEvent`.
|
/// Update the `StateChanges` struct with the given room with a new `StrippedMemberEvent`.
|
||||||
|
@ -434,13 +435,18 @@ impl StateChanges {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the `StateChanges` struct with the given room with a new `AnySyncStateEvent`.
|
/// Update the `StateChanges` struct with the given room with a new `AnySyncStateEvent`.
|
||||||
pub fn add_state_event(&mut self, room_id: &RoomId, event: AnySyncStateEvent) {
|
pub fn add_state_event(
|
||||||
|
&mut self,
|
||||||
|
room_id: &RoomId,
|
||||||
|
event: AnySyncStateEvent,
|
||||||
|
raw_event: Raw<AnySyncStateEvent>,
|
||||||
|
) {
|
||||||
self.state
|
self.state
|
||||||
.entry(room_id.to_owned())
|
.entry(room_id.to_owned())
|
||||||
.or_insert_with(BTreeMap::new)
|
.or_insert_with(BTreeMap::new)
|
||||||
.entry(event.content().event_type().to_string())
|
.entry(event.content().event_type().to_string())
|
||||||
.or_insert_with(BTreeMap::new)
|
.or_insert_with(BTreeMap::new)
|
||||||
.insert(event.state_key().to_string(), event);
|
.insert(event.state_key().to_string(), raw_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the `StateChanges` struct with the given room with a new `Notification`.
|
/// Update the `StateChanges` struct with the given room with a new `Notification`.
|
||||||
|
|
|
@ -31,9 +31,10 @@ use matrix_sdk_common::{
|
||||||
events::{
|
events::{
|
||||||
presence::PresenceEvent,
|
presence::PresenceEvent,
|
||||||
room::member::{MemberEventContent, MembershipState},
|
room::member::{MemberEventContent, MembershipState},
|
||||||
AnyBasicEvent, AnySyncStateEvent, EventContent, EventType,
|
AnyBasicEvent, AnySyncStateEvent, EventType,
|
||||||
},
|
},
|
||||||
identifiers::{RoomId, UserId},
|
identifiers::{RoomId, UserId},
|
||||||
|
Raw,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -405,14 +406,10 @@ impl SledStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (room, event_types) in &changes.state {
|
for (room, event_types) in &changes.state {
|
||||||
for events in event_types.values() {
|
for (event_type, events) in event_types {
|
||||||
for event in events.values() {
|
for (state_key, event) in events {
|
||||||
state.insert(
|
state.insert(
|
||||||
(
|
(room.as_str(), event_type.as_str(), state_key.as_str())
|
||||||
room.as_str(),
|
|
||||||
event.content().event_type(),
|
|
||||||
event.state_key(),
|
|
||||||
)
|
|
||||||
.encode(),
|
.encode(),
|
||||||
self.serialize_event(&event)
|
self.serialize_event(&event)
|
||||||
.map_err(ConflictableTransactionError::Abort)?,
|
.map_err(ConflictableTransactionError::Abort)?,
|
||||||
|
@ -456,14 +453,10 @@ impl SledStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (room, event_types) in &changes.stripped_state {
|
for (room, event_types) in &changes.stripped_state {
|
||||||
for events in event_types.values() {
|
for (event_type, events) in event_types {
|
||||||
for event in events.values() {
|
for (state_key, event) in events {
|
||||||
stripped_state.insert(
|
stripped_state.insert(
|
||||||
(
|
(room.as_str(), event_type.as_str(), state_key.as_str())
|
||||||
room.as_str(),
|
|
||||||
event.content().event_type(),
|
|
||||||
event.state_key(),
|
|
||||||
)
|
|
||||||
.encode(),
|
.encode(),
|
||||||
self.serialize_event(&event)
|
self.serialize_event(&event)
|
||||||
.map_err(ConflictableTransactionError::Abort)?,
|
.map_err(ConflictableTransactionError::Abort)?,
|
||||||
|
@ -485,7 +478,7 @@ impl SledStore {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_presence_event(&self, user_id: &UserId) -> Result<Option<PresenceEvent>> {
|
pub async fn get_presence_event(&self, user_id: &UserId) -> Result<Option<Raw<PresenceEvent>>> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.presence
|
.presence
|
||||||
.get(user_id.encode())?
|
.get(user_id.encode())?
|
||||||
|
@ -498,7 +491,7 @@ impl SledStore {
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
event_type: EventType,
|
event_type: EventType,
|
||||||
state_key: &str,
|
state_key: &str,
|
||||||
) -> Result<Option<AnySyncStateEvent>> {
|
) -> Result<Option<Raw<AnySyncStateEvent>>> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.room_state
|
.room_state
|
||||||
.get((room_id.as_str(), event_type.as_str(), state_key).encode())?
|
.get((room_id.as_str(), event_type.as_str(), state_key).encode())?
|
||||||
|
@ -597,7 +590,7 @@ impl SledStore {
|
||||||
pub async fn get_account_data_event(
|
pub async fn get_account_data_event(
|
||||||
&self,
|
&self,
|
||||||
event_type: EventType,
|
event_type: EventType,
|
||||||
) -> Result<Option<AnyBasicEvent>> {
|
) -> Result<Option<Raw<AnyBasicEvent>>> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.account_data
|
.account_data
|
||||||
.get(event_type.encode())?
|
.get(event_type.encode())?
|
||||||
|
@ -624,7 +617,7 @@ impl StateStore for SledStore {
|
||||||
self.get_sync_token().await
|
self.get_sync_token().await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_presence_event(&self, user_id: &UserId) -> Result<Option<PresenceEvent>> {
|
async fn get_presence_event(&self, user_id: &UserId) -> Result<Option<Raw<PresenceEvent>>> {
|
||||||
self.get_presence_event(user_id).await
|
self.get_presence_event(user_id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,7 +626,7 @@ impl StateStore for SledStore {
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
event_type: EventType,
|
event_type: EventType,
|
||||||
state_key: &str,
|
state_key: &str,
|
||||||
) -> Result<Option<AnySyncStateEvent>> {
|
) -> Result<Option<Raw<AnySyncStateEvent>>> {
|
||||||
self.get_state_event(room_id, event_type, state_key).await
|
self.get_state_event(room_id, event_type, state_key).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,7 +675,10 @@ impl StateStore for SledStore {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_account_data_event(&self, event_type: EventType) -> Result<Option<AnyBasicEvent>> {
|
async fn get_account_data_event(
|
||||||
|
&self,
|
||||||
|
event_type: EventType,
|
||||||
|
) -> Result<Option<Raw<AnyBasicEvent>>> {
|
||||||
self.get_account_data_event(event_type).await
|
self.get_account_data_event(event_type).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -693,12 +689,17 @@ mod test {
|
||||||
|
|
||||||
use matrix_sdk_common::{
|
use matrix_sdk_common::{
|
||||||
events::{
|
events::{
|
||||||
room::member::{MemberEventContent, MembershipState},
|
room::{
|
||||||
Unsigned,
|
member::{MemberEventContent, MembershipState},
|
||||||
|
power_levels::PowerLevelsEventContent,
|
||||||
|
},
|
||||||
|
AnySyncStateEvent, EventType, Unsigned,
|
||||||
},
|
},
|
||||||
identifiers::{room_id, user_id, EventId, UserId},
|
identifiers::{room_id, user_id, EventId, UserId},
|
||||||
|
Raw,
|
||||||
};
|
};
|
||||||
use matrix_sdk_test::async_test;
|
use matrix_sdk_test::async_test;
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
use super::{SledStore, StateChanges};
|
use super::{SledStore, StateChanges};
|
||||||
use crate::deserialized_responses::MemberEvent;
|
use crate::deserialized_responses::MemberEvent;
|
||||||
|
@ -707,6 +708,22 @@ mod test {
|
||||||
user_id!("@example:localhost")
|
user_id!("@example:localhost")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn power_level_event() -> Raw<AnySyncStateEvent> {
|
||||||
|
let content = PowerLevelsEventContent::default();
|
||||||
|
|
||||||
|
let event = json!({
|
||||||
|
"event_id": EventId::try_from("$h29iv0s8:example.com").unwrap(),
|
||||||
|
"content": content,
|
||||||
|
"sender": user_id(),
|
||||||
|
"type": "m.room.power_levels",
|
||||||
|
"origin_server_ts": 0u64,
|
||||||
|
"state_key": "",
|
||||||
|
"unsigned": Unsigned::default(),
|
||||||
|
});
|
||||||
|
|
||||||
|
serde_json::from_value(event).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
fn membership_event() -> MemberEvent {
|
fn membership_event() -> MemberEvent {
|
||||||
let content = MemberEventContent {
|
let content = MemberEventContent {
|
||||||
avatar_url: None,
|
avatar_url: None,
|
||||||
|
@ -752,4 +769,28 @@ mod test {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_some());
|
.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_test]
|
||||||
|
async fn test_power_level_saving() {
|
||||||
|
let store = SledStore::open().unwrap();
|
||||||
|
let room_id = room_id!("!test:localhost");
|
||||||
|
|
||||||
|
let raw_event = power_level_event();
|
||||||
|
let event = raw_event.deserialize().unwrap();
|
||||||
|
|
||||||
|
assert!(store
|
||||||
|
.get_state_event(&room_id, EventType::RoomPowerLevels, "")
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.is_none());
|
||||||
|
let mut changes = StateChanges::default();
|
||||||
|
changes.add_state_event(&room_id, event, raw_event);
|
||||||
|
|
||||||
|
store.save_changes(&changes).await.unwrap();
|
||||||
|
assert!(store
|
||||||
|
.get_state_event(&room_id, EventType::RoomPowerLevels, "")
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.is_some());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
use ruma::{
|
||||||
|
api::client::r0::sync::sync_events::{
|
||||||
|
AccountData, Ephemeral, InvitedRoom, Presence, State, ToDevice,
|
||||||
|
},
|
||||||
|
serde::Raw,
|
||||||
|
DeviceIdBox,
|
||||||
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{collections::BTreeMap, convert::TryFrom, time::SystemTime};
|
use std::{collections::BTreeMap, convert::TryFrom, time::SystemTime};
|
||||||
|
|
||||||
|
@ -9,9 +16,8 @@ use super::{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
events::{
|
events::{
|
||||||
presence::PresenceEvent, room::member::MemberEventContent, AnyBasicEvent,
|
room::member::MemberEventContent, AnySyncRoomEvent, StateEvent, StrippedStateEvent,
|
||||||
AnyStrippedStateEvent, AnySyncEphemeralRoomEvent, AnySyncRoomEvent, AnySyncStateEvent,
|
SyncStateEvent, Unsigned,
|
||||||
AnyToDeviceEvent, StateEvent, StrippedStateEvent, SyncStateEvent, Unsigned,
|
|
||||||
},
|
},
|
||||||
identifiers::{DeviceKeyAlgorithm, EventId, RoomId, UserId},
|
identifiers::{DeviceKeyAlgorithm, EventId, RoomId, UserId},
|
||||||
};
|
};
|
||||||
|
@ -37,6 +43,72 @@ pub struct AmbiguityChanges {
|
||||||
pub changes: BTreeMap<RoomId, BTreeMap<EventId, AmbiguityChange>>,
|
pub changes: BTreeMap<RoomId, BTreeMap<EventId, AmbiguityChange>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The verification state of the device that sent an event to us.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub enum VerificationState {
|
||||||
|
/// The device is trusted.
|
||||||
|
Trusted,
|
||||||
|
/// The device is not trusted.
|
||||||
|
Untrusted,
|
||||||
|
/// The device is not known to us.
|
||||||
|
UnknownDevice,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The algorithm specific information of a decrypted event.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub enum AlgorithmInfo {
|
||||||
|
/// The info if the event was encrypted using m.megolm.v1.aes-sha2
|
||||||
|
MegolmV1AesSha2 {
|
||||||
|
/// The curve25519 key of the device that created the megolm decryption
|
||||||
|
/// key originally.
|
||||||
|
curve25519_key: String,
|
||||||
|
/// The signing keys that have created the megolm key that was used to
|
||||||
|
/// decrypt this session. This map will usually contain a signle ed25519
|
||||||
|
/// key.
|
||||||
|
sender_claimed_keys: BTreeMap<DeviceKeyAlgorithm, String>,
|
||||||
|
/// Chain of curve25519 keys through which this session was forwarded,
|
||||||
|
/// via m.forwarded_room_key events.
|
||||||
|
forwarding_curve25519_key_chain: Vec<String>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Struct containing information on how an event was decrypted.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct EncryptionInfo {
|
||||||
|
/// The user ID of the event sender, note this is untrusted data unless the
|
||||||
|
/// `verification_state` is as well trusted.
|
||||||
|
pub sender: UserId,
|
||||||
|
/// The device ID of the device that sent us the event, note this is
|
||||||
|
/// untrusted data unless `verification_state` is as well trusted.
|
||||||
|
pub sender_device: DeviceIdBox,
|
||||||
|
/// Information about the algorithm that was used to encrypt the event.
|
||||||
|
pub algorithm_info: AlgorithmInfo,
|
||||||
|
/// The verification state of the device that sent us the event, note this
|
||||||
|
/// is the state of the device at the time of decryption. It may change in
|
||||||
|
/// the future if a device gets verified or deleted.
|
||||||
|
pub verification_state: VerificationState,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A customized version of a room event coming from a sync that holds optional
|
||||||
|
/// encryption info.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct SyncRoomEvent {
|
||||||
|
/// The actual event.
|
||||||
|
pub event: Raw<AnySyncRoomEvent>,
|
||||||
|
/// The encryption info about the event. Will be `None` if the event was not
|
||||||
|
/// encrypted.
|
||||||
|
pub encryption_info: Option<EncryptionInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Raw<AnySyncRoomEvent>> for SyncRoomEvent {
|
||||||
|
fn from(inner: Raw<AnySyncRoomEvent>) -> Self {
|
||||||
|
Self {
|
||||||
|
encryption_info: None,
|
||||||
|
event: inner,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||||
pub struct SyncResponse {
|
pub struct SyncResponse {
|
||||||
/// The batch token to supply in the `since` param of the next `/sync` request.
|
/// The batch token to supply in the `since` param of the next `/sync` request.
|
||||||
|
@ -71,33 +143,6 @@ impl SyncResponse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates to the presence status of other users.
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
|
||||||
pub struct Presence {
|
|
||||||
/// A list of events.
|
|
||||||
pub events: Vec<PresenceEvent>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Data that the user has attached to either the account or a specific room.
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
|
||||||
pub struct AccountData {
|
|
||||||
/// The list of account data events.
|
|
||||||
pub events: Vec<AnyBasicEvent>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Messages sent dirrectly between devices.
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
|
||||||
pub struct ToDevice {
|
|
||||||
/// A list of events.
|
|
||||||
pub events: Vec<AnyToDeviceEvent>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Vec<AnyToDeviceEvent>> for ToDevice {
|
|
||||||
fn from(events: Vec<AnyToDeviceEvent>) -> Self {
|
|
||||||
Self { events }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||||
pub struct Rooms {
|
pub struct Rooms {
|
||||||
/// The rooms that the user has left or been banned from.
|
/// The rooms that the user has left or been banned from.
|
||||||
|
@ -144,20 +189,6 @@ impl JoinedRoom {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates to the rooms that the user has been invited to.
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
|
||||||
pub struct InvitedRoom {
|
|
||||||
/// The state of a room that the user has been invited to.
|
|
||||||
pub invite_state: InviteState,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The state of a room that the user has been invited to.
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
|
||||||
pub struct InviteState {
|
|
||||||
/// A list of state events.
|
|
||||||
pub events: Vec<AnyStrippedStateEvent>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Counts of unread notifications for a room.
|
/// Counts of unread notifications for a room.
|
||||||
#[derive(Copy, Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Copy, Clone, Debug, Default, Deserialize, Serialize)]
|
||||||
pub struct UnreadNotificationsCount {
|
pub struct UnreadNotificationsCount {
|
||||||
|
@ -179,13 +210,6 @@ impl From<RumaUnreadNotificationsCount> for UnreadNotificationsCount {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The ephemeral events in the room that aren't recorded in the timeline or
|
|
||||||
/// state of the room. e.g. typing.
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
||||||
pub struct Ephemeral {
|
|
||||||
pub events: Vec<AnySyncEphemeralRoomEvent>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
pub struct LeftRoom {
|
pub struct LeftRoom {
|
||||||
/// The timeline of messages and state changes in the room up to the point
|
/// The timeline of messages and state changes in the room up to the point
|
||||||
|
@ -220,7 +244,7 @@ pub struct Timeline {
|
||||||
pub prev_batch: Option<String>,
|
pub prev_batch: Option<String>,
|
||||||
|
|
||||||
/// A list of events.
|
/// A list of events.
|
||||||
pub events: Vec<AnySyncRoomEvent>,
|
pub events: Vec<SyncRoomEvent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Timeline {
|
impl Timeline {
|
||||||
|
@ -233,13 +257,6 @@ impl Timeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// State events in the room.
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
|
||||||
pub struct State {
|
|
||||||
/// A list of state events.
|
|
||||||
pub events: Vec<AnySyncStateEvent>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
#[serde(
|
#[serde(
|
||||||
try_from = "SyncStateEvent<MemberEventContent>",
|
try_from = "SyncStateEvent<MemberEventContent>",
|
||||||
|
|
|
@ -27,14 +27,13 @@ use matrix_sdk_common::{
|
||||||
upload_keys,
|
upload_keys,
|
||||||
upload_signatures::Request as UploadSignaturesRequest,
|
upload_signatures::Request as UploadSignaturesRequest,
|
||||||
},
|
},
|
||||||
sync::sync_events::{DeviceLists, ToDevice as RumaToDevice},
|
sync::sync_events::{DeviceLists, ToDevice},
|
||||||
},
|
},
|
||||||
assign,
|
assign,
|
||||||
deserialized_responses::ToDevice,
|
deserialized_responses::{AlgorithmInfo, EncryptionInfo, SyncRoomEvent, VerificationState},
|
||||||
events::{
|
events::{
|
||||||
room::encrypted::EncryptedEventContent, room_key::RoomKeyEventContent,
|
room::encrypted::EncryptedEventContent, room_key::RoomKeyEventContent,
|
||||||
AnyMessageEventContent, AnySyncRoomEvent, AnyToDeviceEvent, SyncMessageEvent,
|
AnyMessageEventContent, AnyToDeviceEvent, SyncMessageEvent, ToDeviceEvent,
|
||||||
ToDeviceEvent,
|
|
||||||
},
|
},
|
||||||
identifiers::{
|
identifiers::{
|
||||||
DeviceId, DeviceIdBox, DeviceKeyAlgorithm, EventEncryptionAlgorithm, EventId, RoomId,
|
DeviceId, DeviceIdBox, DeviceKeyAlgorithm, EventEncryptionAlgorithm, EventId, RoomId,
|
||||||
|
@ -42,7 +41,7 @@ use matrix_sdk_common::{
|
||||||
},
|
},
|
||||||
locks::Mutex,
|
locks::Mutex,
|
||||||
uuid::Uuid,
|
uuid::Uuid,
|
||||||
Raw, UInt,
|
UInt,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "sled_cryptostore")]
|
#[cfg(feature = "sled_cryptostore")]
|
||||||
|
@ -802,7 +801,7 @@ impl OlmMachine {
|
||||||
/// [`decrypt_room_event`]: #method.decrypt_room_event
|
/// [`decrypt_room_event`]: #method.decrypt_room_event
|
||||||
pub async fn receive_sync_changes(
|
pub async fn receive_sync_changes(
|
||||||
&self,
|
&self,
|
||||||
to_device_events: &RumaToDevice,
|
to_device_events: ToDevice,
|
||||||
changed_devices: &DeviceLists,
|
changed_devices: &DeviceLists,
|
||||||
one_time_keys_counts: &BTreeMap<DeviceKeyAlgorithm, UInt>,
|
one_time_keys_counts: &BTreeMap<DeviceKeyAlgorithm, UInt>,
|
||||||
) -> OlmResult<ToDevice> {
|
) -> OlmResult<ToDevice> {
|
||||||
|
@ -826,14 +825,14 @@ impl OlmMachine {
|
||||||
|
|
||||||
let mut events = Vec::new();
|
let mut events = Vec::new();
|
||||||
|
|
||||||
for event_result in &to_device_events.events {
|
for mut raw_event in to_device_events.events {
|
||||||
let mut event = match event_result.deserialize() {
|
let event = match raw_event.deserialize() {
|
||||||
Ok(e) => e,
|
Ok(e) => e,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// Skip invalid events.
|
// Skip invalid events.
|
||||||
warn!(
|
warn!(
|
||||||
"Received an invalid to-device event {:?} {:?}",
|
"Received an invalid to-device event {:?} {:?}",
|
||||||
e, event_result
|
e, raw_event
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -841,9 +840,9 @@ impl OlmMachine {
|
||||||
|
|
||||||
info!("Received a to-device event {:?}", event);
|
info!("Received a to-device event {:?}", event);
|
||||||
|
|
||||||
match &mut event {
|
match event {
|
||||||
AnyToDeviceEvent::RoomEncrypted(e) => {
|
AnyToDeviceEvent::RoomEncrypted(e) => {
|
||||||
let decrypted = match self.decrypt_to_device_event(e).await {
|
let decrypted = match self.decrypt_to_device_event(&e).await {
|
||||||
Ok(e) => e,
|
Ok(e) => e,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(
|
warn!(
|
||||||
|
@ -885,12 +884,10 @@ impl OlmMachine {
|
||||||
changes.inbound_group_sessions.push(group_session);
|
changes.inbound_group_sessions.push(group_session);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(e) = decrypted.deserialized_event {
|
raw_event = decrypted.event;
|
||||||
event = e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
AnyToDeviceEvent::RoomKeyRequest(e) => {
|
AnyToDeviceEvent::RoomKeyRequest(e) => {
|
||||||
self.key_request_machine.receive_incoming_key_request(e)
|
self.key_request_machine.receive_incoming_key_request(&e)
|
||||||
}
|
}
|
||||||
AnyToDeviceEvent::KeyVerificationAccept(..)
|
AnyToDeviceEvent::KeyVerificationAccept(..)
|
||||||
| AnyToDeviceEvent::KeyVerificationCancel(..)
|
| AnyToDeviceEvent::KeyVerificationCancel(..)
|
||||||
|
@ -903,7 +900,7 @@ impl OlmMachine {
|
||||||
_ => continue,
|
_ => continue,
|
||||||
}
|
}
|
||||||
|
|
||||||
events.push(event);
|
events.push(raw_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
let changed_sessions = self
|
let changed_sessions = self
|
||||||
|
@ -915,7 +912,10 @@ impl OlmMachine {
|
||||||
|
|
||||||
self.store.save_changes(changes).await?;
|
self.store.save_changes(changes).await?;
|
||||||
|
|
||||||
Ok(ToDevice { events })
|
let mut to_device = ToDevice::new();
|
||||||
|
to_device.events = events;
|
||||||
|
|
||||||
|
Ok(to_device)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request a room key from our devices.
|
/// Request a room key from our devices.
|
||||||
|
@ -950,6 +950,44 @@ impl OlmMachine {
|
||||||
.await?)
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_encryption_info(
|
||||||
|
&self,
|
||||||
|
session: &InboundGroupSession,
|
||||||
|
sender: &UserId,
|
||||||
|
device_id: &DeviceId,
|
||||||
|
) -> StoreResult<EncryptionInfo> {
|
||||||
|
let verification_state = if let Some(device) =
|
||||||
|
self.get_device(sender, device_id).await?.filter(|d| {
|
||||||
|
d.get_key(DeviceKeyAlgorithm::Curve25519)
|
||||||
|
.map(|k| k == session.sender_key())
|
||||||
|
.unwrap_or(false)
|
||||||
|
}) {
|
||||||
|
if (self.user_id() == device.user_id() && self.device_id() == device.device_id())
|
||||||
|
|| device.is_trusted()
|
||||||
|
{
|
||||||
|
VerificationState::Trusted
|
||||||
|
} else {
|
||||||
|
VerificationState::Untrusted
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
VerificationState::UnknownDevice
|
||||||
|
};
|
||||||
|
|
||||||
|
let sender = sender.clone();
|
||||||
|
let device_id = device_id.to_owned();
|
||||||
|
|
||||||
|
Ok(EncryptionInfo {
|
||||||
|
sender,
|
||||||
|
sender_device: device_id,
|
||||||
|
algorithm_info: AlgorithmInfo::MegolmV1AesSha2 {
|
||||||
|
curve25519_key: session.sender_key().to_owned(),
|
||||||
|
sender_claimed_keys: session.signing_keys().to_owned(),
|
||||||
|
forwarding_curve25519_key_chain: session.forwading_key_chain().to_vec(),
|
||||||
|
},
|
||||||
|
verification_state,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Decrypt an event from a room timeline.
|
/// Decrypt an event from a room timeline.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
@ -961,7 +999,7 @@ impl OlmMachine {
|
||||||
&self,
|
&self,
|
||||||
event: &SyncMessageEvent<EncryptedEventContent>,
|
event: &SyncMessageEvent<EncryptedEventContent>,
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
) -> MegolmResult<Raw<AnySyncRoomEvent>> {
|
) -> MegolmResult<SyncRoomEvent> {
|
||||||
let content = match &event.content {
|
let content = match &event.content {
|
||||||
EncryptedEventContent::MegolmV1AesSha2(c) => c,
|
EncryptedEventContent::MegolmV1AesSha2(c) => c,
|
||||||
_ => return Err(EventError::UnsupportedAlgorithm.into()),
|
_ => return Err(EventError::UnsupportedAlgorithm.into()),
|
||||||
|
@ -989,8 +1027,6 @@ impl OlmMachine {
|
||||||
"Successfully decrypted a Megolm event {:?}",
|
"Successfully decrypted a Megolm event {:?}",
|
||||||
decrypted_event
|
decrypted_event
|
||||||
);
|
);
|
||||||
// TODO set the encryption info on the event (is it verified, was it
|
|
||||||
// decrypted, sender key...)
|
|
||||||
|
|
||||||
if let Ok(e) = decrypted_event.deserialize() {
|
if let Ok(e) = decrypted_event.deserialize() {
|
||||||
self.verification_machine
|
self.verification_machine
|
||||||
|
@ -998,7 +1034,14 @@ impl OlmMachine {
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(decrypted_event)
|
let encryption_info = self
|
||||||
|
.get_encryption_info(&session, &event.sender, &content.device_id)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(SyncRoomEvent {
|
||||||
|
encryption_info: Some(encryption_info),
|
||||||
|
event: decrypted_event,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the tracked users.
|
/// Update the tracked users.
|
||||||
|
@ -1815,23 +1858,24 @@ pub(crate) mod test {
|
||||||
.decrypt_room_event(&event, &room_id)
|
.decrypt_room_event(&event, &room_id)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
.event
|
||||||
.deserialize()
|
.deserialize()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
match decrypted_event {
|
if let AnySyncRoomEvent::Message(AnySyncMessageEvent::RoomMessage(SyncMessageEvent {
|
||||||
AnySyncRoomEvent::Message(AnySyncMessageEvent::RoomMessage(SyncMessageEvent {
|
|
||||||
sender,
|
sender,
|
||||||
content,
|
content,
|
||||||
..
|
..
|
||||||
})) => {
|
})) = decrypted_event
|
||||||
|
{
|
||||||
assert_eq!(&sender, alice.user_id());
|
assert_eq!(&sender, alice.user_id());
|
||||||
if let MessageType::Text(c) = &content.msgtype {
|
if let MessageType::Text(c) = &content.msgtype {
|
||||||
assert_eq!(&c.body, plaintext);
|
assert_eq!(&c.body, plaintext);
|
||||||
} else {
|
} else {
|
||||||
panic!("Decrypted event has a missmatched content");
|
panic!("Decrypted event has a mismatched content");
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
_ => panic!("Decrypted room event has the wrong type"),
|
panic!("Decrypted room event has the wrong type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,9 +61,9 @@ pub struct InboundGroupSession {
|
||||||
session_id: Arc<str>,
|
session_id: Arc<str>,
|
||||||
first_known_index: u32,
|
first_known_index: u32,
|
||||||
pub(crate) sender_key: Arc<str>,
|
pub(crate) sender_key: Arc<str>,
|
||||||
pub(crate) signing_key: Arc<BTreeMap<DeviceKeyAlgorithm, String>>,
|
pub(crate) signing_keys: Arc<BTreeMap<DeviceKeyAlgorithm, String>>,
|
||||||
pub(crate) room_id: Arc<RoomId>,
|
pub(crate) room_id: Arc<RoomId>,
|
||||||
forwarding_chains: Arc<Mutex<Option<Vec<String>>>>,
|
forwarding_chains: Arc<Vec<String>>,
|
||||||
imported: Arc<bool>,
|
imported: Arc<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,10 +104,10 @@ impl InboundGroupSession {
|
||||||
history_visibility: history_visibility.into(),
|
history_visibility: history_visibility.into(),
|
||||||
sender_key: sender_key.to_owned().into(),
|
sender_key: sender_key.to_owned().into(),
|
||||||
first_known_index,
|
first_known_index,
|
||||||
signing_key: Arc::new(keys),
|
signing_keys: keys.into(),
|
||||||
room_id: Arc::new(room_id.clone()),
|
room_id: room_id.clone().into(),
|
||||||
forwarding_chains: Arc::new(Mutex::new(None)),
|
forwarding_chains: Vec::new().into(),
|
||||||
imported: Arc::new(false),
|
imported: false.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,15 +152,15 @@ impl InboundGroupSession {
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(InboundGroupSession {
|
Ok(InboundGroupSession {
|
||||||
inner: Arc::new(Mutex::new(session)),
|
inner: Mutex::new(session).into(),
|
||||||
session_id: content.session_id.as_str().into(),
|
session_id: content.session_id.as_str().into(),
|
||||||
sender_key: content.sender_key.as_str().into(),
|
sender_key: content.sender_key.as_str().into(),
|
||||||
first_known_index,
|
first_known_index,
|
||||||
history_visibility: None.into(),
|
history_visibility: None.into(),
|
||||||
signing_key: Arc::new(sender_claimed_key),
|
signing_keys: sender_claimed_key.into(),
|
||||||
room_id: Arc::new(content.room_id.clone()),
|
room_id: content.room_id.clone().into(),
|
||||||
forwarding_chains: Arc::new(Mutex::new(Some(forwarding_chains))),
|
forwarding_chains: forwarding_chains.into(),
|
||||||
imported: Arc::new(true),
|
imported: true.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,9 +176,9 @@ impl InboundGroupSession {
|
||||||
PickledInboundGroupSession {
|
PickledInboundGroupSession {
|
||||||
pickle: InboundGroupSessionPickle::from(pickle),
|
pickle: InboundGroupSessionPickle::from(pickle),
|
||||||
sender_key: self.sender_key.to_string(),
|
sender_key: self.sender_key.to_string(),
|
||||||
signing_key: (&*self.signing_key).clone(),
|
signing_key: (&*self.signing_keys).clone(),
|
||||||
room_id: (&*self.room_id).clone(),
|
room_id: (&*self.room_id).clone(),
|
||||||
forwarding_chains: self.forwarding_chains.lock().await.clone(),
|
forwarding_chains: self.forwading_key_chain().to_vec(),
|
||||||
imported: *self.imported,
|
imported: *self.imported,
|
||||||
history_visibility: self.history_visibility.as_ref().clone(),
|
history_visibility: self.history_visibility.as_ref().clone(),
|
||||||
}
|
}
|
||||||
|
@ -197,6 +197,20 @@ impl InboundGroupSession {
|
||||||
&self.sender_key
|
&self.sender_key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the map of signing keys this session was received from.
|
||||||
|
pub fn signing_keys(&self) -> &BTreeMap<DeviceKeyAlgorithm, String> {
|
||||||
|
&self.signing_keys
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the list of ed25519 keys that this session was forwarded through.
|
||||||
|
///
|
||||||
|
/// Each ed25519 key represents a single device. If device A forwards the
|
||||||
|
/// session to device B and device B to C this list will contain the ed25519
|
||||||
|
/// keys of A and B.
|
||||||
|
pub fn forwading_key_chain(&self) -> &[String] {
|
||||||
|
&self.forwarding_chains
|
||||||
|
}
|
||||||
|
|
||||||
/// Export this session at the given message index.
|
/// Export this session at the given message index.
|
||||||
pub async fn export_at_index(&self, message_index: u32) -> ExportedRoomKey {
|
pub async fn export_at_index(&self, message_index: u32) -> ExportedRoomKey {
|
||||||
let message_index = std::cmp::max(self.first_known_index(), message_index);
|
let message_index = std::cmp::max(self.first_known_index(), message_index);
|
||||||
|
@ -214,14 +228,8 @@ impl InboundGroupSession {
|
||||||
room_id: (&*self.room_id).clone(),
|
room_id: (&*self.room_id).clone(),
|
||||||
sender_key: (&*self.sender_key).to_owned(),
|
sender_key: (&*self.sender_key).to_owned(),
|
||||||
session_id: self.session_id().to_owned(),
|
session_id: self.session_id().to_owned(),
|
||||||
forwarding_curve25519_key_chain: self
|
forwarding_curve25519_key_chain: self.forwading_key_chain().to_vec(),
|
||||||
.forwarding_chains
|
sender_claimed_keys: (&*self.signing_keys).clone(),
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.as_ref()
|
|
||||||
.cloned()
|
|
||||||
.unwrap_or_default(),
|
|
||||||
sender_claimed_keys: (&*self.signing_key).clone(),
|
|
||||||
session_key,
|
session_key,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -246,15 +254,15 @@ impl InboundGroupSession {
|
||||||
let session_id = session.session_id();
|
let session_id = session.session_id();
|
||||||
|
|
||||||
Ok(InboundGroupSession {
|
Ok(InboundGroupSession {
|
||||||
inner: Arc::new(Mutex::new(session)),
|
inner: Mutex::new(session).into(),
|
||||||
session_id: session_id.into(),
|
session_id: session_id.into(),
|
||||||
sender_key: pickle.sender_key.into(),
|
sender_key: pickle.sender_key.into(),
|
||||||
history_visibility: pickle.history_visibility.into(),
|
history_visibility: pickle.history_visibility.into(),
|
||||||
first_known_index,
|
first_known_index,
|
||||||
signing_key: Arc::new(pickle.signing_key),
|
signing_keys: pickle.signing_key.into(),
|
||||||
room_id: Arc::new(pickle.room_id),
|
room_id: pickle.room_id.into(),
|
||||||
forwarding_chains: Arc::new(Mutex::new(pickle.forwarding_chains)),
|
forwarding_chains: pickle.forwarding_chains.into(),
|
||||||
imported: Arc::new(pickle.imported),
|
imported: pickle.imported.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,7 +387,8 @@ pub struct PickledInboundGroupSession {
|
||||||
pub room_id: RoomId,
|
pub room_id: RoomId,
|
||||||
/// The list of claimed ed25519 that forwarded us this key. Will be None if
|
/// The list of claimed ed25519 that forwarded us this key. Will be None if
|
||||||
/// we dirrectly received this session.
|
/// we dirrectly received this session.
|
||||||
pub forwarding_chains: Option<Vec<String>>,
|
#[serde(default)]
|
||||||
|
pub forwarding_chains: Vec<String>,
|
||||||
/// Flag remembering if the session was dirrectly sent to us by the sender
|
/// Flag remembering if the session was dirrectly sent to us by the sender
|
||||||
/// or if it was imported.
|
/// or if it was imported.
|
||||||
pub imported: bool,
|
pub imported: bool,
|
||||||
|
@ -411,21 +420,15 @@ impl TryFrom<ExportedRoomKey> for InboundGroupSession {
|
||||||
let session = OlmInboundGroupSession::import(&key.session_key.0)?;
|
let session = OlmInboundGroupSession::import(&key.session_key.0)?;
|
||||||
let first_known_index = session.first_known_index();
|
let first_known_index = session.first_known_index();
|
||||||
|
|
||||||
let forwarding_chains = if key.forwarding_curve25519_key_chain.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(key.forwarding_curve25519_key_chain)
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(InboundGroupSession {
|
Ok(InboundGroupSession {
|
||||||
inner: Arc::new(Mutex::new(session)),
|
inner: Arc::new(Mutex::new(session)),
|
||||||
session_id: key.session_id.into(),
|
session_id: key.session_id.into(),
|
||||||
sender_key: key.sender_key.into(),
|
sender_key: key.sender_key.into(),
|
||||||
history_visibility: None.into(),
|
history_visibility: None.into(),
|
||||||
first_known_index,
|
first_known_index,
|
||||||
signing_key: Arc::new(key.sender_claimed_keys),
|
signing_keys: Arc::new(key.sender_claimed_keys),
|
||||||
room_id: Arc::new(key.room_id),
|
room_id: Arc::new(key.room_id),
|
||||||
forwarding_chains: Arc::new(Mutex::new(forwarding_chains)),
|
forwarding_chains: Arc::new(key.forwarding_curve25519_key_chain),
|
||||||
imported: Arc::new(true),
|
imported: Arc::new(true),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue