Skip to main content

tuwunel_api/client/admin/users/
mod.rs

1//! Synapse admin API: user endpoints.
2
3mod account_data;
4mod allow_cross_signing_replacement;
5mod create_or_modify;
6mod deactivate_account;
7mod get_details;
8mod is_user_admin;
9mod list_joined_rooms;
10mod list_users;
11mod login_as;
12mod lookup_threepid;
13mod memberships;
14mod pushers;
15mod redact;
16mod redact_status;
17mod reset_password;
18mod suspend;
19mod username_available;
20mod whois;
21
22use futures::StreamExt;
23use ruma::{SecondsSinceUnixEpoch, UInt, UserId};
24use synapse_admin_api::users::UserDetails;
25use tuwunel_core::utils::stream::ReadyExt;
26
27pub(crate) use self::{
28	account_data::admin_account_data_route,
29	allow_cross_signing_replacement::admin_allow_cross_signing_replacement_route,
30	create_or_modify::admin_create_or_modify_route,
31	deactivate_account::admin_deactivate_account_route,
32	get_details::admin_get_details_route,
33	is_user_admin::admin_is_user_admin_route,
34	list_joined_rooms::admin_list_joined_rooms_route,
35	list_users::{admin_list_users_v2_route, admin_list_users_v3_route},
36	login_as::admin_login_as_route,
37	lookup_threepid::admin_lookup_threepid_route,
38	memberships::admin_memberships_route,
39	pushers::admin_pushers_route,
40	redact::admin_redact_user_route,
41	redact_status::admin_redact_status_route,
42	reset_password::admin_reset_password_route,
43	suspend::admin_suspend_route,
44	username_available::admin_username_available_route,
45	whois::admin_whois_route,
46};
47
48/// Action name recorded for the user-redaction task, mirroring Synapse's
49/// `REDACT_ALL_EVENTS_ACTION_NAME`. The redact-status endpoint filters on it.
50const REDACT_USER_ACTION: &str = "redact_all_events";
51
52/// Assembles the Synapse `UserDetails` for a local user from the fields tuwunel
53/// persists. Fields tuwunel never stores (guest, shadow-banned, external IDs,
54/// user type, appservice, consent) are left at their absent defaults.
55async fn user_details(services: crate::State, user_id: &UserId) -> UserDetails {
56	let displayname = services.profile.displayname(user_id).await.ok();
57
58	let avatar_url = services
59		.profile
60		.avatar_url(user_id)
61		.await
62		.ok()
63		.map(|url| url.to_string());
64
65	let admin = services.admin.user_is_admin(user_id).await;
66	let deactivated = services
67		.users
68		.is_deactivated(user_id)
69		.await
70		.unwrap_or(true);
71
72	let locked = services.users.is_locked(user_id).await;
73	let suspended = services.users.is_suspended(user_id).await;
74	let erased = services.users.is_erased(user_id).await;
75
76	let threepids = services
77		.threepid
78		.get_bindings(user_id)
79		.collect()
80		.await;
81
82	let last_seen_ts = services
83		.users
84		.all_devices_metadata(user_id)
85		.ready_fold(None, |max, device| max.max(device.last_seen_ts))
86		.await;
87
88	UserDetails {
89		displayname,
90		avatar_url,
91		admin,
92		deactivated,
93		locked,
94		suspended,
95		erased,
96		threepids,
97		last_seen_ts,
98		// tuwunel has no creation timestamp; emit a 0 sentinel (strict clients reject null).
99		creation_ts: Some(SecondsSinceUnixEpoch(UInt::from(0_u32))),
100		..UserDetails::new(user_id.to_string())
101	}
102}