tuwunel_api/client/session/
appservice.rs1use ruma::{
2 OwnedUserId, UserId,
3 api::client::{
4 session::login::v3::{ApplicationService, Request},
5 uiaa,
6 },
7};
8use tuwunel_core::{Err, Result, err, extract};
9use tuwunel_service::Services;
10
11use crate::Ruma;
12
13pub(super) fn handle_login(
14 services: &Services,
15 body: &Ruma<Request>,
16 info: &ApplicationService,
17) -> Result<OwnedUserId> {
18 #[expect(deprecated)]
19 let ApplicationService { identifier, user } = info;
20
21 let Some(ref info) = body.appservice_info else {
22 return Err!(Request(MissingToken("Missing appservice token.")));
23 };
24
25 let user_id = extract!(
26 identifier,
27 x in Some(uiaa::UserIdentifier::Matrix(uiaa::MatrixUserIdentifier { user: x, .. }))
28 )
29 .or(user.as_ref())
30 .ok_or_else(|| {
31 err!(Request(Unknown(debug_warn!(
32 ?body.login_info,
33 "Valid identifier or username was not provided (invalid or unsupported login type?)"
34 ))))
35 })?;
36
37 let user_id = UserId::parse_with_server_name(user_id, &services.config.server_name)
38 .map_err(|e| err!(Request(InvalidUsername(warn!("Username is invalid: {e}")))))?;
39
40 if !services.globals.user_is_local(&user_id) {
41 return Err!(Request(Unknown("User ID does not belong to this homeserver")));
42 }
43
44 let emergency_mode_enabled = services.config.emergency_password.is_some();
45
46 if !info.is_user_match(&user_id) && !emergency_mode_enabled {
47 return Err!(Request(Exclusive("Username is not in an appservice namespace.")));
48 }
49
50 Ok(user_id)
51}