Skip to main content

matrix_sdk_crypto_ffi/
responses.rs

1#![allow(missing_docs)]
2
3use std::collections::HashMap;
4
5use http::Response;
6use matrix_sdk_crypto::{
7    CrossSigningBootstrapRequests,
8    types::requests::{
9        AnyIncomingResponse, KeysBackupRequest, OutgoingRequest,
10        OutgoingVerificationRequest as SdkVerificationRequest, RoomMessageRequest, ToDeviceRequest,
11        UploadSigningKeysRequest as RustUploadSigningKeysRequest,
12    },
13};
14use ruma::{
15    OwnedTransactionId, UserId,
16    api::client::{
17        backup::add_backup_keys::v3::Response as KeysBackupResponse,
18        keys::{
19            claim_keys::v3::{Request as KeysClaimRequest, Response as KeysClaimResponse},
20            get_keys::v3::Response as KeysQueryResponse,
21            upload_keys::v3::Response as KeysUploadResponse,
22            upload_signatures::v3::{
23                Request as RustSignatureUploadRequest, Response as SignatureUploadResponse,
24            },
25        },
26        message::send_message_event::v3::Response as RoomMessageResponse,
27        sync::sync_events::DeviceLists as RumaDeviceLists,
28        to_device::send_event_to_device::v3::Response as ToDeviceResponse,
29    },
30    assign,
31    events::MessageLikeEventContent,
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<&Box<RoomMessageRequest>> for Request {
228    fn from(r: &Box<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<&[u8]> {
239    Response::builder().status(200).body(body.as_bytes()).expect("Can't create HTTP response")
240}
241
242#[derive(uniffi::Enum)]
243pub enum RequestType {
244    KeysQuery,
245    KeysClaim,
246    KeysUpload,
247    ToDevice,
248    SignatureUpload,
249    KeysBackup,
250    RoomMessage,
251}
252
253#[derive(uniffi::Record)]
254pub struct DeviceLists {
255    pub changed: Vec<String>,
256    pub left: Vec<String>,
257}
258
259impl From<DeviceLists> for RumaDeviceLists {
260    fn from(d: DeviceLists) -> Self {
261        assign!(RumaDeviceLists::new(), {
262            changed: d
263                .changed
264                .into_iter()
265                .filter_map(|u| UserId::parse(u).ok())
266                .collect(),
267            left: d
268                .left
269                .into_iter()
270                .filter_map(|u| UserId::parse(u).ok())
271                .collect(),
272        })
273    }
274}
275
276#[derive(uniffi::Record)]
277pub struct KeysImportResult {
278    /// The number of room keys that were imported.
279    pub imported: i64,
280    /// The total number of room keys that were found in the export.
281    pub total: i64,
282    /// The map of keys that were imported.
283    ///
284    /// It's a map from room id to a map of the sender key to a list of session
285    /// ids.
286    pub keys: HashMap<String, HashMap<String, Vec<String>>>,
287}
288
289pub(crate) enum OwnedResponse {
290    KeysClaim(KeysClaimResponse),
291    KeysUpload(KeysUploadResponse),
292    KeysQuery(KeysQueryResponse),
293    ToDevice(ToDeviceResponse),
294    SignatureUpload(SignatureUploadResponse),
295    KeysBackup(KeysBackupResponse),
296    RoomMessage(RoomMessageResponse),
297}
298
299impl From<KeysClaimResponse> for OwnedResponse {
300    fn from(response: KeysClaimResponse) -> Self {
301        OwnedResponse::KeysClaim(response)
302    }
303}
304
305impl From<KeysQueryResponse> for OwnedResponse {
306    fn from(response: KeysQueryResponse) -> Self {
307        OwnedResponse::KeysQuery(response)
308    }
309}
310
311impl From<KeysUploadResponse> for OwnedResponse {
312    fn from(response: KeysUploadResponse) -> Self {
313        OwnedResponse::KeysUpload(response)
314    }
315}
316
317impl From<ToDeviceResponse> for OwnedResponse {
318    fn from(response: ToDeviceResponse) -> Self {
319        OwnedResponse::ToDevice(response)
320    }
321}
322
323impl From<SignatureUploadResponse> for OwnedResponse {
324    fn from(response: SignatureUploadResponse) -> Self {
325        Self::SignatureUpload(response)
326    }
327}
328
329impl From<KeysBackupResponse> for OwnedResponse {
330    fn from(r: KeysBackupResponse) -> Self {
331        Self::KeysBackup(r)
332    }
333}
334
335impl From<RoomMessageResponse> for OwnedResponse {
336    fn from(response: RoomMessageResponse) -> Self {
337        OwnedResponse::RoomMessage(response)
338    }
339}
340
341impl<'a> From<&'a OwnedResponse> for AnyIncomingResponse<'a> {
342    fn from(r: &'a OwnedResponse) -> Self {
343        match r {
344            OwnedResponse::KeysClaim(r) => AnyIncomingResponse::KeysClaim(r),
345            OwnedResponse::KeysQuery(r) => AnyIncomingResponse::KeysQuery(r),
346            OwnedResponse::KeysUpload(r) => AnyIncomingResponse::KeysUpload(r),
347            OwnedResponse::ToDevice(r) => AnyIncomingResponse::ToDevice(r),
348            OwnedResponse::SignatureUpload(r) => AnyIncomingResponse::SignatureUpload(r),
349            OwnedResponse::KeysBackup(r) => AnyIncomingResponse::KeysBackup(r),
350            OwnedResponse::RoomMessage(r) => AnyIncomingResponse::RoomMessage(r),
351        }
352    }
353}