base: Store the whole encryption info for the room.

master
Damir Jelić 2020-05-14 13:58:09 +02:00
parent c0ff782ea3
commit 96cf90e47c
2 changed files with 111 additions and 12 deletions

View File

@ -33,7 +33,7 @@ use crate::events::room::{
tombstone::TombstoneEvent, tombstone::TombstoneEvent,
}; };
use crate::events::stripped::{AnyStrippedStateEvent, StrippedRoomName}; use crate::events::stripped::{AnyStrippedStateEvent, StrippedRoomName};
use crate::events::EventType; use crate::events::{Algorithm, EventType};
#[cfg(feature = "messages")] #[cfg(feature = "messages")]
use crate::events::room::message::MessageEvent; use crate::events::room::message::MessageEvent;
@ -92,6 +92,51 @@ pub struct PowerLevels {
pub notifications: Int, pub notifications: Int,
} }
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
/// Encryption info of the room.
pub struct EncryptionInfo {
/// The encryption algorithm that should be used to encrypt messages in the
/// room.
algorithm: Algorithm,
/// How long should a session be used before it is rotated.
rotation_period_ms: u64,
/// The maximum amount of messages that should be encrypted using the same
/// session.
rotation_period_messages: u64,
}
impl EncryptionInfo {
/// The encryption algorithm that should be used to encrypt messages in the
/// room.
pub fn algorithm(&self) -> &Algorithm {
&self.algorithm
}
/// How long should a session be used before it is rotated.
pub fn rotation_period(&self) -> u64 {
self.rotation_period_ms
}
/// The maximum amount of messages that should be encrypted using the same
/// session.
pub fn rotation_period_messages(&self) -> u64 {
self.rotation_period_messages
}
}
impl From<&EncryptionEvent> for EncryptionInfo {
fn from(event: &EncryptionEvent) -> Self {
EncryptionInfo {
algorithm: event.content.algorithm.clone(),
rotation_period_ms: event
.content
.rotation_period_ms
.map_or(604800000, Into::into),
rotation_period_messages: event.content.rotation_period_msgs.map_or(100, Into::into),
}
}
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(test, derive(Clone))] #[cfg_attr(test, derive(Clone))]
pub struct Tombstone { pub struct Tombstone {
@ -127,9 +172,8 @@ pub struct Room {
pub typing_users: Vec<UserId>, pub typing_users: Vec<UserId>,
/// The power level requirements for specific actions in this room /// The power level requirements for specific actions in this room
pub power_levels: Option<PowerLevels>, pub power_levels: Option<PowerLevels>,
// TODO when encryption events are handled we store algorithm used and rotation time. /// Optional encryption info, will be `Some` if the room is encrypted.
/// A flag indicating if the room is encrypted. pub encrypted: Option<EncryptionInfo>,
pub encrypted: bool,
/// Number of unread notifications with highlight flag set. /// Number of unread notifications with highlight flag set.
pub unread_highlight: Option<UInt>, pub unread_highlight: Option<UInt>,
/// Number of unread notifications. /// Number of unread notifications.
@ -230,7 +274,7 @@ impl Room {
messages: MessageQueue::new(), messages: MessageQueue::new(),
typing_users: Vec::new(), typing_users: Vec::new(),
power_levels: None, power_levels: None,
encrypted: false, encrypted: None,
unread_highlight: None, unread_highlight: None,
unread_notifications: None, unread_notifications: None,
tombstone: None, tombstone: None,
@ -244,7 +288,14 @@ impl Room {
/// Is the room a encrypted room. /// Is the room a encrypted room.
pub fn is_encrypted(&self) -> bool { pub fn is_encrypted(&self) -> bool {
self.encrypted self.encrypted.is_some()
}
/// Get the encryption info if any of the room.
///
/// Returns None if the room is not encrypted.
pub fn encryption_info(&self) -> Option<&EncryptionInfo> {
self.encrypted.as_ref()
} }
fn add_member(&mut self, event: &MemberEvent) -> bool { fn add_member(&mut self, event: &MemberEvent) -> bool {
@ -426,8 +477,8 @@ impl Room {
true true
} }
fn handle_encryption_event(&mut self, _event: &EncryptionEvent) -> bool { fn handle_encryption_event(&mut self, event: &EncryptionEvent) -> bool {
self.encrypted = true; self.encrypted = Some(event.into());
true true
} }
@ -522,11 +573,16 @@ impl Room {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
use crate::events::room::member::MembershipState; use crate::events::{
use crate::identifiers::UserId; room::{encryption::EncryptionEventContent, member::MembershipState},
UnsignedData,
};
use crate::identifiers::{EventId, UserId};
use crate::{BaseClient, Session}; use crate::{BaseClient, Session};
use matrix_sdk_test::{async_test, sync_response, EventBuilder, EventsFile, SyncResponseFile}; use matrix_sdk_test::{async_test, sync_response, EventBuilder, EventsFile, SyncResponseFile};
use std::time::SystemTime;
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
@ -672,4 +728,47 @@ mod test {
assert_eq!(vec!["example, example2"], room_names); assert_eq!(vec!["example, example2"], room_names);
} }
#[async_test]
async fn encryption_info_test() {
let mut response = sync_response(SyncResponseFile::DefaultWithSummary);
let user_id = UserId::try_from("@example:localhost").unwrap();
let session = Session {
access_token: "1234".to_owned(),
user_id: user_id.clone(),
device_id: "DEVICEID".to_owned(),
};
let client = BaseClient::new(Some(session)).unwrap();
client.receive_sync_response(&mut response).await.unwrap();
let event = EncryptionEvent {
event_id: EventId::new("test").unwrap(),
origin_server_ts: SystemTime::now(),
sender: user_id,
state_key: "".into(),
unsigned: UnsignedData::default(),
content: EncryptionEventContent {
algorithm: Algorithm::MegolmV1AesSha2,
rotation_period_ms: Some(100_000u32.into()),
rotation_period_msgs: Some(100u32.into()),
},
prev_content: None,
room_id: None,
};
let room_id = get_room_id();
let room = client.get_joined_room(&room_id).await.unwrap();
assert!(!room.read().await.is_encrypted());
room.write().await.handle_encryption_event(&event);
assert!(room.read().await.is_encrypted());
let room_lock = room.read().await;
let encryption_info = room_lock.encryption_info().unwrap();
assert_eq!(encryption_info.algorithm(), &Algorithm::MegolmV1AesSha2);
assert_eq!(encryption_info.rotation_period(), 100_000);
assert_eq!(encryption_info.rotation_period_messages(), 100);
}
} }

View File

@ -143,7 +143,7 @@ mod test {
"members": {}, "members": {},
"typing_users": [], "typing_users": [],
"power_levels": null, "power_levels": null,
"encrypted": false, "encrypted": null,
"unread_highlight": null, "unread_highlight": null,
"unread_notifications": null, "unread_notifications": null,
"tombstone": null "tombstone": null
@ -171,7 +171,7 @@ mod test {
"messages": [], "messages": [],
"typing_users": [], "typing_users": [],
"power_levels": null, "power_levels": null,
"encrypted": false, "encrypted": null,
"unread_highlight": null, "unread_highlight": null,
"unread_notifications": null, "unread_notifications": null,
"tombstone": null "tombstone": null