tuwunel_api/client/admin/mas/
sync_devices.rs1use axum::extract::State;
2use futures::{StreamExt, TryStreamExt};
3use ruma::OwnedDeviceId;
4use synapse_admin_api::mas::sync_devices::{Request, Response};
5use tuwunel_core::{
6 Result,
7 utils::stream::{IterStream, TryBroadbandExt, automatic_width},
8};
9
10use super::{Mas, existing_user};
11use crate::Ruma;
12
13pub(crate) async fn sync_devices_route(
15 _mas: Mas,
16 State(services): State<crate::State>,
17 body: Ruma<Request>,
18) -> Result<Response> {
19 let user_id = existing_user(services, &body.localpart).await?;
20
21 let current: Vec<OwnedDeviceId> = services
22 .users
23 .all_device_ids(&user_id)
24 .map(ToOwned::to_owned)
25 .collect()
26 .await;
27
28 current
29 .iter()
30 .filter(|device_id| !body.devices.contains(*device_id))
31 .stream()
32 .for_each_concurrent(automatic_width(), async |device_id| {
33 services
34 .users
35 .remove_device(&user_id, device_id)
36 .await;
37 })
38 .await;
39
40 body.devices
41 .iter()
42 .filter(|device_id| !current.contains(*device_id))
43 .try_stream()
44 .broad_and_then(async |device_id| {
45 services
46 .users
47 .create_device(&user_id, Some(device_id.as_ref()), (None, None), None, None, None)
48 .await
49 .map(|_| ())
50 })
51 .try_collect::<()>()
52 .await?;
53
54 Ok(Response::new())
55}