Skip to main content

tuwunel_api/client/admin/
mod.rs

1mod get_nonce;
2mod is_user_locked;
3mod is_user_suspended;
4mod lock_user;
5pub(crate) mod mas;
6mod register;
7mod suspend_user;
8
9pub(crate) mod devices;
10pub(crate) mod federation;
11pub(crate) mod media;
12pub(crate) mod misc;
13pub(crate) mod rooms;
14pub(crate) mod tokens;
15pub(crate) mod users;
16
17use futures::future::join3;
18use ruma::UserId;
19use tuwunel_core::{Config, Err, Result, err};
20
21pub(crate) use self::{
22	get_nonce::admin_register_nonce_route, is_user_locked::is_user_locked_route,
23	is_user_suspended::is_user_suspended_route, lock_user::lock_user_route,
24	register::admin_register_route, suspend_user::suspend_user_route,
25};
26
27/// MSC4323: authorization is checked before account lookups
28/// (anti-enumeration) per spec.
29async fn authorize(services: &crate::State, caller: &UserId, target: &UserId) -> Result {
30	if caller == target {
31		return Err!(Request(Forbidden("You cannot suspend or lock your own account")));
32	}
33
34	if !services.globals.user_is_local(target) {
35		return Err!(Request(InvalidParam("User is not local to this server")));
36	}
37
38	let (caller_admin, target_active, target_admin) = join3(
39		services.admin.user_is_admin(caller),
40		services.users.is_active(target),
41		services.admin.user_is_admin(target),
42	)
43	.await;
44
45	if !caller_admin {
46		return Err!(Request(Forbidden("Only server administrators can use this endpoint")));
47	}
48
49	if !target_active {
50		return Err!(Request(NotFound("Unknown user")));
51	}
52
53	if target_admin {
54		return Err!(Request(Forbidden(
55			"You cannot suspend or lock another server administrator"
56		)));
57	}
58
59	Ok(())
60}
61
62/// Assert the caller is a server administrator. Generic Synapse admin
63/// endpoints use this plain check, not the MSC4323 anti-enumeration
64/// `authorize()` guard whose self-target and admin-target ordering does not
65/// fit them.
66pub(crate) async fn require_admin(services: &crate::State, sender: &UserId) -> Result {
67	services
68		.admin
69		.user_is_admin(sender)
70		.await
71		.then_some(())
72		.ok_or_else(|| {
73			err!(Request(Forbidden("Only server administrators can use this endpoint")))
74		})
75}
76
77/// True when Matrix Authentication Service delegation is active, in which case
78/// the Synapse-mirrored admin routes MAS owns (user admin, login-as,
79/// reset_password, registration tokens) are left unregistered and answer 404,
80/// mirroring Synapse's de-registration of those servlets.
81pub(crate) fn mas_active(config: &Config) -> bool {
82	config
83		.mas_secret
84		.as_deref()
85		.is_some_and(|secret| !secret.is_empty())
86}