matrix_sdk_crypto_ffi/
responses.rs

1#![allow(missing_docs)]
2
3use std::collections::HashMap;
4
5use http::Response;
6use matrix_sdk_crypto::{
7    types::requests::{
8        AnyIncomingResponse, KeysBackupRequest, OutgoingRequest,
9        OutgoingVerificationRequest as SdkVerificationRequest, RoomMessageRequest, ToDeviceRequest,
10        UploadSigningKeysRequest as RustUploadSigningKeysRequest,
11    },
12    CrossSigningBootstrapRequests,
13};
14use ruma::{
15    api::client::{
16        backup::add_backup_keys::v3::Response as KeysBackupResponse,
17        keys::{
18            claim_keys::v3::{Request as KeysClaimRequest, Response as KeysClaimResponse},
19            get_keys::v3::Response as KeysQueryResponse,
20            upload_keys::v3::Response as KeysUploadResponse,
21            upload_signatures::v3::{
22                Request as RustSignatureUploadRequest, Response as SignatureUploadResponse,
23            },
24        },
25        message::send_message_event::v3::Response as RoomMessageResponse,
26        sync::sync_events::DeviceLists as RumaDeviceLists,
27        to_device::send_event_to_device::v3::Response as ToDeviceResponse,
28    },
29    assign,
30    events::EventContent,
31    OwnedTransactionId, UserId,
32};
33use serde_json::json;
34
35#[derive(uniffi::Record)]
36pub struct SignatureUploadRequest {
37    pub body: String,
38}
39
40impl From<RustSignatureUploadRequest> for SignatureUploadRequest {
41    fn from(r: RustSignatureUploadRequest) -> Self {
42        Self {
43            body: serde_json::to_string(&r.signed_keys)
44                .expect("Can't serialize signature upload request"),
45        }
46    }
47}
48
49#[derive(uniffi::Record)]
50pub struct UploadSigningKeysRequest {
51    pub master_key: String,
52    pub self_signing_key: String,
53    pub user_signing_key: String,
54}
55
56impl From<RustUploadSigningKeysRequest> for UploadSigningKeysRequest {
57    fn from(r: RustUploadSigningKeysRequest) -> Self {
58        Self {
59            master_key: serde_json::to_string(
60                &r.master_key.expect("Request didn't contain a master key"),
61            )
62            .expect("Can't serialize cross signing master key"),
63            self_signing_key: serde_json::to_string(
64                &r.self_signing_key.expect("Request didn't contain a self-signing key"),
65            )
66            .expect("Can't serialize cross signing self-signing key"),
67            user_signing_key: serde_json::to_string(
68                &r.user_signing_key.expect("Request didn't contain a user-signing key"),
69            )
70            .expect("Can't serialize cross signing user-signing key"),
71        }
72    }
73}
74
75#[derive(uniffi::Record)]
76pub struct BootstrapCrossSigningResult {
77    /// Optional request to upload some device keys alongside.
78    ///
79    /// Must be sent first if present, and marked with `mark_request_as_sent`.
80    pub upload_keys_request: Option<Request>,
81    /// Request to upload the signing keys. Must be sent second.
82    pub upload_signing_keys_request: UploadSigningKeysRequest,
83    /// Request to upload the keys signatures, including for the signing keys
84    /// and optionally for the device keys. Must be sent last.
85    pub upload_signature_request: SignatureUploadRequest,
86}
87
88impl From<CrossSigningBootstrapRequests> for BootstrapCrossSigningResult {
89    fn from(requests: CrossSigningBootstrapRequests) -> Self {
90        Self {
91            upload_signing_keys_request: requests.upload_signing_keys_req.into(),
92            upload_keys_request: requests.upload_keys_req.map(Request::from),
93            upload_signature_request: requests.upload_signatures_req.into(),
94        }
95    }
96}
97
98#[derive(uniffi::Enum)]
99pub enum OutgoingVerificationRequest {
100    ToDevice { request_id: String, event_type: String, body: String },
101    InRoom { request_id: String, room_id: String, event_type: String, content: String },
102}
103
104impl From<SdkVerificationRequest> for OutgoingVerificationRequest {
105    fn from(r: SdkVerificationRequest) -> Self {
106        match r {
107            SdkVerificationRequest::ToDevice(r) => r.into(),
108            SdkVerificationRequest::InRoom(r) => Self::InRoom {
109                request_id: r.txn_id.to_string(),
110                room_id: r.room_id.to_string(),
111                content: serde_json::to_string(&r.content)
112                    .expect("Can't serialize message content"),
113                event_type: r.content.event_type().to_string(),
114            },
115        }
116    }
117}
118
119impl From<ToDeviceRequest> for OutgoingVerificationRequest {
120    fn from(r: ToDeviceRequest) -> Self {
121        Self::ToDevice {
122            request_id: r.txn_id.to_string(),
123            event_type: r.event_type.to_string(),
124            body: serde_json::to_string(&r.messages).expect("Can't serialize to-device body"),
125        }
126    }
127}
128
129#[derive(Debug, uniffi::Enum)]
130pub enum Request {
131    ToDevice { request_id: String, event_type: String, body: String },
132    KeysUpload { request_id: String, body: String },
133    KeysQuery { request_id: String, users: Vec<String> },
134    KeysClaim { request_id: String, one_time_keys: HashMap<String, HashMap<String, String>> },
135    KeysBackup { request_id: String, version: String, rooms: String },
136    RoomMessage { request_id: String, room_id: String, event_type: String, content: String },
137    SignatureUpload { request_id: String, body: String },
138}
139
140impl From<OutgoingRequest> for Request {
141    fn from(r: OutgoingRequest) -> Self {
142        use matrix_sdk_crypto::types::requests::AnyOutgoingRequest::*;
143
144        match r.request() {
145            KeysUpload(u) => {
146                let body = json!({
147                    "device_keys": u.device_keys,
148                    "one_time_keys": u.one_time_keys,
149                    "fallback_keys": u.fallback_keys,
150                });
151
152                Request::KeysUpload {
153                    request_id: r.request_id().to_string(),
154                    body: serde_json::to_string(&body)
155                        .expect("Can't serialize `/keys/upload` request"),
156                }
157            }
158            KeysQuery(k) => {
159                let users: Vec<String> = k.device_keys.keys().map(|u| u.to_string()).collect();
160                Request::KeysQuery { request_id: r.request_id().to_string(), users }
161            }
162            ToDeviceRequest(t) => Request::from(t),
163            SignatureUpload(t) => Request::SignatureUpload {
164                request_id: r.request_id().to_string(),
165                body: serde_json::to_string(&t.signed_keys)
166                    .expect("Can't serialize signature upload request"),
167            },
168            RoomMessage(r) => Request::from(r),
169            KeysClaim(c) => (r.request_id().to_owned(), c.clone()).into(),
170        }
171    }
172}
173
174impl From<ToDeviceRequest> for Request {
175    fn from(r: ToDeviceRequest) -> Self {
176        Request::ToDevice {
177            request_id: r.txn_id.to_string(),
178            event_type: r.event_type.to_string(),
179            body: serde_json::to_string(&r.messages).expect("Can't serialize to-device body"),
180        }
181    }
182}
183
184impl From<(OwnedTransactionId, KeysClaimRequest)> for Request {
185    fn from(request_tuple: (OwnedTransactionId, KeysClaimRequest)) -> Self {
186        let (request_id, request) = request_tuple;
187
188        Request::KeysClaim {
189            request_id: request_id.to_string(),
190            one_time_keys: request
191                .one_time_keys
192                .into_iter()
193                .map(|(u, d)| {
194                    (
195                        u.to_string(),
196                        d.into_iter().map(|(k, v)| (k.to_string(), v.to_string())).collect(),
197                    )
198                })
199                .collect(),
200        }
201    }
202}
203
204impl From<(OwnedTransactionId, KeysBackupRequest)> for Request {
205    fn from(request_tuple: (OwnedTransactionId, KeysBackupRequest)) -> Self {
206        let (request_id, request) = request_tuple;
207
208        Request::KeysBackup {
209            request_id: request_id.to_string(),
210            version: request.version.to_owned(),
211            rooms: serde_json::to_string(&request.rooms)
212                .expect("Can't serialize keys backup request"),
213        }
214    }
215}
216
217impl From<&ToDeviceRequest> for Request {
218    fn from(r: &ToDeviceRequest) -> Self {
219        Request::ToDevice {
220            request_id: r.txn_id.to_string(),
221            event_type: r.event_type.to_string(),
222            body: serde_json::to_string(&r.messages).expect("Can't serialize to-device body"),
223        }
224    }
225}
226
227impl From<&RoomMessageRequest> for Request {
228    fn from(r: &RoomMessageRequest) -> Self {
229        Self::RoomMessage {
230            request_id: r.txn_id.to_string(),
231            room_id: r.room_id.to_string(),
232            event_type: r.content.event_type().to_string(),
233            content: serde_json::to_string(&r.content).expect("Can't serialize message content"),
234        }
235    }
236}
237
238pub(crate) fn response_from_string(body: &str) -> Response<Vec<u8>> {
239    Response::builder()
240        .status(200)
241        .body(body.as_bytes().to_vec())
242        .expect("Can't create HTTP response")
243}
244
245#[derive(uniffi::Enum)]
246pub enum RequestType {
247    KeysQuery,
248    KeysClaim,
249    KeysUpload,
250    ToDevice,
251    SignatureUpload,
252    KeysBackup,
253    RoomMessage,
254}
255
256#[derive(uniffi::Record)]
257pub struct DeviceLists {
258    pub changed: Vec<String>,
259    pub left: Vec<String>,
260}
261
262impl From<DeviceLists> for RumaDeviceLists {
263    fn from(d: DeviceLists) -> Self {
264        assign!(RumaDeviceLists::new(), {
265            changed: d
266                .changed
267                .into_iter()
268                .filter_map(|u| UserId::parse(u).ok())
269                .collect(),
270            left: d
271                .left
272                .into_iter()
273                .filter_map(|u| UserId::parse(u).ok())
274                .collect(),
275        })
276    }
277}
278
279#[derive(uniffi::Record)]
280pub struct KeysImportResult {
281    /// The number of room keys that were imported.
282    pub imported: i64,
283    /// The total number of room keys that were found in the export.
284    pub total: i64,
285    /// The map of keys that were imported.
286    ///
287    /// It's a map from room id to a map of the sender key to a list of session
288    /// ids.
289    pub keys: HashMap<String, HashMap<String, Vec<String>>>,
290}
291
292pub(crate) enum OwnedResponse {
293    KeysClaim(KeysClaimResponse),
294    KeysUpload(KeysUploadResponse),
295    KeysQuery(KeysQueryResponse),
296    ToDevice(ToDeviceResponse),
297    SignatureUpload(SignatureUploadResponse),
298    KeysBackup(KeysBackupResponse),
299    RoomMessage(RoomMessageResponse),
300}
301
302impl From<KeysClaimResponse> for OwnedResponse {
303    fn from(response: KeysClaimResponse) -> Self {
304        OwnedResponse::KeysClaim(response)
305    }
306}
307
308impl From<KeysQueryResponse> for OwnedResponse {
309    fn from(response: KeysQueryResponse) -> Self {
310        OwnedResponse::KeysQuery(response)
311    }
312}
313
314impl From<KeysUploadResponse> for OwnedResponse {
315    fn from(response: KeysUploadResponse) -> Self {
316        OwnedResponse::KeysUpload(response)
317    }
318}
319
320impl From<ToDeviceResponse> for OwnedResponse {
321    fn from(response: ToDeviceResponse) -> Self {
322        OwnedResponse::ToDevice(response)
323    }
324}
325
326impl From<SignatureUploadResponse> for OwnedResponse {
327    fn from(response: SignatureUploadResponse) -> Self {
328        Self::SignatureUpload(response)
329    }
330}
331
332impl From<KeysBackupResponse> for OwnedResponse {
333    fn from(r: KeysBackupResponse) -> Self {
334        Self::KeysBackup(r)
335    }
336}
337
338impl From<RoomMessageResponse> for OwnedResponse {
339    fn from(response: RoomMessageResponse) -> Self {
340        OwnedResponse::RoomMessage(response)
341    }
342}
343
344impl<'a> From<&'a OwnedResponse> for AnyIncomingResponse<'a> {
345    fn from(r: &'a OwnedResponse) -> Self {
346        match r {
347            OwnedResponse::KeysClaim(r) => AnyIncomingResponse::KeysClaim(r),
348            OwnedResponse::KeysQuery(r) => AnyIncomingResponse::KeysQuery(r),
349            OwnedResponse::KeysUpload(r) => AnyIncomingResponse::KeysUpload(r),
350            OwnedResponse::ToDevice(r) => AnyIncomingResponse::ToDevice(r),
351            OwnedResponse::SignatureUpload(r) => AnyIncomingResponse::SignatureUpload(r),
352            OwnedResponse::KeysBackup(r) => AnyIncomingResponse::KeysBackup(r),
353            OwnedResponse::RoomMessage(r) => AnyIncomingResponse::RoomMessage(r),
354        }
355    }
356}