Add new RoomEvent type, try to decrypt event

master
Felix Häcker 2021-07-28 19:49:41 +02:00
parent f3620e7072
commit 91e9a5f9f3
3 changed files with 55 additions and 3 deletions

View File

@ -47,6 +47,8 @@ use matrix_sdk_base::crypto::{
store::CryptoStoreError, AttachmentDecryptor, OutgoingRequests, RoomMessageRequest,
ToDeviceRequest,
};
#[cfg(feature = "encryption")]
use matrix_sdk_base::deserialized_responses::RoomEvent;
use matrix_sdk_base::{
deserialized_responses::SyncResponse,
media::{MediaEventContent, MediaFormat, MediaRequest, MediaThumbnailSize, MediaType},
@ -56,6 +58,8 @@ use mime::{self, Mime};
#[cfg(feature = "sso_login")]
use rand::{thread_rng, Rng};
use reqwest::header::InvalidHeaderValue;
#[cfg(feature = "encryption")]
use ruma::events::{AnyMessageEvent, AnyRoomEvent, AnySyncMessageEvent};
use ruma::{api::SendAccessToken, events::AnyMessageEventContent, MxcUri};
#[cfg(feature = "sso_login")]
use tokio::{net::TcpListener, sync::oneshot};
@ -946,6 +950,40 @@ impl Client {
self.store().get_room(room_id).and_then(|room| room::Left::new(self.clone(), room))
}
/// Tries to decrypt a `AnyRoomEvent`. Returns unencrypted room event when
/// decryption fails.
#[cfg(feature = "encryption")]
#[cfg_attr(feature = "docs", doc(cfg(encryption)))]
pub(crate) async fn decrypt_room_event(&self, event: &AnyRoomEvent) -> RoomEvent {
if let Some(machine) = self.base_client.olm_machine().await {
if let AnyRoomEvent::Message(event) = event {
if let AnyMessageEvent::RoomEncrypted(_) = event {
let room_id = event.room_id();
// Turn the AnyMessageEvent into a AnySyncMessageEvent
let event = event.clone().into();
if let AnySyncMessageEvent::RoomEncrypted(e) = event {
if let Ok(decrypted) = machine.decrypt_room_event(&e, &room_id).await {
let event = decrypted
.event
.deserialize()
.unwrap()
.into_full_event(room_id.clone())
.into();
let encryption_info = decrypted.encryption_info;
// Return decrytped room event
return RoomEvent { event, encryption_info };
}
}
}
}
}
// Fallback to unencrypted room event
RoomEvent { event: event.into(), encryption_info: None }
}
/// Gets the homeservers supported login types.
///
/// This should be the first step when trying to login so you can call the

View File

@ -1,6 +1,6 @@
use std::{ops::Deref, sync::Arc};
use matrix_sdk_base::deserialized_responses::MembersResponse;
use matrix_sdk_base::deserialized_responses::{MembersResponse, RoomEvent};
use matrix_sdk_common::locks::Mutex;
use ruma::{
api::client::r0::{
@ -153,9 +153,15 @@ impl Common {
pub async fn event(
&self,
request: impl Into<get_room_event::Request<'_>>,
) -> Result<get_room_event::Response> {
) -> Result<RoomEvent> {
let request = request.into();
self.client.send(request, None).await
let event = self.client.send(request, None).await?.event.deserialize()?;
#[cfg(feature = "encryption")]
return Ok(self.client.decrypt_room_event(&event).await);
#[cfg(not(feature = "encryption"))]
return Ok(RoomEvent { event: event.into(), encryption_info: None });
}
pub(crate) async fn request_members(&self) -> Result<Option<MembersResponse>> {

View File

@ -133,6 +133,14 @@ impl SyncResponse {
}
}
pub struct RoomEvent {
/// The actual event.
pub event: Raw<ruma::events::AnyRoomEvent>,
/// The encryption info about the event. Will be `None` if the event was not
/// encrypted.
pub encryption_info: Option<EncryptionInfo>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Rooms {
/// The rooms that the user has left or been banned from.