Skip to main content

tuwunel_api_mas/
is_localpart_available.rs

1use axum::extract::State;
2use ruma::UserId;
3use synapse_admin_api::mas::is_localpart_available::{Request, Response};
4use tuwunel_core::{Err, Result, err};
5
6use super::Mas;
7use crate::Ruma;
8
9/// # `GET /_synapse/mas/is_localpart_available`
10pub(crate) async fn is_localpart_available_route(
11	_mas: Mas,
12	State(services): State<crate::State>,
13	body: Ruma<Request>,
14) -> Result<Response> {
15	if services
16		.config
17		.registration
18		.forbidden_usernames
19		.is_match(&body.localpart)
20	{
21		return Err!(Request(InvalidUsername("Localpart is forbidden")));
22	}
23
24	let user_id = UserId::parse_with_server_name(&body.localpart, services.globals.server_name())
25		.map_err(|_| err!(Request(InvalidUsername("Localpart is not a valid username"))))?;
26
27	if user_id.validate_strict().is_err() {
28		return Err!(Request(InvalidUsername("Localpart contains disallowed characters")));
29	}
30
31	if services.users.exists(&user_id).await {
32		return Err!(Request(UserInUse("Localpart is not available")));
33	}
34
35	services.users.check_creation(&user_id).await?;
36
37	if services
38		.appservice
39		.is_exclusive_user_id(&user_id)
40		.await
41	{
42		return Err!(Request(Exclusive("Localpart is reserved by an appservice")));
43	}
44
45	Ok(Response::new())
46}