Restructure the withheld code types
This commit is contained in:
@@ -1289,15 +1289,15 @@ impl OlmMachine {
|
||||
if let MegolmError::Decryption(DecryptionError::UnknownMessageIndex(_, _)) =
|
||||
error
|
||||
{
|
||||
let withheld_info = self
|
||||
let withheld_code = self
|
||||
.store
|
||||
.get_withheld_info(room_id, content.session_id())
|
||||
.await?
|
||||
.map(|i| i.withheld_code);
|
||||
.map(|i| i.withheld_code());
|
||||
|
||||
if withheld_info.is_some() {
|
||||
if withheld_code.is_some() {
|
||||
// Partially withheld, report with a withheld code if we have one.
|
||||
MegolmError::MissingRoomKey(withheld_info)
|
||||
MegolmError::MissingRoomKey(withheld_code)
|
||||
} else {
|
||||
error
|
||||
}
|
||||
@@ -1307,12 +1307,13 @@ impl OlmMachine {
|
||||
),
|
||||
}
|
||||
} else {
|
||||
let withheld_info = self
|
||||
let withheld_code = self
|
||||
.store
|
||||
.get_withheld_info(room_id, content.session_id())
|
||||
.await?
|
||||
.map(|i| i.withheld_code);
|
||||
Err(MegolmError::MissingRoomKey(withheld_info))
|
||||
.map(|i| i.withheld_code());
|
||||
|
||||
Err(MegolmError::MissingRoomKey(withheld_code))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ use crate::{
|
||||
MegolmV1AesSha2Content, RoomEncryptedEventContent, RoomEventEncryptionScheme,
|
||||
},
|
||||
room_key::{MegolmV1AesSha2Content as MegolmV1AesSha2RoomKeyContent, RoomKeyContent},
|
||||
room_key_withheld::WithheldCode,
|
||||
room_key_withheld::{RoomKeyWithheldContent, WithheldCode},
|
||||
},
|
||||
EventEncryptionAlgorithm,
|
||||
},
|
||||
@@ -242,6 +242,19 @@ impl OutboundGroupSession {
|
||||
self.to_share_with_set.insert(request_id, (request, share_infos));
|
||||
}
|
||||
|
||||
/// Create a new `m.room_key.withheld` event content with the given code for
|
||||
/// this outbound group session.
|
||||
pub fn withheld_code(&self, code: WithheldCode) -> RoomKeyWithheldContent {
|
||||
RoomKeyWithheldContent::new(
|
||||
self.settings().algorithm.to_owned(),
|
||||
code,
|
||||
self.room_id().to_owned(),
|
||||
self.session_id().to_owned(),
|
||||
self.sender_key().to_owned(),
|
||||
(*self.device_id).to_owned(),
|
||||
)
|
||||
}
|
||||
|
||||
/// This should be called if an the user wishes to rotate this session.
|
||||
pub fn invalidate_session(&self) {
|
||||
self.invalidated.store(true, Ordering::Relaxed)
|
||||
|
||||
@@ -586,15 +586,7 @@ impl GroupSessionManager {
|
||||
) -> OlmResult<()> {
|
||||
// Convert a withheld code for the group session into a to-device event content.
|
||||
let to_content = |code| {
|
||||
let content = RoomKeyWithheldContent::create(
|
||||
group_session.settings().algorithm.to_owned(),
|
||||
code,
|
||||
group_session.room_id().to_owned(),
|
||||
group_session.session_id().to_owned(),
|
||||
group_session.sender_key(),
|
||||
Some(self.account.device_id().to_owned()),
|
||||
);
|
||||
|
||||
let content = group_session.withheld_code(code);
|
||||
Raw::new(&content).expect("We can always serialize a withheld content info").cast()
|
||||
};
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ macro_rules! cryptostore_integration_tests {
|
||||
use matrix_sdk_test::async_test;
|
||||
use ruma::{
|
||||
device_id, encryption::SignedKey, room_id, serde::Base64, user_id, DeviceId,
|
||||
OwnedDeviceId, OwnedUserId, TransactionId, UserId,
|
||||
JsOption, OwnedDeviceId, OwnedUserId, TransactionId, UserId,
|
||||
};
|
||||
use $crate::{
|
||||
olm::{
|
||||
@@ -22,7 +22,8 @@ macro_rules! cryptostore_integration_tests {
|
||||
testing::{get_device, get_other_identity, get_own_identity},
|
||||
types::{
|
||||
events::{
|
||||
room_key_request::MegolmV1AesSha2Content, room_key_withheld::WithheldCode,
|
||||
room_key_request::MegolmV1AesSha2Content,
|
||||
room_key_withheld::{CommonWithheldCodeContent, WithheldCode},
|
||||
},
|
||||
EventEncryptionAlgorithm,
|
||||
},
|
||||
@@ -629,30 +630,28 @@ macro_rules! cryptostore_integration_tests {
|
||||
let session_id_1 = "GBnDxGP9i3IkPsz3/ihNr6P7qjIXxSRVWZ1MYmSn09w";
|
||||
let session_id_2 = "IDLtnNCH2kIr3xIf1B7JFkGpQmTjyMca2jww+X6zeOE";
|
||||
|
||||
let info = DirectWithheldInfo {
|
||||
let content = CommonWithheldCodeContent {
|
||||
room_id: room_id.to_owned(),
|
||||
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
session_id: session_id_1.into(),
|
||||
claimed_sender_key: Curve25519PublicKey::from_base64(
|
||||
from_device: JsOption::Undefined,
|
||||
other: Default::default(),
|
||||
sender_key: Curve25519PublicKey::from_base64(
|
||||
"9n7mdWKOjr9c4NTlG6zV8dbFtNK79q9vZADoh7nMUwA",
|
||||
)
|
||||
.unwrap(),
|
||||
withheld_code: WithheldCode::Unverified,
|
||||
};
|
||||
|
||||
let info = DirectWithheldInfo::new(
|
||||
EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
WithheldCode::Unverified,
|
||||
content.to_owned(),
|
||||
);
|
||||
info_list.push(info);
|
||||
|
||||
let info = DirectWithheldInfo {
|
||||
room_id: room_id.to_owned(),
|
||||
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
session_id: session_id_2.into(),
|
||||
claimed_sender_key: Curve25519PublicKey::from_base64(
|
||||
"9n7mdWKOjr9c4NTlG6zV8dbFtNK79q9vZADoh7nMUwA",
|
||||
)
|
||||
.unwrap(),
|
||||
withheld_code: WithheldCode::Blacklisted,
|
||||
};
|
||||
|
||||
let info = DirectWithheldInfo::new(
|
||||
EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
WithheldCode::Blacklisted,
|
||||
content,
|
||||
);
|
||||
info_list.push(info);
|
||||
|
||||
let changes = Changes { withheld_session_info: info_list, ..Default::default() };
|
||||
@@ -662,9 +661,9 @@ macro_rules! cryptostore_integration_tests {
|
||||
let is_withheld = store.get_withheld_info(room_id, session_id_1).await.unwrap();
|
||||
|
||||
if let Some(info) = is_withheld {
|
||||
let actual_code = info.withheld_code;
|
||||
assert_eq!(EventEncryptionAlgorithm::MegolmV1AesSha2, info.algorithm);
|
||||
assert_eq!(room_id, info.room_id);
|
||||
let actual_code = info.withheld_code();
|
||||
assert_eq!(EventEncryptionAlgorithm::MegolmV1AesSha2, info.algorithm());
|
||||
assert_eq!(room_id, info.room_id());
|
||||
assert_eq!(WithheldCode::Unverified, actual_code);
|
||||
} else {
|
||||
panic!();
|
||||
@@ -673,7 +672,7 @@ macro_rules! cryptostore_integration_tests {
|
||||
let is_withheld = store.get_withheld_info(room_id, session_id_2).await.unwrap();
|
||||
|
||||
if let Some(info) = is_withheld {
|
||||
let actual_code = info.withheld_code;
|
||||
let actual_code = info.withheld_code();
|
||||
assert_eq!(WithheldCode::Blacklisted, actual_code);
|
||||
} else {
|
||||
panic!();
|
||||
|
||||
@@ -150,7 +150,7 @@ impl CryptoStore for MemoryStore {
|
||||
}
|
||||
|
||||
for info in changes.withheld_session_info {
|
||||
self.direct_withheld_info.insert(info.session_id.to_owned(), info.to_owned());
|
||||
self.direct_withheld_info.insert(info.session_id().to_owned(), info);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -285,19 +285,11 @@ impl CryptoStore for MemoryStore {
|
||||
room_id: &RoomId,
|
||||
session_id: &str,
|
||||
) -> Result<Option<DirectWithheldInfo>> {
|
||||
let entry = self.direct_withheld_info.entry(session_id.to_owned());
|
||||
|
||||
match entry {
|
||||
Entry::Occupied(e) => {
|
||||
let found = e.get();
|
||||
if found.room_id == room_id {
|
||||
Ok(Some(found.to_owned()))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
Entry::Vacant(_) => Ok(None),
|
||||
}
|
||||
Ok(self
|
||||
.direct_withheld_info
|
||||
.get(session_id)
|
||||
.filter(|e| e.value().room_id() == room_id)
|
||||
.map(|e| e.value().to_owned()))
|
||||
}
|
||||
|
||||
async fn get_room_settings(&self, _room_id: &RoomId) -> Result<Option<RoomSettings>> {
|
||||
|
||||
@@ -16,33 +16,126 @@
|
||||
//! to all devices present in the room. Sometimes this may be inadvertent (for
|
||||
//! example, if the sending device is not aware of some devices that have
|
||||
//! joined), but some times, this may be purposeful.
|
||||
use ruma::OwnedRoomId;
|
||||
|
||||
use ruma::RoomId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vodozemac::Curve25519PublicKey;
|
||||
|
||||
use crate::types::{
|
||||
events::room_key_withheld::{MegolmV1AesSha2WithheldContent, WithheldCode},
|
||||
events::room_key_withheld::{
|
||||
CommonWithheldCodeContent, MegolmV1AesSha2WithheldContent, WithheldCode,
|
||||
},
|
||||
EventEncryptionAlgorithm,
|
||||
};
|
||||
|
||||
///
|
||||
/// We want to store when the owner of the group session sent us a withheld
|
||||
/// code. It's not storing withheld code that can be sent in a
|
||||
/// `m.forwarded_room_key`, it's another sort of relation as the same key can be
|
||||
/// withheld for several reasons by different devices.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
|
||||
pub struct DirectWithheldInfo {
|
||||
/// The room of the group key.
|
||||
pub room_id: OwnedRoomId,
|
||||
/// The key algorithm
|
||||
pub algorithm: EventEncryptionAlgorithm,
|
||||
/// The group session id.
|
||||
pub session_id: String,
|
||||
/// The session creator device identity.
|
||||
/// Claimed because withheld codes message are sent in clear
|
||||
pub claimed_sender_key: Curve25519PublicKey,
|
||||
/// The reason why the key was not distributed
|
||||
pub withheld_code: WithheldCode,
|
||||
pub enum DirectWithheldInfo {
|
||||
MegolmV1(MegolmV1WithheldInfo),
|
||||
#[cfg(feature = "experimental-algorithms")]
|
||||
MegolmV2(MegolmV2WithheldInfo),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
|
||||
pub enum MegolmV1WithheldInfo {
|
||||
BlackListed(Box<CommonWithheldCodeContent>),
|
||||
Unverified(Box<CommonWithheldCodeContent>),
|
||||
}
|
||||
|
||||
#[cfg(feature = "experimental-algorithms")]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
|
||||
pub enum MegolmV2WithheldInfo {
|
||||
BlackListed(Box<CommonWithheldCodeContent>),
|
||||
Unverified(Box<CommonWithheldCodeContent>),
|
||||
}
|
||||
|
||||
impl DirectWithheldInfo {
|
||||
pub fn new(
|
||||
algorithm: EventEncryptionAlgorithm,
|
||||
code: WithheldCode,
|
||||
content: CommonWithheldCodeContent,
|
||||
) -> Self {
|
||||
let content = content.into();
|
||||
|
||||
match algorithm {
|
||||
EventEncryptionAlgorithm::MegolmV1AesSha2 => match code {
|
||||
WithheldCode::Blacklisted => {
|
||||
Self::MegolmV1(MegolmV1WithheldInfo::BlackListed(content))
|
||||
}
|
||||
WithheldCode::Unverified => {
|
||||
Self::MegolmV1(MegolmV1WithheldInfo::Unverified(content))
|
||||
}
|
||||
_ => panic!("Unsupported direct withheld code"),
|
||||
},
|
||||
#[cfg(feature = "experimental-algorithms")]
|
||||
EventEncryptionAlgorithm::MegolmV1AesSha2 => match code {
|
||||
WithheldCode::Blacklisted => {
|
||||
Self::MegolmV2(MegolmV2WithheldInfo::BlackListed(content))
|
||||
}
|
||||
WithheldCode::Unverified => {
|
||||
Self::MegolmV2(MegolmV2WithheldInfo::Unverified(content))
|
||||
}
|
||||
_ => panic!("Unsupported direct withheld code"),
|
||||
},
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn algorithm(&self) -> EventEncryptionAlgorithm {
|
||||
match self {
|
||||
DirectWithheldInfo::MegolmV1(_) => EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
#[cfg(feature = "experimental-algorithms")]
|
||||
DirectWithheldInfo::MegolmV2(_) => EventEncryptionAlgorithm::MegolmV2AesSha2,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn withheld_code(&self) -> WithheldCode {
|
||||
match self {
|
||||
DirectWithheldInfo::MegolmV1(c) => match c {
|
||||
MegolmV1WithheldInfo::BlackListed(_) => WithheldCode::Blacklisted,
|
||||
MegolmV1WithheldInfo::Unverified(_) => WithheldCode::Unverified,
|
||||
},
|
||||
#[cfg(feature = "experimental-algorithms")]
|
||||
DirectWithheldInfo::MegolmV2(c) => match c {
|
||||
MegolmV2WithheldInfo::BlackListed(_) => WithheldCode::Blacklisted,
|
||||
MegolmV2WithheldInfo::Unverified(_) => WithheldCode::Unverified,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn room_id(&self) -> &RoomId {
|
||||
match self {
|
||||
DirectWithheldInfo::MegolmV1(c) => match c {
|
||||
MegolmV1WithheldInfo::BlackListed(c) | MegolmV1WithheldInfo::Unverified(c) => {
|
||||
&c.room_id
|
||||
}
|
||||
},
|
||||
#[cfg(feature = "experimental-algorithms")]
|
||||
DirectWithheldInfo::MegolmV2(c) => match c {
|
||||
MegolmV2WithheldInfo::BlackListed(c) | MegolmV2WithheldInfo::Unverified(c) => {
|
||||
&c.room_id
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn session_id(&self) -> &str {
|
||||
match self {
|
||||
DirectWithheldInfo::MegolmV1(c) => match c {
|
||||
MegolmV1WithheldInfo::BlackListed(c) | MegolmV1WithheldInfo::Unverified(c) => {
|
||||
&c.session_id
|
||||
}
|
||||
},
|
||||
#[cfg(feature = "experimental-algorithms")]
|
||||
DirectWithheldInfo::MegolmV2(c) => match c {
|
||||
MegolmV2WithheldInfo::BlackListed(c) | MegolmV2WithheldInfo::Unverified(c) => {
|
||||
&c.session_id
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&MegolmV1AesSha2WithheldContent> for DirectWithheldInfo {
|
||||
@@ -50,16 +143,15 @@ impl TryFrom<&MegolmV1AesSha2WithheldContent> for DirectWithheldInfo {
|
||||
|
||||
fn try_from(value: &MegolmV1AesSha2WithheldContent) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
MegolmV1AesSha2WithheldContent::AnyContent((code, content)) => Ok(DirectWithheldInfo {
|
||||
room_id: content.room_id.to_owned(),
|
||||
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
session_id: content.session_id.to_owned(),
|
||||
claimed_sender_key: content.sender_key,
|
||||
withheld_code: code.clone(),
|
||||
}),
|
||||
MegolmV1AesSha2WithheldContent::NoOlmContent(_) => {
|
||||
Err("No Olm can't be converted to direct info")
|
||||
MegolmV1AesSha2WithheldContent::BlackListed(c) => {
|
||||
Ok(Self::MegolmV1(MegolmV1WithheldInfo::BlackListed(c.to_owned())))
|
||||
}
|
||||
MegolmV1AesSha2WithheldContent::Unverified(c) => {
|
||||
Ok(Self::MegolmV1(MegolmV1WithheldInfo::Unverified(c.to_owned())))
|
||||
}
|
||||
MegolmV1AesSha2WithheldContent::Unauthorised(_) => todo!(),
|
||||
MegolmV1AesSha2WithheldContent::Unavailable(_) => todo!(),
|
||||
MegolmV1AesSha2WithheldContent::NoOlm(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! Types for the `m.room_key.withheld` events.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use ruma::{
|
||||
@@ -44,97 +45,78 @@ pub type RoomKeyWithheldEvent = ToDeviceEvent<RoomKeyWithheldContent>;
|
||||
pub enum RoomKeyWithheldContent {
|
||||
/// The `m.megolm.v1.aes-sha2` variant of the `m.room_key.withheld` content.
|
||||
MegolmV1AesSha2(MegolmV1AesSha2WithheldContent),
|
||||
/// The `m.megolm.v2.aes-sha2` variant of the `m.room_key.withheld` content.
|
||||
// The `m.megolm.v2.aes-sha2` variant of the `m.room_key.withheld` content.
|
||||
#[cfg(feature = "experimental-algorithms")]
|
||||
MegolmV2AesSha2(MegolmV2AesSha2WithheldContent),
|
||||
/// An unknown and unsupported variant of the `m.room_key.withheld` content.
|
||||
Unknown(UnknownRoomKeyWithHeld),
|
||||
}
|
||||
|
||||
macro_rules! construct_withheld_content {
|
||||
($algorithm:ident, $code:ident, $room_id:ident, $session_id:ident, $sender_key:ident, $from_device:ident) => {
|
||||
match $code {
|
||||
WithheldCode::Blacklisted
|
||||
| WithheldCode::Unverified
|
||||
| WithheldCode::Unauthorised
|
||||
| WithheldCode::Unavailable => {
|
||||
let content = CommonWithheldCodeContent {
|
||||
$room_id,
|
||||
$session_id,
|
||||
$sender_key,
|
||||
$from_device,
|
||||
other: Default::default(),
|
||||
};
|
||||
|
||||
RoomKeyWithheldContent::$algorithm(
|
||||
MegolmV1AesSha2WithheldContent::from_code_and_content($code, content),
|
||||
)
|
||||
}
|
||||
WithheldCode::NoOlm => {
|
||||
RoomKeyWithheldContent::$algorithm(MegolmV1AesSha2WithheldContent::NoOlm(
|
||||
NoOlmWithheldContent { $sender_key, $from_device, other: Default::default() }
|
||||
.into(),
|
||||
))
|
||||
}
|
||||
_ => unreachable!("Can't create an unknown withheld code content"),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl RoomKeyWithheldContent {
|
||||
/// Creates a withheld content from the given info
|
||||
pub fn create(
|
||||
pub fn new(
|
||||
algorithm: EventEncryptionAlgorithm,
|
||||
code: WithheldCode,
|
||||
room_id: OwnedRoomId,
|
||||
session_id: String,
|
||||
sender_key: Curve25519PublicKey,
|
||||
from_device: Option<OwnedDeviceId>,
|
||||
from_device: OwnedDeviceId,
|
||||
) -> Self {
|
||||
let from_device = JsOption::Some(from_device);
|
||||
|
||||
match algorithm {
|
||||
EventEncryptionAlgorithm::MegolmV1AesSha2 => {
|
||||
let other = match code {
|
||||
WithheldCode::NoOlm => {
|
||||
let content = NoOlmWithheldContent {
|
||||
sender_key,
|
||||
reason: JsOption::Some(code.to_string()),
|
||||
from_device: JsOption::from_implicit_option(from_device),
|
||||
other: Default::default(),
|
||||
};
|
||||
serde_json::to_value(content)
|
||||
.expect("We can always serialize this construction")
|
||||
}
|
||||
_ => {
|
||||
let content = AnyWithheldContent {
|
||||
room_id,
|
||||
session_id,
|
||||
sender_key,
|
||||
// code: code.clone(),
|
||||
reason: JsOption::Some(code.to_string()),
|
||||
from_device: JsOption::from_implicit_option(from_device),
|
||||
other: Default::default(),
|
||||
};
|
||||
serde_json::to_value(content)
|
||||
.expect("We can always serialize this construction")
|
||||
}
|
||||
};
|
||||
let helper = WithheldHelper {
|
||||
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
construct_withheld_content!(
|
||||
MegolmV1AesSha2,
|
||||
code,
|
||||
other,
|
||||
};
|
||||
RoomKeyWithheldContent::try_from(helper)
|
||||
.expect("We can always serialize this construction")
|
||||
room_id,
|
||||
session_id,
|
||||
sender_key,
|
||||
from_device
|
||||
)
|
||||
}
|
||||
#[cfg(feature = "experimental-algorithms")]
|
||||
EventEncryptionAlgorithm::MegolmV2AesSha2 => {
|
||||
let other = match code {
|
||||
WithheldCode::NoOlm => {
|
||||
let content = NoOlmWithheldContent {
|
||||
sender_key,
|
||||
reason: JsOption::Some(code.to_string()),
|
||||
from_device: JsOption::from_implicit_option(from_device),
|
||||
other: Default::default(),
|
||||
};
|
||||
serde_json::to_value(content)
|
||||
.expect("We can always serialize this construction")
|
||||
}
|
||||
_ => {
|
||||
let content = AnyWithheldContent {
|
||||
room_id,
|
||||
session_id,
|
||||
sender_key,
|
||||
reason: JsOption::Some(code.to_string()),
|
||||
from_device: JsOption::from_implicit_option(from_device),
|
||||
other: Default::default(),
|
||||
};
|
||||
serde_json::to_value(content)
|
||||
.expect("We can always serialize this construction")
|
||||
}
|
||||
};
|
||||
let helper = WithheldHelper {
|
||||
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
construct_withheld_content!(
|
||||
MegolmV2AesSha2,
|
||||
code,
|
||||
other,
|
||||
};
|
||||
RoomKeyWithheldContent::try_from(helper)
|
||||
.expect("We can always serialize this construction")
|
||||
room_id,
|
||||
session_id,
|
||||
sender_key,
|
||||
from_device
|
||||
)
|
||||
}
|
||||
_ => RoomKeyWithheldContent::Unknown(UnknownRoomKeyWithHeld {
|
||||
algorithm,
|
||||
code,
|
||||
other: Default::default(),
|
||||
}),
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,70 +197,74 @@ impl std::fmt::Display for WithheldCode {
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
struct WithheldHelper {
|
||||
pub algorithm: EventEncryptionAlgorithm,
|
||||
pub reason: JsOption<String>,
|
||||
pub code: WithheldCode,
|
||||
#[serde(flatten)]
|
||||
other: Value,
|
||||
}
|
||||
|
||||
/// The content of a withheld event depends on the
|
||||
/// value of the code. This enum reflect that for better type safety
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum MegolmV1AesSha2WithheldContent {
|
||||
/// Content for regular withheld content
|
||||
AnyContent((WithheldCode, Box<AnyWithheldContent>)),
|
||||
/// Content for no_olm withheld content
|
||||
NoOlmContent(Box<NoOlmWithheldContent>),
|
||||
BlackListed(Box<CommonWithheldCodeContent>),
|
||||
Unverified(Box<CommonWithheldCodeContent>),
|
||||
Unauthorised(Box<CommonWithheldCodeContent>),
|
||||
Unavailable(Box<CommonWithheldCodeContent>),
|
||||
NoOlm(Box<NoOlmWithheldContent>),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||
pub struct CommonWithheldCodeContent {
|
||||
/// The room where the key is used.
|
||||
pub room_id: OwnedRoomId,
|
||||
|
||||
/// The ID of the session.
|
||||
pub session_id: String,
|
||||
|
||||
/// The device curve25519 key of the session creator.
|
||||
#[serde(deserialize_with = "deserialize_curve_key", serialize_with = "serialize_curve_key")]
|
||||
pub sender_key: Curve25519PublicKey,
|
||||
|
||||
/// The device ID of the device sending the m.room_key.withheld message
|
||||
/// MSC3735.
|
||||
#[serde(default, skip_serializing_if = "JsOption::is_undefined")]
|
||||
pub from_device: JsOption<OwnedDeviceId>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub other: BTreeMap<String, Value>,
|
||||
}
|
||||
|
||||
impl MegolmV1AesSha2WithheldContent {
|
||||
/// Get the withheld code for this content
|
||||
pub fn withheld_code(&self) -> WithheldCode {
|
||||
match self {
|
||||
MegolmV1AesSha2WithheldContent::AnyContent((code, _)) => code.clone(),
|
||||
MegolmV1AesSha2WithheldContent::NoOlmContent(_) => WithheldCode::NoOlm,
|
||||
MegolmV1AesSha2WithheldContent::BlackListed(_) => WithheldCode::Blacklisted,
|
||||
MegolmV1AesSha2WithheldContent::Unverified(_) => WithheldCode::Unverified,
|
||||
MegolmV1AesSha2WithheldContent::Unauthorised(_) => WithheldCode::Unauthorised,
|
||||
MegolmV1AesSha2WithheldContent::Unavailable(_) => WithheldCode::Unavailable,
|
||||
MegolmV1AesSha2WithheldContent::NoOlm(_) => WithheldCode::NoOlm,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_code_and_content(code: WithheldCode, content: CommonWithheldCodeContent) -> Self {
|
||||
let content = content.into();
|
||||
|
||||
match code {
|
||||
WithheldCode::Blacklisted => Self::BlackListed(content),
|
||||
WithheldCode::Unverified => Self::Unverified(content),
|
||||
WithheldCode::Unauthorised => Self::Unauthorised(content),
|
||||
WithheldCode::Unavailable => Self::Unavailable(content),
|
||||
_ => unreachable!("This constructor requires one of the common withheld codes"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Devices that purposely do not send megolm keys to a device may instead send
|
||||
/// an m.room_key.withheld event as a to-device message to the device to
|
||||
/// indicate that it should not expect to receive keys for the message.
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
pub struct AnyWithheldContent {
|
||||
/// The room where the key is used.
|
||||
pub room_id: OwnedRoomId,
|
||||
/// The ID of the session.
|
||||
pub session_id: String,
|
||||
#[serde(deserialize_with = "deserialize_curve_key", serialize_with = "serialize_curve_key")]
|
||||
/// The device curve25519 key of the session creator.
|
||||
pub sender_key: Curve25519PublicKey,
|
||||
|
||||
/// A human-readable reason for why the key was not sent. The receiving
|
||||
/// client should only use this string if it does not understand the code
|
||||
#[serde(default, skip_serializing_if = "JsOption::is_undefined")]
|
||||
pub reason: JsOption<String>,
|
||||
|
||||
/// The device ID of the device sending the m.room_key.withheld message
|
||||
/// MSC3735.
|
||||
#[serde(default, skip_serializing_if = "JsOption::is_undefined")]
|
||||
pub from_device: JsOption<OwnedDeviceId>,
|
||||
|
||||
#[serde(flatten)]
|
||||
other: BTreeMap<String, Value>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
/// No olm content (no room_id nor session_id)
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
pub struct NoOlmWithheldContent {
|
||||
#[serde(deserialize_with = "deserialize_curve_key", serialize_with = "serialize_curve_key")]
|
||||
/// The device curve25519 key of the session creator.
|
||||
pub sender_key: Curve25519PublicKey,
|
||||
|
||||
/// A human-readable reason for why the key was not sent. The receiving
|
||||
/// client should only use this string if it does not understand the code
|
||||
#[serde(default, skip_serializing_if = "JsOption::is_undefined")]
|
||||
pub reason: JsOption<String>,
|
||||
|
||||
/// The device ID of the device sending the m.room_key.withheld message
|
||||
/// MSC3735.
|
||||
#[serde(default, skip_serializing_if = "JsOption::is_undefined")]
|
||||
@@ -288,7 +274,7 @@ pub struct NoOlmWithheldContent {
|
||||
other: BTreeMap<String, Value>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for AnyWithheldContent {
|
||||
impl std::fmt::Debug for CommonWithheldCodeContent {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("AnyWithheldContent")
|
||||
.field("room_id", &self.room_id)
|
||||
@@ -318,6 +304,8 @@ pub struct UnknownRoomKeyWithHeld {
|
||||
pub algorithm: EventEncryptionAlgorithm,
|
||||
/// The withheld code
|
||||
pub code: WithheldCode,
|
||||
|
||||
pub reason: JsOption<String>,
|
||||
/// The other data of the unknown room key.
|
||||
#[serde(flatten)]
|
||||
other: BTreeMap<String, Value>,
|
||||
@@ -327,39 +315,52 @@ impl TryFrom<WithheldHelper> for RoomKeyWithheldContent {
|
||||
type Error = serde_json::Error;
|
||||
|
||||
fn try_from(value: WithheldHelper) -> Result<Self, Self::Error> {
|
||||
Ok(match value.algorithm {
|
||||
EventEncryptionAlgorithm::MegolmV1AesSha2 => {
|
||||
let content = match value.code {
|
||||
WithheldCode::NoOlm => {
|
||||
let content: NoOlmWithheldContent = serde_json::from_value(value.other)?;
|
||||
MegolmV1AesSha2WithheldContent::NoOlmContent(content.into())
|
||||
}
|
||||
_ => {
|
||||
let content: AnyWithheldContent = serde_json::from_value(value.other)?;
|
||||
MegolmV1AesSha2WithheldContent::AnyContent((value.code, content.into()))
|
||||
}
|
||||
};
|
||||
Self::MegolmV1AesSha2(content)
|
||||
}
|
||||
#[cfg(feature = "experimental-algorithms")]
|
||||
EventEncryptionAlgorithm::MegolmV2AesSha2 => {
|
||||
let content = match value.code {
|
||||
WithheldCode::NoOlm => {
|
||||
let content: NoOlmWithheldContent = serde_json::from_value(value.other)?;
|
||||
MegolmV1AesSha2WithheldContent::NoOlmContent(content.into())
|
||||
}
|
||||
_ => {
|
||||
let content: AnyWithheldContent = serde_json::from_value(value.other)?;
|
||||
MegolmV1AesSha2WithheldContent::AnyContent((value.code, content.into()))
|
||||
}
|
||||
};
|
||||
Self::MegolmV2AesSha2(content)
|
||||
}
|
||||
_ => Self::Unknown(UnknownRoomKeyWithHeld {
|
||||
let unknown = |value: WithheldHelper| -> Result<RoomKeyWithheldContent, _> {
|
||||
Ok(Self::Unknown(UnknownRoomKeyWithHeld {
|
||||
algorithm: value.algorithm,
|
||||
code: value.code,
|
||||
reason: value.reason,
|
||||
other: serde_json::from_value(value.other)?,
|
||||
}),
|
||||
}))
|
||||
};
|
||||
|
||||
Ok(match value.algorithm {
|
||||
EventEncryptionAlgorithm::MegolmV1AesSha2 => match value.code {
|
||||
WithheldCode::NoOlm => {
|
||||
let content: NoOlmWithheldContent = serde_json::from_value(value.other)?;
|
||||
Self::MegolmV1AesSha2(MegolmV1AesSha2WithheldContent::NoOlm(content.into()))
|
||||
}
|
||||
WithheldCode::Blacklisted
|
||||
| WithheldCode::Unverified
|
||||
| WithheldCode::Unauthorised
|
||||
| WithheldCode::Unavailable => {
|
||||
let content: CommonWithheldCodeContent = serde_json::from_value(value.other)?;
|
||||
|
||||
Self::MegolmV1AesSha2(MegolmV1AesSha2WithheldContent::from_code_and_content(
|
||||
value.code, content,
|
||||
))
|
||||
}
|
||||
_ => unknown(value)?,
|
||||
},
|
||||
#[cfg(feature = "experimental-algorithms")]
|
||||
EventEncryptionAlgorithm::MegolmV2AesSha2 => match value.code {
|
||||
WithheldCode::NoOlm => {
|
||||
let content: NoOlmWithheldContent = serde_json::from_value(value.other)?;
|
||||
Self::MegolmV1AesSha2(MegolmV1AesSha2WithheldContent::NoOlm(content.into()))
|
||||
}
|
||||
WithheldCode::Blacklisted
|
||||
| WithheldCode::Unverified
|
||||
| WithheldCode::Unauthorised
|
||||
| WithheldCode::Unavailable => {
|
||||
let content: CommonWithheldCodeContent = serde_json::from_value(value.other)?;
|
||||
|
||||
Self::MegolmV1AesSha2(MegolmV1AesSha2WithheldContent::from_code_and_content(
|
||||
value.code, content,
|
||||
))
|
||||
}
|
||||
_ => unknown(value)?,
|
||||
},
|
||||
_ => unknown(value)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -369,35 +370,58 @@ impl Serialize for RoomKeyWithheldContent {
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let algorithm = self.algorithm();
|
||||
|
||||
let helper = match self {
|
||||
Self::MegolmV1AesSha2(r) => match r {
|
||||
MegolmV2AesSha2WithheldContent::AnyContent((code, content)) => WithheldHelper {
|
||||
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
code: code.clone(),
|
||||
other: serde_json::to_value(content).map_err(serde::ser::Error::custom)?,
|
||||
},
|
||||
MegolmV2AesSha2WithheldContent::NoOlmContent(content) => WithheldHelper {
|
||||
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
code: WithheldCode::NoOlm,
|
||||
other: serde_json::to_value(content).map_err(serde::ser::Error::custom)?,
|
||||
},
|
||||
},
|
||||
Self::MegolmV1AesSha2(r) => {
|
||||
let code = r.withheld_code();
|
||||
let reason = JsOption::Some(code.to_string());
|
||||
|
||||
match r {
|
||||
MegolmV1AesSha2WithheldContent::BlackListed(content)
|
||||
| MegolmV1AesSha2WithheldContent::Unverified(content)
|
||||
| MegolmV1AesSha2WithheldContent::Unauthorised(content)
|
||||
| MegolmV1AesSha2WithheldContent::Unavailable(content) => WithheldHelper {
|
||||
algorithm,
|
||||
code,
|
||||
reason,
|
||||
other: serde_json::to_value(content).map_err(serde::ser::Error::custom)?,
|
||||
},
|
||||
MegolmV1AesSha2WithheldContent::NoOlm(content) => WithheldHelper {
|
||||
algorithm,
|
||||
code,
|
||||
reason,
|
||||
other: serde_json::to_value(content).map_err(serde::ser::Error::custom)?,
|
||||
},
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "experimental-algorithms")]
|
||||
Self::MegolmV2AesSha2(r) => match r {
|
||||
MegolmV2AesSha2WithheldContent::AnyContent((code, content)) => WithheldHelper {
|
||||
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
code: code.clone(),
|
||||
other: serde_json::to_value(content).map_err(serde::ser::Error::custom)?,
|
||||
},
|
||||
MegolmV2AesSha2WithheldContent::NoOlmContent(content) => WithheldHelper {
|
||||
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
code: WithheldCode::NoOlm,
|
||||
other: serde_json::to_value(content).map_err(serde::ser::Error::custom)?,
|
||||
},
|
||||
},
|
||||
Self::MegolmV2AesSha2(r) => {
|
||||
let code = r.withheld_code();
|
||||
let reason = JsOption::Some(code.to_string());
|
||||
|
||||
match r {
|
||||
MegolmV1AesSha2WithheldContent::BlackListed(content)
|
||||
| MegolmV1AesSha2WithheldContent::Unverified(content)
|
||||
| MegolmV1AesSha2WithheldContent::Unauthorised(content)
|
||||
| MegolmV1AesSha2WithheldContent::Unavailable(content) => WithheldHelper {
|
||||
algorithm,
|
||||
code,
|
||||
reason,
|
||||
other: serde_json::to_value(content).map_err(serde::ser::Error::custom)?,
|
||||
},
|
||||
MegolmV1AesSha2WithheldContent::NoOlm(content) => WithheldHelper {
|
||||
algorithm,
|
||||
code,
|
||||
reason,
|
||||
other: serde_json::to_value(content).map_err(serde::ser::Error::custom)?,
|
||||
},
|
||||
}
|
||||
}
|
||||
Self::Unknown(r) => WithheldHelper {
|
||||
algorithm: r.algorithm.clone(),
|
||||
code: r.code.clone(),
|
||||
algorithm: r.algorithm.to_owned(),
|
||||
code: r.code.to_owned(),
|
||||
reason: r.reason.to_owned(),
|
||||
other: serde_json::to_value(r.other.clone()).map_err(serde::ser::Error::custom)?,
|
||||
},
|
||||
};
|
||||
@@ -498,32 +522,10 @@ pub(super) mod test {
|
||||
for code in codes {
|
||||
let json = json(&code);
|
||||
let event: RoomKeyWithheldEvent = serde_json::from_value(json.clone())?;
|
||||
assert_matches!(
|
||||
event.content,
|
||||
RoomKeyWithheldContent::MegolmV1AesSha2(
|
||||
MegolmV1AesSha2WithheldContent::AnyContent(_)
|
||||
)
|
||||
);
|
||||
|
||||
if let RoomKeyWithheldContent::MegolmV1AesSha2(content) = &event.content {
|
||||
assert_eq!(content.withheld_code().to_owned(), code)
|
||||
} else {
|
||||
panic!()
|
||||
}
|
||||
assert_matches!(&event.content, RoomKeyWithheldContent::MegolmV1AesSha2(content) if code == content.withheld_code());
|
||||
|
||||
if let RoomKeyWithheldContent::MegolmV1AesSha2(
|
||||
MegolmV1AesSha2WithheldContent::AnyContent((_, content)),
|
||||
) = &event.content
|
||||
{
|
||||
assert_eq!(content.reason, ruma::JsOption::Some(code.to_string()))
|
||||
} else {
|
||||
panic!()
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
event.content.algorithm().to_owned(),
|
||||
EventEncryptionAlgorithm::MegolmV1AesSha2
|
||||
);
|
||||
assert_eq!(event.content.algorithm(), EventEncryptionAlgorithm::MegolmV1AesSha2);
|
||||
let serialized = serde_json::to_value(event)?;
|
||||
assert_eq!(json, serialized);
|
||||
}
|
||||
@@ -536,9 +538,7 @@ pub(super) mod test {
|
||||
let event: RoomKeyWithheldEvent = serde_json::from_value(json.clone())?;
|
||||
assert_matches!(
|
||||
event.content,
|
||||
RoomKeyWithheldContent::MegolmV1AesSha2(MegolmV1AesSha2WithheldContent::NoOlmContent(
|
||||
_
|
||||
))
|
||||
RoomKeyWithheldContent::MegolmV1AesSha2(MegolmV1AesSha2WithheldContent::NoOlm(_))
|
||||
);
|
||||
let serialized = serde_json::to_value(event)?;
|
||||
assert_eq!(json, serialized);
|
||||
@@ -550,19 +550,14 @@ pub(super) mod test {
|
||||
fn deserialization_unknown_code() -> Result<(), serde_json::Error> {
|
||||
let json = unknown_code_json();
|
||||
let event: RoomKeyWithheldEvent = serde_json::from_value(json.clone())?;
|
||||
assert_matches!(event.content, RoomKeyWithheldContent::Unknown(_));
|
||||
|
||||
assert_matches!(
|
||||
event.content,
|
||||
RoomKeyWithheldContent::MegolmV1AesSha2(MegolmV1AesSha2WithheldContent::AnyContent((
|
||||
_,
|
||||
_
|
||||
)))
|
||||
&event.content,
|
||||
RoomKeyWithheldContent::Unknown(content)
|
||||
if content.code.as_str() == "org.mscXXX.new_code"
|
||||
);
|
||||
|
||||
if let RoomKeyWithheldContent::MegolmV1AesSha2(content) = &event.content {
|
||||
assert_matches!(content.withheld_code(), WithheldCode::_Custom(_));
|
||||
} else {
|
||||
panic!()
|
||||
}
|
||||
let serialized = serde_json::to_value(event)?;
|
||||
assert_eq!(json, serialized);
|
||||
|
||||
@@ -597,13 +592,13 @@ pub(super) mod test {
|
||||
Curve25519PublicKey::from_base64("9n7mdWKOjr9c4NTlG6zV8dbFtNK79q9vZADoh7nMUwA")
|
||||
.unwrap();
|
||||
|
||||
let content = RoomKeyWithheldContent::create(
|
||||
let content = RoomKeyWithheldContent::new(
|
||||
EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
WithheldCode::Unverified,
|
||||
room_id.to_owned(),
|
||||
"0ZcULv8j1nqVWx6orFjD6OW9JQHydDPXfaanA+uRyfs".to_owned(),
|
||||
sender_key,
|
||||
Some(device_id.to_owned()),
|
||||
device_id.to_owned(),
|
||||
);
|
||||
let content: Raw<RoomKeyWithheldContent> =
|
||||
Raw::new(&content).expect("We can always serialize a withheld content info").cast();
|
||||
@@ -617,15 +612,15 @@ pub(super) mod test {
|
||||
|
||||
let expected: Value = json!({
|
||||
"@alice:example.org":{
|
||||
"DEV001":{
|
||||
"algorithm":"m.megolm.v1.aes-sha2",
|
||||
"code":"m.unverified",
|
||||
"from_device":"DEV001",
|
||||
"reason":"The sender has disabled encrypting to unverified devices.",
|
||||
"room_id":"!DwLygpkclUAfQNnfva:localhost:8481",
|
||||
"sender_key":"9n7mdWKOjr9c4NTlG6zV8dbFtNK79q9vZADoh7nMUwA",
|
||||
"session_id":"0ZcULv8j1nqVWx6orFjD6OW9JQHydDPXfaanA+uRyfs"
|
||||
}
|
||||
"DEV001":{
|
||||
"algorithm":"m.megolm.v1.aes-sha2",
|
||||
"code":"m.unverified",
|
||||
"from_device":"DEV001",
|
||||
"reason":"The sender has disabled encrypting to unverified devices.",
|
||||
"room_id":"!DwLygpkclUAfQNnfva:localhost:8481",
|
||||
"sender_key":"9n7mdWKOjr9c4NTlG6zV8dbFtNK79q9vZADoh7nMUwA",
|
||||
"session_id":"0ZcULv8j1nqVWx6orFjD6OW9JQHydDPXfaanA+uRyfs"
|
||||
}
|
||||
}
|
||||
});
|
||||
assert_eq!(serialized, expected);
|
||||
@@ -639,49 +634,34 @@ pub(super) mod test {
|
||||
Curve25519PublicKey::from_base64("9n7mdWKOjr9c4NTlG6zV8dbFtNK79q9vZADoh7nMUwA")
|
||||
.unwrap();
|
||||
|
||||
let content = RoomKeyWithheldContent::create(
|
||||
let content = RoomKeyWithheldContent::new(
|
||||
EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
WithheldCode::NoOlm,
|
||||
room_id.to_owned(),
|
||||
"0ZcULv8j1nqVWx6orFjD6OW9JQHydDPXfaanA+uRyfs".to_owned(),
|
||||
sender_key,
|
||||
Some(device_id.to_owned()),
|
||||
device_id.to_owned(),
|
||||
);
|
||||
|
||||
assert_matches!(content, RoomKeyWithheldContent::MegolmV1AesSha2(_));
|
||||
assert_matches!(
|
||||
content,
|
||||
RoomKeyWithheldContent::MegolmV1AesSha2(MegolmV1AesSha2WithheldContent::NoOlm(content))
|
||||
if content.sender_key == sender_key
|
||||
);
|
||||
|
||||
match content {
|
||||
RoomKeyWithheldContent::MegolmV1AesSha2(content) => match content {
|
||||
MegolmV1AesSha2WithheldContent::AnyContent(_) => panic!(),
|
||||
MegolmV1AesSha2WithheldContent::NoOlmContent(no_olm_content) => {
|
||||
assert_eq!(sender_key, no_olm_content.sender_key);
|
||||
}
|
||||
},
|
||||
_ => panic!(),
|
||||
}
|
||||
|
||||
let content = RoomKeyWithheldContent::create(
|
||||
let content = RoomKeyWithheldContent::new(
|
||||
EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
WithheldCode::Unverified,
|
||||
room_id.to_owned(),
|
||||
"0ZcULv8j1nqVWx6orFjD6OW9JQHydDPXfaanA+uRyfs".to_owned(),
|
||||
sender_key,
|
||||
Some(device_id.to_owned()),
|
||||
device_id.to_owned(),
|
||||
);
|
||||
|
||||
assert_matches!(content, RoomKeyWithheldContent::MegolmV1AesSha2(_));
|
||||
|
||||
match content {
|
||||
RoomKeyWithheldContent::MegolmV1AesSha2(content) => match content {
|
||||
MegolmV1AesSha2WithheldContent::NoOlmContent(_) => panic!(),
|
||||
MegolmV1AesSha2WithheldContent::AnyContent((code, content)) => {
|
||||
assert_eq!(sender_key, content.sender_key);
|
||||
assert_eq!(code, WithheldCode::Unverified);
|
||||
assert_eq!("0ZcULv8j1nqVWx6orFjD6OW9JQHydDPXfaanA+uRyfs", content.session_id);
|
||||
assert_eq!(room_id, content.room_id);
|
||||
}
|
||||
},
|
||||
_ => panic!(),
|
||||
}
|
||||
assert_matches!(
|
||||
content,
|
||||
RoomKeyWithheldContent::MegolmV1AesSha2(MegolmV1AesSha2WithheldContent::Unverified(content))
|
||||
if content.session_id == "0ZcULv8j1nqVWx6orFjD6OW9JQHydDPXfaanA+uRyfs"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -570,8 +570,9 @@ impl_crypto_store! {
|
||||
let withhelds = tx.object_store(keys::DIRECT_WITHHELD_INFO)?;
|
||||
|
||||
for info in withheld_session_info {
|
||||
let room_id = info.room_id.to_owned();
|
||||
let session_id = info.session_id.to_owned();
|
||||
let room_id = info.room_id();
|
||||
let session_id = info.session_id();
|
||||
|
||||
let key = self.encode_key(keys::DIRECT_WITHHELD_INFO, (session_id, room_id));
|
||||
withhelds.put_key_val(&key, &self.serialize_value(&info)?)?;
|
||||
}
|
||||
|
||||
@@ -671,12 +671,11 @@ impl SledCryptoStore {
|
||||
}
|
||||
|
||||
for info in &changes.withheld_session_info {
|
||||
let session_id = info.session_id.to_owned();
|
||||
let room_id = info.room_id.to_owned();
|
||||
let key = self.encode_key(
|
||||
DIRECT_WITHHELD_INFO_TABLE,
|
||||
(session_id.as_str(), room_id.as_str()),
|
||||
);
|
||||
let session_id = info.session_id();
|
||||
let room_id = info.room_id();
|
||||
|
||||
let key =
|
||||
self.encode_key(DIRECT_WITHHELD_INFO_TABLE, (session_id, room_id));
|
||||
direct_withheld_info.insert(
|
||||
key,
|
||||
self.serialize_value(info)
|
||||
|
||||
Reference in New Issue
Block a user