Skip to main content

tuwunel_api/client/admin/rooms/
join.rs

1use axum::extract::State;
2use synapse_admin_api::room_membership::join_room::v1::{Request, Response};
3use tuwunel_core::{Err, Result};
4use tuwunel_service::membership::Join;
5
6use crate::{Ruma, client::admin::require_admin};
7
8/// # `POST /_synapse/admin/v1/join/{room_id_or_alias}`
9///
10/// Joins a local user to a room on an admin's behalf, resolving an alias and
11/// using the supplied servers as remote-join candidates.
12pub(crate) async fn admin_join_room_route(
13	State(services): State<crate::State>,
14	body: Ruma<Request>,
15) -> Result<Response> {
16	require_admin(&services, body.sender_user()).await?;
17
18	let user_id = &body.user_id;
19
20	if !services.globals.user_is_local(user_id) {
21		return Err!(Request(InvalidParam("User must be local to this server")));
22	}
23
24	if !services.users.exists(user_id).await {
25		return Err!(Request(NotFound("Unknown user")));
26	}
27
28	let (room_id, servers) = services
29		.alias
30		.maybe_resolve_with_servers(&body.room_id_or_alias, Some(body.server_name.as_slice()))
31		.await?;
32
33	services
34		.membership
35		.join(Join {
36			sender_user: user_id,
37			room_id: &room_id,
38			orig_room_id: Some(&body.room_id_or_alias),
39			reason: None,
40			servers: &servers,
41			is_appservice: false,
42			extra_content: None,
43		})
44		.await?;
45
46	Ok(Response { room_id })
47}