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::{DecryptionSettings, EncryptionSyncChanges, OlmMachine};
21use ruma::{
22 OneTimeKeyAlgorithm, UInt,
23 api::client::sync::sync_events::{DeviceLists, v3, v5},
24 events::AnyToDeviceEvent,
25 serde::Raw,
26};
27
28use crate::Result;
29
30pub async fn from_msc4186(
36 to_device: Option<&v5::response::ToDevice>,
37 e2ee: &v5::response::E2EE,
38 olm_machine: Option<&OlmMachine>,
39 decryption_settings: &DecryptionSettings,
40) -> Result<Output> {
41 process(
42 olm_machine,
43 to_device.as_ref().map(|to_device| to_device.events.clone()).unwrap_or_default(),
44 &e2ee.device_lists,
45 &e2ee.device_one_time_keys_count,
46 e2ee.device_unused_fallback_key_types.as_deref(),
47 to_device.as_ref().map(|to_device| to_device.next_batch.clone()),
48 decryption_settings,
49 true,
50 )
51 .await
52}
53
54pub async fn from_sync_v2(
60 response: &v3::Response,
61 olm_machine: Option<&OlmMachine>,
62 decryption_settings: &DecryptionSettings,
63) -> Result<Output> {
64 process(
65 olm_machine,
66 response.to_device.events.clone(),
67 &response.device_lists,
68 &response.device_one_time_keys_count,
69 response.device_unused_fallback_key_types.as_deref(),
70 Some(response.next_batch.clone()),
71 decryption_settings,
72 false,
73 )
74 .await
75}
76
77#[allow(clippy::too_many_arguments)]
82async fn process(
83 olm_machine: Option<&OlmMachine>,
84 to_device_events: Vec<Raw<AnyToDeviceEvent>>,
85 device_lists: &DeviceLists,
86 one_time_keys_counts: &BTreeMap<OneTimeKeyAlgorithm, UInt>,
87 unused_fallback_keys: Option<&[OneTimeKeyAlgorithm]>,
88 next_batch_token: Option<String>,
89 decryption_settings: &DecryptionSettings,
90 msc_4186: bool,
91) -> Result<Output> {
92 let encryption_sync_changes = EncryptionSyncChanges {
93 to_device_events,
94 changed_devices: device_lists,
95 one_time_keys_counts,
96 unused_fallback_keys,
97 next_batch_token,
98 };
99
100 Ok(if let Some(olm_machine) = olm_machine {
101 let (events, _room_key_updates) = if msc_4186 {
106 olm_machine
107 .receive_sync_changes_msc4186(encryption_sync_changes, decryption_settings)
108 .await?
109 } else {
110 olm_machine.receive_sync_changes(encryption_sync_changes, decryption_settings).await?
111 };
112
113 Output { processed_to_device_events: events }
114 } else {
115 Output {
120 processed_to_device_events: encryption_sync_changes
121 .to_device_events
122 .into_iter()
123 .map(|raw| {
124 if let Ok(Some(event_type)) = raw.get_field::<String>("type") {
125 if event_type == "m.room.encrypted" {
126 ProcessedToDeviceEvent::UnableToDecrypt {
127 encrypted_event: raw,
128 utd_info: ToDeviceUnableToDecryptInfo {
129 reason: ToDeviceUnableToDecryptReason::NoOlmMachine,
130 },
131 }
132 } else {
133 ProcessedToDeviceEvent::PlainText(raw)
134 }
135 } else {
136 ProcessedToDeviceEvent::Invalid(raw)
138 }
139 })
140 .collect(),
141 }
142 })
143}
144
145pub struct Output {
146 pub processed_to_device_events: Vec<ProcessedToDeviceEvent>,
147}