1mod get_nonce;
2mod is_user_locked;
3mod is_user_suspended;
4mod lock_user;
5mod register;
6mod suspend_user;
7
8pub(crate) mod devices;
9pub(crate) mod federation;
10pub(crate) mod media;
11pub(crate) mod misc;
12pub(crate) mod rooms;
13pub mod routes;
17pub(crate) mod tokens;
18pub(crate) mod users;
19
20use futures::future::join3;
21use log as _;
22use ruma::UserId;
23pub(crate) use tuwunel_api::router::require_admin;
24use tuwunel_api::router::{ClientIp, Ruma, RumaAdmin, RumaResponse, State};
25use tuwunel_core::{Config, Err, Result};
26
27pub(crate) use self::{
28 get_nonce::admin_register_nonce_route, is_user_locked::is_user_locked_route,
29 is_user_suspended::is_user_suspended_route, lock_user::lock_user_route,
30 register::admin_register_route, suspend_user::suspend_user_route,
31};
32
33async fn authorize(services: &State, caller: &UserId, target: &UserId) -> Result {
36 if caller == target {
37 return Err!(Request(Forbidden("You cannot suspend or lock your own account")));
38 }
39
40 if !services.globals.user_is_local(target) {
41 return Err!(Request(InvalidParam("User is not local to this server")));
42 }
43
44 let (caller_admin, target_active, target_admin) = join3(
45 services.admin.user_is_admin(caller),
46 services.users.is_active(target),
47 services.admin.user_is_admin(target),
48 )
49 .await;
50
51 if !caller_admin {
52 return Err!(Request(Forbidden("Only server administrators can use this endpoint")));
53 }
54
55 if !target_active {
56 return Err!(Request(NotFound("Unknown user")));
57 }
58
59 if target_admin {
60 return Err!(Request(Forbidden(
61 "You cannot suspend or lock another server administrator"
62 )));
63 }
64
65 Ok(())
66}
67
68pub(crate) fn refuse_server_user(services: State, user_id: &UserId) -> Result {
75 if user_id == services.globals.server_user {
76 return Err!(Request(InvalidParam(
77 "The server user cannot be changed through this endpoint."
78 )));
79 }
80
81 Ok(())
82}
83
84pub(crate) fn mas_active(config: &Config) -> bool {
89 config
90 .authentication
91 .mas_secret
92 .as_deref()
93 .is_some_and(|secret| !secret.is_empty())
94}
95
96tuwunel_core::mod_ctor! {}
97tuwunel_core::mod_dtor! {}