Skip to main content

tuwunel_api/client/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, client::admin::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	if body.sender_user() == body.user_id {
26		return Err!(Request(InvalidParam("Cannot use admin API to login as self")));
27	}
28
29	if !services.users.exists(&body.user_id).await {
30		return Err!(Request(NotFound("User not found")));
31	}
32
33	let expires_in = body
34		.valid_until_ms
35		.and_then(MilliSecondsSinceUnixEpoch::to_system_time)
36		.map(|valid_until| {
37			valid_until
38				.duration_since(SystemTime::now())
39				.unwrap_or(Duration::ZERO)
40		});
41
42	let (access_token, _) = services.users.generate_access_token(false);
43
44	services
45		.users
46		.create_device(
47			&body.user_id,
48			None,
49			(Some(&access_token), expires_in),
50			None,
51			Some("Admin login"),
52			None,
53		)
54		.await?;
55
56	Ok(Response::new(access_token))
57}