rust-sdk: Update to the latest ruma releases.

master
Damir Jelić 2020-04-23 10:52:47 +02:00
parent 4369d0b854
commit 1de791c207
11 changed files with 126 additions and 125 deletions

View File

@ -24,10 +24,10 @@ async-trait = "0.1.30"
# Ruma dependencies # Ruma dependencies
js_int = "0.1.4" js_int = "0.1.4"
ruma-api = "0.15.1" ruma-api = "0.16.0-rc.2"
ruma-client-api = { git = "https://github.com/matrix-org/ruma-client-api/", version = "0.7.0" } ruma-client-api = { version = "0.8.0-rc.5" }
ruma-events = { git = "https://github.com/matrix-org/ruma-events", version = "0.18.0" } ruma-events = { version = "0.21.0-beta.1" }
ruma-identifiers = "0.14.1" ruma-identifiers = "0.16.0"
uuid = { version = "0.8.1", features = ["v4"] } uuid = { version = "0.8.1", features = ["v4"] }
# Dependencies for the encryption support # Dependencies for the encryption support

View File

@ -101,6 +101,8 @@ async fn login_and_sync(
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), matrix_sdk::Error> { async fn main() -> Result<(), matrix_sdk::Error> {
tracing_subscriber::fmt::init();
let (homeserver_url, username, password) = let (homeserver_url, username, password) =
match (env::args().nth(1), env::args().nth(2), env::args().nth(3)) { match (env::args().nth(1), env::args().nth(2), env::args().nth(3)) {
(Some(a), Some(b), Some(c)) => (a, b, c), (Some(a), Some(b), Some(c)) => (a, b, c),

View File

@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use std::collections::HashMap; use std::collections::{BTreeMap, HashMap};
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};
use std::result::Result as StdResult; use std::result::Result as StdResult;
use std::sync::Arc; use std::sync::Arc;
@ -33,9 +33,9 @@ use http::Response as HttpResponse;
use reqwest::header::{HeaderValue, InvalidHeaderValue}; use reqwest::header::{HeaderValue, InvalidHeaderValue};
use url::Url; use url::Url;
use ruma_api::{Endpoint, Outgoing}; use ruma_api::Endpoint;
use ruma_events::room::message::MessageEventContent; use ruma_events::room::message::MessageEventContent;
use ruma_events::EventResult; use ruma_events::EventJson;
pub use ruma_events::EventType; pub use ruma_events::EventType;
use ruma_identifiers::{RoomId, RoomIdOrAliasId, UserId}; use ruma_identifiers::{RoomId, RoomIdOrAliasId, UserId};
@ -370,9 +370,11 @@ impl AsyncClient {
pub async fn join_room_by_id_or_alias( pub async fn join_room_by_id_or_alias(
&self, &self,
alias: &RoomIdOrAliasId, alias: &RoomIdOrAliasId,
server_name: &str,
) -> Result<join_room_by_id_or_alias::Response> { ) -> Result<join_room_by_id_or_alias::Response> {
let request = join_room_by_id_or_alias::Request { let request = join_room_by_id_or_alias::Request {
room_id_or_alias: alias.clone(), room_id_or_alias: alias.clone(),
server_name: server_name.to_owned(),
third_party_signed: None, third_party_signed: None,
}; };
self.send(request).await self.send(request).await
@ -538,7 +540,7 @@ impl AsyncClient {
pub async fn room_messages<R: Into<get_message_events::Request>>( pub async fn room_messages<R: Into<get_message_events::Request>>(
&self, &self,
request: R, request: R,
) -> Result<get_message_events::IncomingResponse> { ) -> Result<get_message_events::Response> {
let req = request.into(); let req = request.into();
self.send(req).await self.send(req).await
} }
@ -549,7 +551,7 @@ impl AsyncClient {
/// ///
/// * `sync_settings` - Settings for the sync call. /// * `sync_settings` - Settings for the sync call.
#[instrument] #[instrument]
pub async fn sync(&self, sync_settings: SyncSettings) -> Result<sync_events::IncomingResponse> { pub async fn sync(&self, sync_settings: SyncSettings) -> Result<sync_events::Response> {
let request = sync_events::Request { let request = sync_events::Request {
filter: None, filter: None,
since: sync_settings.token, since: sync_settings.token,
@ -564,7 +566,7 @@ impl AsyncClient {
let matrix_room = { let matrix_room = {
let mut client = self.base_client.write().await; let mut client = self.base_client.write().await;
for event in &room.state.events { for event in &room.state.events {
if let EventResult::Ok(e) = event { if let Ok(e) = event.deserialize() {
client.receive_joined_state_event(&room_id, &e).await; client.receive_joined_state_event(&room_id, &e).await;
} }
} }
@ -577,9 +579,9 @@ impl AsyncClient {
// re looping is not ideal here // re looping is not ideal here
for event in &mut room.state.events { for event in &mut room.state.events {
if let EventResult::Ok(e) = event { if let Ok(e) = event.deserialize() {
let client = self.base_client.read().await; let client = self.base_client.read().await;
client.emit_state_event(room_id, e).await; client.emit_state_event(&room_id, &e).await;
} }
} }
@ -595,19 +597,19 @@ impl AsyncClient {
*event = e; *event = e;
} }
if let EventResult::Ok(e) = event { if let Ok(e) = event.deserialize() {
let client = self.base_client.read().await; let client = self.base_client.read().await;
client.emit_timeline_event(room_id, e).await; client.emit_timeline_event(&room_id, &e).await;
} }
} }
// look at AccountData to further cut down users by collecting ignored users // look at AccountData to further cut down users by collecting ignored users
for account_data in &mut room.account_data.events { for account_data in &mut room.account_data.events {
{ {
if let EventResult::Ok(e) = account_data { if let Ok(e) = account_data.deserialize() {
let mut client = self.base_client.write().await; let mut client = self.base_client.write().await;
client.receive_account_data_event(&room_id, e).await; client.receive_account_data_event(&room_id, &e).await;
client.emit_account_data_event(room_id, e).await; client.emit_account_data_event(&room_id, &e).await;
} }
} }
} }
@ -617,22 +619,22 @@ impl AsyncClient {
// efficient but we need a room_id so we would loop through now or later. // efficient but we need a room_id so we would loop through now or later.
for presence in &mut response.presence.events { for presence in &mut response.presence.events {
{ {
if let EventResult::Ok(e) = presence { if let Ok(e) = presence.deserialize() {
let mut client = self.base_client.write().await; let mut client = self.base_client.write().await;
client.receive_presence_event(&room_id, e).await; client.receive_presence_event(&room_id, &e).await;
client.emit_presence_event(room_id, e).await; client.emit_presence_event(&room_id, &e).await;
} }
} }
} }
for ephemeral in &mut room.ephemeral.events { for ephemeral in &mut room.ephemeral.events {
{ {
if let EventResult::Ok(e) = ephemeral { if let Ok(e) = ephemeral.deserialize() {
let mut client = self.base_client.write().await; let mut client = self.base_client.write().await;
client.receive_ephemeral_event(&room_id, e).await; client.receive_ephemeral_event(&room_id, &e).await;
client.emit_ephemeral_event(room_id, e).await; client.emit_ephemeral_event(&room_id, &e).await;
} }
} }
} }
@ -703,7 +705,7 @@ impl AsyncClient {
pub async fn sync_forever<C>( pub async fn sync_forever<C>(
&self, &self,
sync_settings: SyncSettings, sync_settings: SyncSettings,
callback: impl Fn(sync_events::IncomingResponse) -> C + Send, callback: impl Fn(sync_events::Response) -> C + Send,
) where ) where
C: Future<Output = ()>, C: Future<Output = ()>,
{ {
@ -759,18 +761,7 @@ impl AsyncClient {
async fn send<Request: Endpoint<ResponseError = ruma_client_api::Error> + std::fmt::Debug>( async fn send<Request: Endpoint<ResponseError = ruma_client_api::Error> + std::fmt::Debug>(
&self, &self,
request: Request, request: Request,
) -> Result<<Request::Response as Outgoing>::Incoming> ) -> Result<Request::Response> {
where
Request::Incoming:
TryFrom<http::Request<Vec<u8>>, Error = ruma_api::error::FromHttpRequestError>,
<Request::Response as Outgoing>::Incoming: TryFrom<
http::Response<Vec<u8>>,
Error = ruma_api::error::FromHttpResponseError<
<Request as ruma_api::Endpoint>::ResponseError,
>,
>,
<Request as ruma_api::Endpoint>::ResponseError: std::fmt::Debug,
{
let request: http::Request<Vec<u8>> = request.try_into()?; let request: http::Request<Vec<u8>> = request.try_into()?;
let url = request.uri(); let url = request.uri();
let path_and_query = url.path_and_query().unwrap(); let path_and_query = url.path_and_query().unwrap();
@ -828,9 +819,7 @@ impl AsyncClient {
let body = response.bytes().await?.as_ref().to_owned(); let body = response.bytes().await?.as_ref().to_owned();
let http_response = http_builder.body(body).unwrap(); let http_response = http_builder.body(body).unwrap();
Ok(<Request::Response as Outgoing>::Incoming::try_from( Ok(<Request::Response>::try_from(http_response)?)
http_response,
)?)
} }
/// Send a room message to the homeserver. /// Send a room message to the homeserver.
@ -940,7 +929,7 @@ impl AsyncClient {
room_id: room_id.clone(), room_id: room_id.clone(),
event_type, event_type,
txn_id: txn_id.unwrap_or_else(Uuid::new_v4).to_string(), txn_id: txn_id.unwrap_or_else(Uuid::new_v4).to_string(),
data: content, data: EventJson::from(content),
}; };
let response = self.send(request).await?; let response = self.send(request).await?;
@ -962,7 +951,7 @@ impl AsyncClient {
#[instrument] #[instrument]
async fn claim_one_time_keys( async fn claim_one_time_keys(
&self, &self,
one_time_keys: HashMap<UserId, HashMap<DeviceId, KeyAlgorithm>>, one_time_keys: BTreeMap<UserId, BTreeMap<DeviceId, KeyAlgorithm>>,
) -> Result<claim_keys::Response> { ) -> Result<claim_keys::Response> {
let request = claim_keys::Request { let request = claim_keys::Request {
timeout: None, timeout: None,
@ -1076,7 +1065,7 @@ impl AsyncClient {
users_for_query users_for_query
); );
let mut device_keys: HashMap<UserId, Vec<DeviceId>> = HashMap::new(); let mut device_keys: BTreeMap<UserId, Vec<DeviceId>> = BTreeMap::new();
for user in users_for_query.drain() { for user in users_for_query.drain() {
device_keys.insert(user, Vec::new()); device_keys.insert(user, Vec::new());

View File

@ -15,7 +15,7 @@
use std::collections::HashMap; use std::collections::HashMap;
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
use std::collections::HashSet; use std::collections::{BTreeMap, HashSet};
use std::fmt; use std::fmt;
use std::sync::Arc; use std::sync::Arc;
@ -30,7 +30,7 @@ use crate::events::presence::PresenceEvent;
use crate::events::collections::only::Event as NonRoomEvent; use crate::events::collections::only::Event as NonRoomEvent;
use crate::events::ignored_user_list::IgnoredUserListEvent; use crate::events::ignored_user_list::IgnoredUserListEvent;
use crate::events::push_rules::{PushRulesEvent, Ruleset}; use crate::events::push_rules::{PushRulesEvent, Ruleset};
use crate::events::EventResult; use crate::events::EventJson;
use crate::identifiers::{RoomId, UserId}; use crate::identifiers::{RoomId, UserId};
use crate::models::Room; use crate::models::Room;
use crate::session::Session; use crate::session::Session;
@ -234,10 +234,10 @@ impl Client {
pub async fn receive_joined_timeline_event( pub async fn receive_joined_timeline_event(
&mut self, &mut self,
room_id: &RoomId, room_id: &RoomId,
event: &mut EventResult<RoomEvent>, event: &mut EventJson<RoomEvent>,
) -> Option<EventResult<RoomEvent>> { ) -> Option<EventJson<RoomEvent>> {
match event { match event.deserialize() {
EventResult::Ok(e) => { Ok(mut e) => {
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
let mut decrypted_event = None; let mut decrypted_event = None;
#[cfg(not(feature = "encryption"))] #[cfg(not(feature = "encryption"))]
@ -246,12 +246,12 @@ impl Client {
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
{ {
match e { match e {
RoomEvent::RoomEncrypted(e) => { RoomEvent::RoomEncrypted(ref mut e) => {
e.room_id = Some(room_id.to_owned()); e.room_id = Some(room_id.to_owned());
let mut olm = self.olm.lock().await; let mut olm = self.olm.lock().await;
if let Some(o) = &mut *olm { if let Some(o) = &mut *olm {
decrypted_event = o.decrypt_room_event(e).await.ok(); decrypted_event = o.decrypt_room_event(&e).await.ok();
} }
} }
_ => (), _ => (),
@ -259,7 +259,7 @@ impl Client {
} }
let mut room = self.get_or_create_room(&room_id).write().await; let mut room = self.get_or_create_room(&room_id).write().await;
room.receive_timeline_event(e); room.receive_timeline_event(&e);
decrypted_event decrypted_event
} }
_ => None, _ => None,
@ -358,10 +358,7 @@ impl Client {
/// # Arguments /// # Arguments
/// ///
/// * `response` - The response that we received after a successful sync. /// * `response` - The response that we received after a successful sync.
pub async fn receive_sync_response( pub async fn receive_sync_response(&mut self, response: &mut api::sync::sync_events::Response) {
&mut self,
response: &mut api::sync::sync_events::IncomingResponse,
) {
self.sync_token = Some(response.next_batch.clone()); self.sync_token = Some(response.next_batch.clone());
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
@ -437,12 +434,12 @@ impl Client {
pub async fn get_missing_sessions( pub async fn get_missing_sessions(
&self, &self,
users: impl Iterator<Item = &UserId>, users: impl Iterator<Item = &UserId>,
) -> HashMap<UserId, HashMap<DeviceId, KeyAlgorithm>> { ) -> BTreeMap<UserId, BTreeMap<DeviceId, KeyAlgorithm>> {
let mut olm = self.olm.lock().await; let mut olm = self.olm.lock().await;
match &mut *olm { match &mut *olm {
Some(o) => o.get_missing_sessions(users).await, Some(o) => o.get_missing_sessions(users).await,
None => HashMap::new(), None => BTreeMap::new(),
} }
} }

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use std::collections::HashMap; use std::collections::BTreeMap;
use std::mem; use std::mem;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
@ -29,7 +29,7 @@ pub struct Device {
user_id: Arc<UserId>, user_id: Arc<UserId>,
device_id: Arc<DeviceId>, device_id: Arc<DeviceId>,
algorithms: Arc<Vec<Algorithm>>, algorithms: Arc<Vec<Algorithm>>,
keys: Arc<HashMap<KeyAlgorithm, String>>, keys: Arc<BTreeMap<KeyAlgorithm, String>>,
display_name: Arc<Option<String>>, display_name: Arc<Option<String>>,
deleted: Arc<AtomicBool>, deleted: Arc<AtomicBool>,
trust_state: Arc<Atomic<TrustState>>, trust_state: Arc<Atomic<TrustState>>,
@ -68,7 +68,7 @@ impl Device {
display_name: Option<String>, display_name: Option<String>,
trust_state: TrustState, trust_state: TrustState,
algorithms: Vec<Algorithm>, algorithms: Vec<Algorithm>,
keys: HashMap<KeyAlgorithm, String>, keys: BTreeMap<KeyAlgorithm, String>,
) -> Self { ) -> Self {
Device { Device {
user_id: Arc::new(user_id), user_id: Arc::new(user_id),
@ -102,7 +102,7 @@ impl Device {
} }
/// Get a map containing all the device keys. /// Get a map containing all the device keys.
pub fn keys(&self) -> &HashMap<KeyAlgorithm, String> { pub fn keys(&self) -> &BTreeMap<KeyAlgorithm, String> {
&self.keys &self.keys
} }
@ -123,7 +123,7 @@ impl Device {
/// Update a device with a new device keys struct. /// Update a device with a new device keys struct.
pub(crate) fn update_device(&mut self, device_keys: &DeviceKeys) { pub(crate) fn update_device(&mut self, device_keys: &DeviceKeys) {
let mut keys = HashMap::new(); let mut keys = BTreeMap::new();
for (key_id, key) in device_keys.keys.iter() { for (key_id, key) in device_keys.keys.iter() {
let key_id = key_id.0; let key_id = key_id.0;
@ -153,7 +153,7 @@ impl Device {
impl From<&DeviceKeys> for Device { impl From<&DeviceKeys> for Device {
fn from(device_keys: &DeviceKeys) -> Self { fn from(device_keys: &DeviceKeys) -> Self {
let mut keys = HashMap::new(); let mut keys = BTreeMap::new();
for (key_id, key) in device_keys.keys.iter() { for (key_id, key) in device_keys.keys.iter() {
let key_id = key_id.0; let key_id = key_id.0;

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use std::collections::{HashMap, HashSet}; use std::collections::{BTreeMap, HashMap, HashSet};
use std::convert::TryInto; use std::convert::TryInto;
use std::mem; use std::mem;
#[cfg(feature = "sqlite-cryptostore")] #[cfg(feature = "sqlite-cryptostore")]
@ -42,7 +42,7 @@ use crate::events::{
AnyToDeviceEvent as ToDeviceEvent, ToDeviceEncrypted, ToDeviceForwardedRoomKey, AnyToDeviceEvent as ToDeviceEvent, ToDeviceEncrypted, ToDeviceForwardedRoomKey,
ToDeviceRoomKey, ToDeviceRoomKeyRequest, ToDeviceRoomKey, ToDeviceRoomKeyRequest,
}, },
Algorithm, EventResult, EventType, Algorithm, EventJson, EventType,
}; };
use crate::identifiers::{DeviceId, RoomId, UserId}; use crate::identifiers::{DeviceId, RoomId, UserId};
@ -50,14 +50,14 @@ use api::r0::keys;
use api::r0::{ use api::r0::{
client_exchange::{send_event_to_device::Request as ToDeviceRequest, DeviceIdOrAllDevices}, client_exchange::{send_event_to_device::Request as ToDeviceRequest, DeviceIdOrAllDevices},
keys::{AlgorithmAndDeviceId, DeviceKeys, KeyAlgorithm, OneTimeKey, SignedKey}, keys::{AlgorithmAndDeviceId, DeviceKeys, KeyAlgorithm, OneTimeKey, SignedKey},
sync::sync_events::IncomingResponse as SyncResponse, sync::sync_events::Response as SyncResponse,
}; };
use cjson; use cjson;
use serde_json::{json, Value}; use serde_json::{json, Value};
use tracing::{debug, error, info, instrument, trace, warn}; use tracing::{debug, error, info, instrument, trace, warn};
pub type OneTimeKeys = HashMap<AlgorithmAndDeviceId, OneTimeKey>; pub type OneTimeKeys = BTreeMap<AlgorithmAndDeviceId, OneTimeKey>;
#[derive(Debug)] #[derive(Debug)]
pub struct OlmMachine { pub struct OlmMachine {
@ -193,8 +193,8 @@ impl OlmMachine {
pub async fn get_missing_sessions( pub async fn get_missing_sessions(
&mut self, &mut self,
users: impl Iterator<Item = &UserId>, users: impl Iterator<Item = &UserId>,
) -> HashMap<UserId, HashMap<DeviceId, KeyAlgorithm>> { ) -> BTreeMap<UserId, BTreeMap<DeviceId, KeyAlgorithm>> {
let mut missing = HashMap::new(); let mut missing = BTreeMap::new();
for user_id in users { for user_id in users {
let user_devices = self.store.get_user_devices(user_id).await.unwrap(); let user_devices = self.store.get_user_devices(user_id).await.unwrap();
@ -216,7 +216,7 @@ impl OlmMachine {
if is_missing { if is_missing {
if !missing.contains_key(user_id) { if !missing.contains_key(user_id) {
missing.insert(user_id.clone(), HashMap::new()); missing.insert(user_id.clone(), BTreeMap::new());
} }
let user_map = missing.get_mut(user_id).unwrap(); let user_map = missing.get_mut(user_id).unwrap();
@ -472,7 +472,7 @@ impl OlmMachine {
async fn device_keys(&self) -> DeviceKeys { async fn device_keys(&self) -> DeviceKeys {
let identity_keys = self.account.identity_keys(); let identity_keys = self.account.identity_keys();
let mut keys = HashMap::new(); let mut keys = BTreeMap::new();
keys.insert( keys.insert(
AlgorithmAndDeviceId(KeyAlgorithm::Curve25519, self.device_id.clone()), AlgorithmAndDeviceId(KeyAlgorithm::Curve25519, self.device_id.clone()),
@ -490,9 +490,9 @@ impl OlmMachine {
"keys": keys, "keys": keys,
}); });
let mut signatures = HashMap::new(); let mut signatures = BTreeMap::new();
let mut signature = HashMap::new(); let mut signature = BTreeMap::new();
signature.insert( signature.insert(
AlgorithmAndDeviceId(KeyAlgorithm::Ed25519, self.device_id.clone()), AlgorithmAndDeviceId(KeyAlgorithm::Ed25519, self.device_id.clone()),
self.sign_json(&device_keys).await, self.sign_json(&device_keys).await,
@ -518,7 +518,7 @@ impl OlmMachine {
async fn signed_one_time_keys(&self) -> StdResult<OneTimeKeys, ()> { async fn signed_one_time_keys(&self) -> StdResult<OneTimeKeys, ()> {
let _ = self.generate_one_time_keys().await?; let _ = self.generate_one_time_keys().await?;
let one_time_keys = self.account.one_time_keys().await; let one_time_keys = self.account.one_time_keys().await;
let mut one_time_key_map = HashMap::new(); let mut one_time_key_map = BTreeMap::new();
for (key_id, key) in one_time_keys.curve25519().iter() { for (key_id, key) in one_time_keys.curve25519().iter() {
let key_json = json!({ let key_json = json!({
@ -527,14 +527,14 @@ impl OlmMachine {
let signature = self.sign_json(&key_json).await; let signature = self.sign_json(&key_json).await;
let mut signature_map = HashMap::new(); let mut signature_map = BTreeMap::new();
signature_map.insert( signature_map.insert(
AlgorithmAndDeviceId(KeyAlgorithm::Ed25519, self.device_id.clone()), AlgorithmAndDeviceId(KeyAlgorithm::Ed25519, self.device_id.clone()),
signature, signature,
); );
let mut signatures = HashMap::new(); let mut signatures = BTreeMap::new();
signatures.insert(self.user_id.clone(), signature_map); signatures.insert(self.user_id.clone(), signature_map);
let signed_key = SignedKey { let signed_key = SignedKey {
@ -711,7 +711,7 @@ impl OlmMachine {
sender: &UserId, sender: &UserId,
sender_key: &str, sender_key: &str,
message: OlmMessage, message: OlmMessage,
) -> Result<(EventResult<ToDeviceEvent>, String)> { ) -> Result<(EventJson<ToDeviceEvent>, String)> {
// First try to decrypt using an existing session. // First try to decrypt using an existing session.
let plaintext = if let Some(p) = self let plaintext = if let Some(p) = self
.try_decrypt_olm_event(sender, sender_key, &message) .try_decrypt_olm_event(sender, sender_key, &message)
@ -778,7 +778,7 @@ impl OlmMachine {
&self, &self,
sender: &UserId, sender: &UserId,
plaintext: &str, plaintext: &str,
) -> Result<(EventResult<ToDeviceEvent>, String)> { ) -> Result<(EventJson<ToDeviceEvent>, String)> {
// TODO make the errors a bit more specific. // TODO make the errors a bit more specific.
let decrypted_json: Value = serde_json::from_str(&plaintext)?; let decrypted_json: Value = serde_json::from_str(&plaintext)?;
@ -793,13 +793,13 @@ impl OlmMachine {
.ok_or(OlmError::MissingCiphertext)?; .ok_or(OlmError::MissingCiphertext)?;
let recipient: UserId = serde_json::from_value(recipient)?; let recipient: UserId = serde_json::from_value(recipient)?;
let recipient_keys: HashMap<KeyAlgorithm, String> = serde_json::from_value( let recipient_keys: BTreeMap<KeyAlgorithm, String> = serde_json::from_value(
decrypted_json decrypted_json
.get("recipient_keys") .get("recipient_keys")
.cloned() .cloned()
.ok_or(OlmError::MissingCiphertext)?, .ok_or(OlmError::MissingCiphertext)?,
)?; )?;
let keys: HashMap<KeyAlgorithm, String> = serde_json::from_value( let keys: BTreeMap<KeyAlgorithm, String> = serde_json::from_value(
decrypted_json decrypted_json
.get("keys") .get("keys")
.cloned() .cloned()
@ -823,7 +823,7 @@ impl OlmMachine {
.ok_or(OlmError::MissingSigningKey)?; .ok_or(OlmError::MissingSigningKey)?;
Ok(( Ok((
serde_json::from_value::<EventResult<ToDeviceEvent>>(decrypted_json)?, serde_json::from_value::<EventJson<ToDeviceEvent>>(decrypted_json)?,
signing_key.to_owned(), signing_key.to_owned(),
)) ))
} }
@ -840,7 +840,7 @@ impl OlmMachine {
async fn decrypt_to_device_event( async fn decrypt_to_device_event(
&mut self, &mut self,
event: &ToDeviceEncrypted, event: &ToDeviceEncrypted,
) -> Result<EventResult<ToDeviceEvent>> { ) -> Result<EventJson<ToDeviceEvent>> {
info!("Decrypting to-device event"); info!("Decrypting to-device event");
let content = if let EncryptedEventContent::OlmV1Curve25519AesSha2(c) = &event.content { let content = if let EncryptedEventContent::OlmV1Curve25519AesSha2(c) = &event.content {
@ -1026,7 +1026,7 @@ impl OlmMachine {
message_type: (message_type as u32).into(), message_type: (message_type as u32).into(),
}; };
let mut content = HashMap::new(); let mut content = BTreeMap::new();
content.insert(recipient_sender_key.to_owned(), ciphertext); content.insert(recipient_sender_key.to_owned(), ciphertext);
@ -1119,11 +1119,11 @@ impl OlmMachine {
let mut message_vec = Vec::new(); let mut message_vec = Vec::new();
for user_map_chunk in user_map.chunks(OlmMachine::MAX_TO_DEVICE_MESSAGES) { for user_map_chunk in user_map.chunks(OlmMachine::MAX_TO_DEVICE_MESSAGES) {
let mut messages = HashMap::new(); let mut messages = BTreeMap::new();
for (session, device) in user_map_chunk { for (session, device) in user_map_chunk {
if !messages.contains_key(device.user_id()) { if !messages.contains_key(device.user_id()) {
messages.insert(device.user_id().clone(), HashMap::new()); messages.insert(device.user_id().clone(), BTreeMap::new());
}; };
let user_messages = messages.get_mut(device.user_id()).unwrap(); let user_messages = messages.get_mut(device.user_id()).unwrap();
@ -1139,7 +1139,7 @@ impl OlmMachine {
user_messages.insert( user_messages.insert(
DeviceIdOrAllDevices::DeviceId(device.device_id().clone()), DeviceIdOrAllDevices::DeviceId(device.device_id().clone()),
MessageEventContent::Encrypted(encrypted_content), EventJson::from(MessageEventContent::Encrypted(encrypted_content)),
); );
} }
@ -1167,9 +1167,9 @@ impl OlmMachine {
&mut self, &mut self,
sender_key: &str, sender_key: &str,
signing_key: &str, signing_key: &str,
event: &mut EventResult<ToDeviceEvent>, event: &mut EventJson<ToDeviceEvent>,
) -> Result<()> { ) -> Result<()> {
let event = if let EventResult::Ok(e) = event { let event = if let Ok(e) = event.deserialize() {
e e
} else { } else {
warn!("Decrypted to-device event failed to be parsed correctly"); warn!("Decrypted to-device event failed to be parsed correctly");
@ -1177,9 +1177,11 @@ impl OlmMachine {
}; };
match event { match event {
ToDeviceEvent::RoomKey(e) => self.add_room_key(sender_key, signing_key, e).await, ToDeviceEvent::RoomKey(mut e) => {
ToDeviceEvent::ForwardedRoomKey(e) => { self.add_room_key(sender_key, signing_key, &mut e).await
self.add_forwarded_room_key(sender_key, signing_key, e) }
ToDeviceEvent::ForwardedRoomKey(mut e) => {
self.add_forwarded_room_key(sender_key, signing_key, &mut e)
} }
_ => { _ => {
warn!("Received a unexpected encrypted to-device event"); warn!("Received a unexpected encrypted to-device event");
@ -1213,7 +1215,7 @@ impl OlmMachine {
self.uploaded_signed_key_count = Some(count); self.uploaded_signed_key_count = Some(count);
for event_result in &mut response.to_device.events { for event_result in &mut response.to_device.events {
let event = if let EventResult::Ok(e) = &event_result { let event = if let Ok(e) = event_result.deserialize() {
e e
} else { } else {
// Skip invalid events. // Skip invalid events.
@ -1223,7 +1225,7 @@ impl OlmMachine {
info!("Received a to-device event {:?}", event); info!("Received a to-device event {:?}", event);
match event { match &event {
ToDeviceEvent::RoomEncrypted(e) => { ToDeviceEvent::RoomEncrypted(e) => {
let decrypted_event = match self.decrypt_to_device_event(e).await { let decrypted_event = match self.decrypt_to_device_event(e).await {
Ok(e) => e, Ok(e) => e,
@ -1248,7 +1250,7 @@ impl OlmMachine {
| ToDeviceEvent::KeyVerificationKey(..) | ToDeviceEvent::KeyVerificationKey(..)
| ToDeviceEvent::KeyVerificationMac(..) | ToDeviceEvent::KeyVerificationMac(..)
| ToDeviceEvent::KeyVerificationRequest(..) | ToDeviceEvent::KeyVerificationRequest(..)
| ToDeviceEvent::KeyVerificationStart(..) => self.handle_verification_event(event), | ToDeviceEvent::KeyVerificationStart(..) => self.handle_verification_event(&event),
_ => continue, _ => continue,
} }
} }
@ -1257,7 +1259,7 @@ impl OlmMachine {
pub async fn decrypt_room_event( pub async fn decrypt_room_event(
&mut self, &mut self,
event: &EncryptedEvent, event: &EncryptedEvent,
) -> Result<EventResult<RoomEvent>> { ) -> Result<EventJson<RoomEvent>> {
let content = match &event.content { let content = match &event.content {
EncryptedEventContent::MegolmV1AesSha2(c) => c, EncryptedEventContent::MegolmV1AesSha2(c) => c,
_ => return Err(OlmError::UnsupportedAlgorithm), _ => return Err(OlmError::UnsupportedAlgorithm),
@ -1281,15 +1283,24 @@ impl OlmMachine {
.as_object_mut() .as_object_mut()
.ok_or(OlmError::NotAnObject)?; .ok_or(OlmError::NotAnObject)?;
let server_ts: u64 = event.origin_server_ts.into(); // TODO better number conversion here.
let server_ts = event
.origin_server_ts
.duration_since(std::time::SystemTime::UNIX_EPOCH)
.unwrap_or_default()
.as_millis();
let server_ts: i64 = server_ts.try_into().unwrap_or_default();
decrypted_object.insert("sender".to_owned(), event.sender.to_string().into()); decrypted_object.insert("sender".to_owned(), event.sender.to_string().into());
decrypted_object.insert("event_id".to_owned(), event.event_id.to_string().into()); decrypted_object.insert("event_id".to_owned(), event.event_id.to_string().into());
decrypted_object.insert("origin_server_ts".to_owned(), server_ts.into()); decrypted_object.insert("origin_server_ts".to_owned(), server_ts.into());
decrypted_object.insert("unsigned".to_owned(), event.unsigned.clone().into()); decrypted_object.insert(
"unsigned".to_owned(),
serde_json::to_value(&event.unsigned).unwrap_or_default(),
);
let decrypted_event = serde_json::from_value::<EventResult<RoomEvent>>(decrypted_value)?; let decrypted_event = serde_json::from_value::<EventJson<RoomEvent>>(decrypted_value)?;
trace!("Successfully decrypted megolm event {:?}", decrypted_event); trace!("Successfully decrypted megolm event {:?}", decrypted_event);
// TODO set the encryption info on the event (is it verified, was it // TODO set the encryption info on the event (is it verified, was it
// decrypted, sender key...) // decrypted, sender key...)

View File

@ -623,7 +623,7 @@ pub(crate) mod test {
use crate::identifiers::RoomId; use crate::identifiers::RoomId;
use olm_rs::session::OlmMessage; use olm_rs::session::OlmMessage;
use ruma_client_api::r0::keys::SignedKey; use ruma_client_api::r0::keys::SignedKey;
use std::collections::HashMap; use std::collections::BTreeMap;
use std::convert::TryFrom; use std::convert::TryFrom;
pub(crate) async fn get_account_and_session() -> (Account, Session) { pub(crate) async fn get_account_and_session() -> (Account, Session) {
@ -643,7 +643,7 @@ pub(crate) mod test {
.to_owned(); .to_owned();
let one_time_key = SignedKey { let one_time_key = SignedKey {
key: one_time_key, key: one_time_key,
signatures: HashMap::new(), signatures: BTreeMap::new(),
}; };
let sender_key = bob.identity_keys().curve25519().to_owned(); let sender_key = bob.identity_keys().curve25519().to_owned();
let session = alice let session = alice
@ -721,7 +721,7 @@ pub(crate) mod test {
let one_time_key = SignedKey { let one_time_key = SignedKey {
key: one_time_key, key: one_time_key,
signatures: HashMap::new(), signatures: BTreeMap::new(),
}; };
let mut bob_session = bob let mut bob_session = bob

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use std::collections::{HashMap, HashSet}; use std::collections::{BTreeMap, HashSet};
use std::convert::TryFrom; use std::convert::TryFrom;
use std::mem; use std::mem;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -348,7 +348,7 @@ impl SqliteStore {
.fetch_all(&mut *connection) .fetch_all(&mut *connection)
.await?; .await?;
let mut keys = HashMap::new(); let mut keys = BTreeMap::new();
for row in key_rows { for row in key_rows {
let algorithm = if let Ok(a) = KeyAlgorithm::try_from(&row.0 as &str) { let algorithm = if let Ok(a) = KeyAlgorithm::try_from(&row.0 as &str) {
@ -643,7 +643,7 @@ mod test {
use crate::crypto::device::test::get_device; use crate::crypto::device::test::get_device;
use crate::crypto::olm::GroupSessionKey; use crate::crypto::olm::GroupSessionKey;
use olm_rs::outbound_group_session::OlmOutboundGroupSession; use olm_rs::outbound_group_session::OlmOutboundGroupSession;
use std::collections::HashMap; use std::collections::BTreeMap;
use tempfile::tempdir; use tempfile::tempdir;
use super::{ use super::{
@ -709,7 +709,7 @@ mod test {
.to_owned(); .to_owned();
let one_time_key = SignedKey { let one_time_key = SignedKey {
key: one_time_key, key: one_time_key,
signatures: HashMap::new(), signatures: BTreeMap::new(),
}; };
let sender_key = bob.identity_keys().curve25519().to_owned(); let sender_key = bob.identity_keys().curve25519().to_owned();
let session = alice let session = alice

View File

@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use std::collections::HashMap; use std::collections::{BTreeMap, HashMap};
use std::convert::TryFrom; use std::convert::TryFrom;
use super::RoomMember; use super::RoomMember;
@ -63,7 +63,7 @@ pub struct PowerLevels {
/// The level required to send specific event types. /// The level required to send specific event types.
/// ///
/// This is a mapping from event type to power level required. /// This is a mapping from event type to power level required.
pub events: HashMap<EventType, Int>, pub events: BTreeMap<EventType, Int>,
/// The default level required to send message events. /// The default level required to send message events.
pub events_default: Int, pub events_default: Int,
/// The level required to invite a user. /// The level required to invite a user.

View File

@ -1,5 +1,6 @@
use crate::api; use crate::api;
use crate::events::room::power_levels::PowerLevelsEventContent; use crate::events::room::power_levels::PowerLevelsEventContent;
use crate::events::EventJson;
use crate::identifiers::{RoomId, UserId}; use crate::identifiers::{RoomId, UserId};
use api::r0::filter::RoomEventFilter; use api::r0::filter::RoomEventFilter;
use api::r0::membership::Invite3pid; use api::r0::membership::Invite3pid;
@ -163,7 +164,7 @@ impl Into<create_room::Request> for RoomBuilder {
invite_3pid: self.invite_3pid, invite_3pid: self.invite_3pid,
is_direct: self.is_direct, is_direct: self.is_direct,
name: self.name, name: self.name,
power_level_content_override: self.power_level_content_override, power_level_content_override: self.power_level_content_override.map(EventJson::from),
preset: self.preset, preset: self.preset,
room_alias_name: self.room_alias_name, room_alias_name: self.room_alias_name,
room_version: self.room_version, room_version: self.room_version,
@ -177,6 +178,7 @@ impl Into<create_room::Request> for RoomBuilder {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// # use std::convert::TryFrom;
/// # use matrix_sdk::{AsyncClient, MessagesRequestBuilder}; /// # use matrix_sdk::{AsyncClient, MessagesRequestBuilder};
/// # use matrix_sdk::api::r0::message::get_message_events::{self, Direction}; /// # use matrix_sdk::api::r0::message::get_message_events::{self, Direction};
/// # use matrix_sdk::identifiers::RoomId; /// # use matrix_sdk::identifiers::RoomId;
@ -184,8 +186,8 @@ impl Into<create_room::Request> for RoomBuilder {
/// # let homeserver = Url::parse("http://example.com").unwrap(); /// # let homeserver = Url::parse("http://example.com").unwrap();
/// # let mut rt = tokio::runtime::Runtime::new().unwrap(); /// # let mut rt = tokio::runtime::Runtime::new().unwrap();
/// # rt.block_on(async { /// # rt.block_on(async {
/// # let room_id = RoomId::new(homeserver.as_str()).unwrap(); /// # let room_id = RoomId::try_from("!test:localhost").unwrap();
/// # let last_sync_token = "".to_string();; /// # let last_sync_token = "".to_string();
/// let mut cli = AsyncClient::new(homeserver, None).unwrap(); /// let mut cli = AsyncClient::new(homeserver, None).unwrap();
/// ///
/// let mut builder = MessagesRequestBuilder::new(); /// let mut builder = MessagesRequestBuilder::new();
@ -288,7 +290,7 @@ impl Into<get_message_events::Request> for MessagesRequestBuilder {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::collections::HashMap; use std::collections::{BTreeMap, HashMap};
use super::*; use super::*;
use crate::events::room::power_levels::NotificationPowerLevels; use crate::events::room::power_levels::NotificationPowerLevels;
@ -325,7 +327,7 @@ mod test {
.is_direct(true) .is_direct(true)
.power_level_override(PowerLevelsEventContent { .power_level_override(PowerLevelsEventContent {
ban: Int::max_value(), ban: Int::max_value(),
events: HashMap::default(), events: BTreeMap::default(),
events_default: Int::min_value(), events_default: Int::min_value(),
invite: Int::min_value(), invite: Int::min_value(),
kick: Int::min_value(), kick: Int::min_value(),
@ -335,7 +337,7 @@ mod test {
notifications: NotificationPowerLevels { notifications: NotificationPowerLevels {
room: Int::min_value(), room: Int::min_value(),
}, },
users: HashMap::default(), users: BTreeMap::default(),
}) })
.preset(RoomPreset::PrivateChat) .preset(RoomPreset::PrivateChat)
.room_alias_name("room_alias") .room_alias_name("room_alias")

View File

@ -10,7 +10,7 @@ use crate::events::{
only::Event, only::Event,
}, },
presence::PresenceEvent, presence::PresenceEvent,
EventResult, TryFromRaw, EventJson, TryFromRaw,
}; };
use crate::identifiers::{RoomId, UserId}; use crate::identifiers::{RoomId, UserId};
use crate::AsyncClient; use crate::AsyncClient;
@ -97,9 +97,9 @@ impl EventBuilder {
) -> Self { ) -> Self {
let val = fs::read_to_string(path.as_ref()) let val = fs::read_to_string(path.as_ref())
.expect(&format!("file not found {:?}", path.as_ref())); .expect(&format!("file not found {:?}", path.as_ref()));
let event = serde_json::from_str::<EventResult<Ev>>(&val) let event = serde_json::from_str::<EventJson<Ev>>(&val)
.unwrap() .unwrap()
.into_result() .deserialize()
.unwrap(); .unwrap();
self.ephemeral.push(variant(event)); self.ephemeral.push(variant(event));
self self
@ -113,9 +113,9 @@ impl EventBuilder {
) -> Self { ) -> Self {
let val = fs::read_to_string(path.as_ref()) let val = fs::read_to_string(path.as_ref())
.expect(&format!("file not found {:?}", path.as_ref())); .expect(&format!("file not found {:?}", path.as_ref()));
let event = serde_json::from_str::<EventResult<Ev>>(&val) let event = serde_json::from_str::<EventJson<Ev>>(&val)
.unwrap() .unwrap()
.into_result() .deserialize()
.unwrap(); .unwrap();
self.account_data.push(variant(event)); self.account_data.push(variant(event));
self self
@ -129,9 +129,9 @@ impl EventBuilder {
) -> Self { ) -> Self {
let val = fs::read_to_string(path.as_ref()) let val = fs::read_to_string(path.as_ref())
.expect(&format!("file not found {:?}", path.as_ref())); .expect(&format!("file not found {:?}", path.as_ref()));
let event = serde_json::from_str::<EventResult<Ev>>(&val) let event = serde_json::from_str::<EventJson<Ev>>(&val)
.unwrap() .unwrap()
.into_result() .deserialize()
.unwrap(); .unwrap();
self.room_events.push(variant(event)); self.room_events.push(variant(event));
self self
@ -145,9 +145,9 @@ impl EventBuilder {
) -> Self { ) -> Self {
let val = fs::read_to_string(path.as_ref()) let val = fs::read_to_string(path.as_ref())
.expect(&format!("file not found {:?}", path.as_ref())); .expect(&format!("file not found {:?}", path.as_ref()));
let event = serde_json::from_str::<EventResult<Ev>>(&val) let event = serde_json::from_str::<EventJson<Ev>>(&val)
.unwrap() .unwrap()
.into_result() .deserialize()
.unwrap(); .unwrap();
self.state_events.push(variant(event)); self.state_events.push(variant(event));
self self
@ -157,9 +157,9 @@ impl EventBuilder {
pub fn add_presence_event_from_file<P: AsRef<Path>>(mut self, path: P) -> Self { pub fn add_presence_event_from_file<P: AsRef<Path>>(mut self, path: P) -> Self {
let val = fs::read_to_string(path.as_ref()) let val = fs::read_to_string(path.as_ref())
.expect(&format!("file not found {:?}", path.as_ref())); .expect(&format!("file not found {:?}", path.as_ref()));
let event = serde_json::from_str::<EventResult<PresenceEvent>>(&val) let event = serde_json::from_str::<EventJson<PresenceEvent>>(&val)
.unwrap() .unwrap()
.into_result() .deserialize()
.unwrap(); .unwrap();
self.presence_events.push(event); self.presence_events.push(event);
self self
@ -344,7 +344,7 @@ impl ClientTestRunner {
} }
for event in &self.room_events { for event in &self.room_events {
cli.receive_joined_timeline_event(room_id, &mut EventResult::Ok(event.clone())) cli.receive_joined_timeline_event(room_id, &mut EventJson::from(event.clone()))
.await; .await;
} }
for event in &self.presence_events { for event in &self.presence_events {