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 pub upload_keys_request: Option<Request>,
81 pub upload_signing_keys_request: UploadSigningKeysRequest,
83 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 pub imported: i64,
283 pub total: i64,
285 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}