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 )
50 .await
51}
52
53pub async fn from_sync_v2(
59 response: &v3::Response,
60 olm_machine: Option<&OlmMachine>,
61 decryption_settings: &DecryptionSettings,
62) -> Result<Output> {
63 process(
64 olm_machine,
65 response.to_device.events.clone(),
66 &response.device_lists,
67 &response.device_one_time_keys_count,
68 response.device_unused_fallback_key_types.as_deref(),
69 Some(response.next_batch.clone()),
70 decryption_settings,
71 )
72 .await
73}
74
75async fn process(
80 olm_machine: Option<&OlmMachine>,
81 to_device_events: Vec<Raw<AnyToDeviceEvent>>,
82 device_lists: &DeviceLists,
83 one_time_keys_counts: &BTreeMap<OneTimeKeyAlgorithm, UInt>,
84 unused_fallback_keys: Option<&[OneTimeKeyAlgorithm]>,
85 next_batch_token: Option<String>,
86 decryption_settings: &DecryptionSettings,
87) -> Result<Output> {
88 let encryption_sync_changes = EncryptionSyncChanges {
89 to_device_events,
90 changed_devices: device_lists,
91 one_time_keys_counts,
92 unused_fallback_keys,
93 next_batch_token,
94 };
95
96 Ok(if let Some(olm_machine) = olm_machine {
97 let (events, _room_key_updates) =
102 olm_machine.receive_sync_changes(encryption_sync_changes, decryption_settings).await?;
103
104 Output { processed_to_device_events: events }
105 } else {
106 Output {
111 processed_to_device_events: encryption_sync_changes
112 .to_device_events
113 .into_iter()
114 .map(|raw| {
115 if let Ok(Some(event_type)) = raw.get_field::<String>("type") {
116 if event_type == "m.room.encrypted" {
117 ProcessedToDeviceEvent::UnableToDecrypt {
118 encrypted_event: raw,
119 utd_info: ToDeviceUnableToDecryptInfo {
120 reason: ToDeviceUnableToDecryptReason::NoOlmMachine,
121 },
122 }
123 } else {
124 ProcessedToDeviceEvent::PlainText(raw)
125 }
126 } else {
127 ProcessedToDeviceEvent::Invalid(raw)
129 }
130 })
131 .collect(),
132 }
133 })
134}
135
136pub struct Output {
137 pub processed_to_device_events: Vec<ProcessedToDeviceEvent>,
138}