matrix_sdk_base/response_processors/e2ee/
to_device.rs1use std::collections::BTreeMap;
16
17use matrix_sdk_common::deserialized_responses::{
18 ProcessedToDeviceEvent, ToDeviceUnableToDecryptInfo, ToDeviceUnableToDecryptReason,
19};
20use matrix_sdk_crypto::{
21 DecryptionSettings, EncryptionSyncChanges, OlmMachine, store::types::RoomKeyInfo,
22};
23use ruma::{
24 OneTimeKeyAlgorithm, UInt,
25 api::client::sync::sync_events::{DeviceLists, v3, v5},
26 events::AnyToDeviceEvent,
27 serde::Raw,
28};
29
30use crate::Result;
31
32pub async fn from_msc4186(
38 to_device: Option<&v5::response::ToDevice>,
39 e2ee: &v5::response::E2EE,
40 olm_machine: Option<&OlmMachine>,
41 decryption_settings: &DecryptionSettings,
42) -> Result<Output> {
43 process(
44 olm_machine,
45 to_device.as_ref().map(|to_device| to_device.events.clone()).unwrap_or_default(),
46 &e2ee.device_lists,
47 &e2ee.device_one_time_keys_count,
48 e2ee.device_unused_fallback_key_types.as_deref(),
49 to_device.as_ref().map(|to_device| to_device.next_batch.clone()),
50 decryption_settings,
51 )
52 .await
53}
54
55pub async fn from_sync_v2(
61 response: &v3::Response,
62 olm_machine: Option<&OlmMachine>,
63 decryption_settings: &DecryptionSettings,
64) -> Result<Output> {
65 process(
66 olm_machine,
67 response.to_device.events.clone(),
68 &response.device_lists,
69 &response.device_one_time_keys_count,
70 response.device_unused_fallback_key_types.as_deref(),
71 Some(response.next_batch.clone()),
72 decryption_settings,
73 )
74 .await
75}
76
77async fn process(
82 olm_machine: Option<&OlmMachine>,
83 to_device_events: Vec<Raw<AnyToDeviceEvent>>,
84 device_lists: &DeviceLists,
85 one_time_keys_counts: &BTreeMap<OneTimeKeyAlgorithm, UInt>,
86 unused_fallback_keys: Option<&[OneTimeKeyAlgorithm]>,
87 next_batch_token: Option<String>,
88 decryption_settings: &DecryptionSettings,
89) -> Result<Output> {
90 let encryption_sync_changes = EncryptionSyncChanges {
91 to_device_events,
92 changed_devices: device_lists,
93 one_time_keys_counts,
94 unused_fallback_keys,
95 next_batch_token,
96 };
97
98 Ok(if let Some(olm_machine) = olm_machine {
99 let (events, room_key_updates) =
104 olm_machine.receive_sync_changes(encryption_sync_changes, decryption_settings).await?;
105
106 Output { processed_to_device_events: events, room_key_updates: Some(room_key_updates) }
107 } else {
108 Output {
113 processed_to_device_events: encryption_sync_changes
114 .to_device_events
115 .into_iter()
116 .map(|raw| {
117 if let Ok(Some(event_type)) = raw.get_field::<String>("type") {
118 if event_type == "m.room.encrypted" {
119 ProcessedToDeviceEvent::UnableToDecrypt {
120 encrypted_event: raw,
121 utd_info: ToDeviceUnableToDecryptInfo {
122 reason: ToDeviceUnableToDecryptReason::NoOlmMachine,
123 },
124 }
125 } else {
126 ProcessedToDeviceEvent::PlainText(raw)
127 }
128 } else {
129 ProcessedToDeviceEvent::Invalid(raw)
131 }
132 })
133 .collect(),
134 room_key_updates: None,
135 }
136 })
137}
138
139pub struct Output {
140 pub processed_to_device_events: Vec<ProcessedToDeviceEvent>,
141 pub room_key_updates: Option<Vec<RoomKeyInfo>>,
142}