Skip to main content

tuwunel_api_admin/users/
login_as.rs

1use std::time::{Duration, SystemTime};
2
3use axum::extract::State;
4use ruma::MilliSecondsSinceUnixEpoch;
5use synapse_admin_api::users::login_as::v1::{Request, Response};
6use tuwunel_core::{Err, Result};
7
8use crate::{Ruma, refuse_server_user, require_admin};
9
10/// # `POST /_synapse/admin/v1/users/{user_id}/login`
11///
12/// Mints a token through a visible device on the target account. The target's
13/// logout revokes it, and an optional expiry is enforced during authentication.
14/// This route is unavailable while Matrix Authentication Service is active.
15pub(crate) async fn admin_login_as_route(
16	State(services): State<crate::State>,
17	body: Ruma<Request>,
18) -> Result<Response> {
19	require_admin(&services, body.sender_user()).await?;
20
21	if !services.globals.user_is_local(&body.user_id) {
22		return Err!(Request(InvalidParam("Only local users can be logged in as")));
23	}
24
25	refuse_server_user(services, &body.user_id)?;
26
27	if body.sender_user() == body.user_id {
28		return Err!(Request(InvalidParam("Cannot use admin API to login as self")));
29	}
30
31	if !services.users.exists(&body.user_id).await {
32		return Err!(Request(NotFound("User not found")));
33	}
34
35	let expires_in = body
36		.valid_until_ms
37		.and_then(MilliSecondsSinceUnixEpoch::to_system_time)
38		.map(|valid_until| {
39			valid_until
40				.duration_since(SystemTime::now())
41				.unwrap_or(Duration::ZERO)
42		});
43
44	let (access_token, _) = services.users.generate_access_token(false);
45
46	services
47		.users
48		.create_device(
49			&body.user_id,
50			None,
51			(Some(&access_token), expires_in),
52			None,
53			Some("Admin login"),
54			None,
55		)
56		.await?;
57
58	Ok(Response::new(access_token))
59}