tuwunel_api/client/admin/users/
login_as.rs1use 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::{
9 Ruma,
10 client::admin::{refuse_server_user, require_admin},
11};
12
13pub(crate) async fn admin_login_as_route(
19 State(services): State<crate::State>,
20 body: Ruma<Request>,
21) -> Result<Response> {
22 require_admin(&services, body.sender_user()).await?;
23
24 if !services.globals.user_is_local(&body.user_id) {
25 return Err!(Request(InvalidParam("Only local users can be logged in as")));
26 }
27
28 refuse_server_user(services, &body.user_id)?;
29
30 if body.sender_user() == body.user_id {
31 return Err!(Request(InvalidParam("Cannot use admin API to login as self")));
32 }
33
34 if !services.users.exists(&body.user_id).await {
35 return Err!(Request(NotFound("User not found")));
36 }
37
38 let expires_in = body
39 .valid_until_ms
40 .and_then(MilliSecondsSinceUnixEpoch::to_system_time)
41 .map(|valid_until| {
42 valid_until
43 .duration_since(SystemTime::now())
44 .unwrap_or(Duration::ZERO)
45 });
46
47 let (access_token, _) = services.users.generate_access_token(false);
48
49 services
50 .users
51 .create_device(
52 &body.user_id,
53 None,
54 (Some(&access_token), expires_in),
55 None,
56 Some("Admin login"),
57 None,
58 )
59 .await?;
60
61 Ok(Response::new(access_token))
62}