implement deprecated user field for login requests

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-02-15 20:47:12 -05:00 committed by June
parent 5f007d8117
commit a0205cd41d
6 changed files with 73 additions and 33 deletions

24
Cargo.lock generated
View file

@ -2121,7 +2121,7 @@ dependencies = [
[[package]]
name = "ruma"
version = "0.9.4"
source = "git+https://github.com/ruma/ruma?rev=68c9bb0930f2195fa8672fbef9633ef62737df5d#68c9bb0930f2195fa8672fbef9633ef62737df5d"
source = "git+https://github.com/ruma/ruma?rev=4d9f754657a099df8e61533787b8eebd12946435#4d9f754657a099df8e61533787b8eebd12946435"
dependencies = [
"assign",
"js_int",
@ -2140,7 +2140,7 @@ dependencies = [
[[package]]
name = "ruma-appservice-api"
version = "0.9.0"
source = "git+https://github.com/ruma/ruma?rev=68c9bb0930f2195fa8672fbef9633ef62737df5d#68c9bb0930f2195fa8672fbef9633ef62737df5d"
source = "git+https://github.com/ruma/ruma?rev=4d9f754657a099df8e61533787b8eebd12946435#4d9f754657a099df8e61533787b8eebd12946435"
dependencies = [
"js_int",
"ruma-common",
@ -2152,7 +2152,7 @@ dependencies = [
[[package]]
name = "ruma-client-api"
version = "0.17.4"
source = "git+https://github.com/ruma/ruma?rev=68c9bb0930f2195fa8672fbef9633ef62737df5d#68c9bb0930f2195fa8672fbef9633ef62737df5d"
source = "git+https://github.com/ruma/ruma?rev=4d9f754657a099df8e61533787b8eebd12946435#4d9f754657a099df8e61533787b8eebd12946435"
dependencies = [
"as_variant",
"assign",
@ -2171,7 +2171,7 @@ dependencies = [
[[package]]
name = "ruma-common"
version = "0.12.1"
source = "git+https://github.com/ruma/ruma?rev=68c9bb0930f2195fa8672fbef9633ef62737df5d#68c9bb0930f2195fa8672fbef9633ef62737df5d"
source = "git+https://github.com/ruma/ruma?rev=4d9f754657a099df8e61533787b8eebd12946435#4d9f754657a099df8e61533787b8eebd12946435"
dependencies = [
"as_variant",
"base64",
@ -2199,7 +2199,7 @@ dependencies = [
[[package]]
name = "ruma-events"
version = "0.27.11"
source = "git+https://github.com/ruma/ruma?rev=68c9bb0930f2195fa8672fbef9633ef62737df5d#68c9bb0930f2195fa8672fbef9633ef62737df5d"
source = "git+https://github.com/ruma/ruma?rev=4d9f754657a099df8e61533787b8eebd12946435#4d9f754657a099df8e61533787b8eebd12946435"
dependencies = [
"as_variant",
"indexmap",
@ -2221,7 +2221,7 @@ dependencies = [
[[package]]
name = "ruma-federation-api"
version = "0.8.0"
source = "git+https://github.com/ruma/ruma?rev=68c9bb0930f2195fa8672fbef9633ef62737df5d#68c9bb0930f2195fa8672fbef9633ef62737df5d"
source = "git+https://github.com/ruma/ruma?rev=4d9f754657a099df8e61533787b8eebd12946435#4d9f754657a099df8e61533787b8eebd12946435"
dependencies = [
"js_int",
"ruma-common",
@ -2233,7 +2233,7 @@ dependencies = [
[[package]]
name = "ruma-identifiers-validation"
version = "0.9.3"
source = "git+https://github.com/ruma/ruma?rev=68c9bb0930f2195fa8672fbef9633ef62737df5d#68c9bb0930f2195fa8672fbef9633ef62737df5d"
source = "git+https://github.com/ruma/ruma?rev=4d9f754657a099df8e61533787b8eebd12946435#4d9f754657a099df8e61533787b8eebd12946435"
dependencies = [
"js_int",
"thiserror",
@ -2242,7 +2242,7 @@ dependencies = [
[[package]]
name = "ruma-identity-service-api"
version = "0.8.0"
source = "git+https://github.com/ruma/ruma?rev=68c9bb0930f2195fa8672fbef9633ef62737df5d#68c9bb0930f2195fa8672fbef9633ef62737df5d"
source = "git+https://github.com/ruma/ruma?rev=4d9f754657a099df8e61533787b8eebd12946435#4d9f754657a099df8e61533787b8eebd12946435"
dependencies = [
"js_int",
"ruma-common",
@ -2252,7 +2252,7 @@ dependencies = [
[[package]]
name = "ruma-macros"
version = "0.12.0"
source = "git+https://github.com/ruma/ruma?rev=68c9bb0930f2195fa8672fbef9633ef62737df5d#68c9bb0930f2195fa8672fbef9633ef62737df5d"
source = "git+https://github.com/ruma/ruma?rev=4d9f754657a099df8e61533787b8eebd12946435#4d9f754657a099df8e61533787b8eebd12946435"
dependencies = [
"once_cell",
"proc-macro-crate",
@ -2267,7 +2267,7 @@ dependencies = [
[[package]]
name = "ruma-push-gateway-api"
version = "0.8.0"
source = "git+https://github.com/ruma/ruma?rev=68c9bb0930f2195fa8672fbef9633ef62737df5d#68c9bb0930f2195fa8672fbef9633ef62737df5d"
source = "git+https://github.com/ruma/ruma?rev=4d9f754657a099df8e61533787b8eebd12946435#4d9f754657a099df8e61533787b8eebd12946435"
dependencies = [
"js_int",
"ruma-common",
@ -2279,7 +2279,7 @@ dependencies = [
[[package]]
name = "ruma-signatures"
version = "0.14.0"
source = "git+https://github.com/ruma/ruma?rev=68c9bb0930f2195fa8672fbef9633ef62737df5d#68c9bb0930f2195fa8672fbef9633ef62737df5d"
source = "git+https://github.com/ruma/ruma?rev=4d9f754657a099df8e61533787b8eebd12946435#4d9f754657a099df8e61533787b8eebd12946435"
dependencies = [
"base64",
"ed25519-dalek",
@ -2295,7 +2295,7 @@ dependencies = [
[[package]]
name = "ruma-state-res"
version = "0.10.0"
source = "git+https://github.com/ruma/ruma?rev=68c9bb0930f2195fa8672fbef9633ef62737df5d#68c9bb0930f2195fa8672fbef9633ef62737df5d"
source = "git+https://github.com/ruma/ruma?rev=4d9f754657a099df8e61533787b8eebd12946435#4d9f754657a099df8e61533787b8eebd12946435"
dependencies = [
"itertools 0.11.0",
"js_int",

View file

@ -23,8 +23,8 @@ tower-http = { version = "0.4.4", features = ["add-extension", "cors", "sensitiv
# Used for matrix spec type definitions and helpers
#ruma = { version = "0.4.0", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] }
ruma = { git = "https://github.com/ruma/ruma", rev = "68c9bb0930f2195fa8672fbef9633ef62737df5d", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified", "unstable-msc2870", "unstable-msc3061", "unstable-msc2867", "unstable-extensible-events"] }
#ruma = { git = "https://github.com/timokoesters/ruma", rev = "4ec9c69bb7e09391add2382b3ebac97b6e8f4c64", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] }
ruma = { git = "https://github.com/ruma/ruma", rev = "4d9f754657a099df8e61533787b8eebd12946435", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified", "unstable-msc2870", "unstable-msc3061", "unstable-msc2867", "unstable-extensible-events"] }
#ruma = { git = "https://github.com/girlbossceo/ruma", rev = "b111ec442df34c4d6518e0ba98c6d10a451fa8a1", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified", "unstable-msc2870", "unstable-msc3061", "unstable-msc2867", "unstable-extensible-events"] }
#ruma = { path = "../ruma/crates/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] }
# Async runtime and utilities

View file

@ -71,11 +71,11 @@ pub async fn get_register_available_route(
Ok(get_username_availability::v3::Response { available: true })
}
/// # `POST /_matrix/client/r0/register`
/// # `POST /_matrix/client/v3/register`
///
/// Register an account on this homeserver.
///
/// You can use [`GET /_matrix/client/r0/register/available`](fn.get_register_available_route.html)
/// You can use [`GET /_matrix/client/v3/register/available`](fn.get_register_available_route.html)
/// to check if the user id is valid and available.
///
/// - Only works if registration is enabled

View file

@ -17,7 +17,7 @@ use ruma::{
UserId,
};
use serde::Deserialize;
use tracing::{error, info, warn};
use tracing::{debug, error, info, warn};
#[derive(Debug, Deserialize)]
struct Claims {
@ -53,21 +53,32 @@ pub async fn login_route(body: Ruma<login::v3::Request>) -> Result<login::v3::Re
// Validate login method
// TODO: Other login methods
let user_id = match &body.login_info {
#[allow(deprecated)]
login::v3::LoginInfo::Password(login::v3::Password {
identifier,
password,
user,
..
}) => {
let username = if let UserIdentifier::UserIdOrLocalpart(user_id) = identifier {
debug!("Got password login type");
let username = if let Some(UserIdentifier::UserIdOrLocalpart(user_id)) = identifier {
debug!("Using username from identifier field");
user_id.to_lowercase()
} else if let Some(user_id) = user {
warn!("User \"{}\" is attempting to login with the deprecated \"user\" field at \"/_matrix/client/v3/login\". conduwuit implements this deprecated behaviour, but this is destined to be removed in a future Matrix release.", user_id);
user_id.to_lowercase()
} else {
warn!("Bad login type: {:?}", &body.login_info);
return Err(Error::BadRequest(ErrorKind::Forbidden, "Bad login type."));
};
let user_id =
UserId::parse_with_server_name(username, services().globals.server_name())
.map_err(|_| {
.map_err(|e| {
warn!("Failed to parse username from user logging in: {}", e);
Error::BadRequest(ErrorKind::InvalidUsername, "Username is invalid.")
})?;
let hash = services()
.users
.password_hash(&user_id)?
@ -82,15 +93,18 @@ pub async fn login_route(body: Ruma<login::v3::Request>) -> Result<login::v3::Re
"The user has been deactivated",
));
}
let Ok(parsed_hash) = PasswordHash::new(&hash) else {
error!("error while hashing user {}", user_id);
return Err(Error::BadServerResponse("could not hash"));
};
let hash_matches = services()
.globals
.argon
.verify_password(password.as_bytes(), &parsed_hash)
.is_ok();
if !hash_matches {
return Err(Error::BadRequest(
ErrorKind::Forbidden,
@ -101,16 +115,25 @@ pub async fn login_route(body: Ruma<login::v3::Request>) -> Result<login::v3::Re
user_id
}
login::v3::LoginInfo::Token(login::v3::Token { token }) => {
debug!("Got token login type");
if let Some(jwt_decoding_key) = services().globals.jwt_decoding_key() {
let token = jsonwebtoken::decode::<Claims>(
token,
jwt_decoding_key,
&jsonwebtoken::Validation::default(),
)
.map_err(|_| Error::BadRequest(ErrorKind::InvalidUsername, "Token is invalid."))?;
.map_err(|e| {
warn!("Failed to parse JWT token from user logging in: {}", e);
Error::BadRequest(ErrorKind::InvalidUsername, "Token is invalid.")
})?;
let username = token.claims.sub.to_lowercase();
UserId::parse_with_server_name(username, services().globals.server_name()).map_err(
|_| Error::BadRequest(ErrorKind::InvalidUsername, "Username is invalid."),
|e| {
warn!("Failed to parse username from user logging in: {}", e);
Error::BadRequest(ErrorKind::InvalidUsername, "Username is invalid.")
},
)?
} else {
return Err(Error::BadRequest(
@ -119,28 +142,41 @@ pub async fn login_route(body: Ruma<login::v3::Request>) -> Result<login::v3::Re
));
}
}
login::v3::LoginInfo::ApplicationService(login::v3::ApplicationService { identifier }) => {
#[allow(deprecated)]
login::v3::LoginInfo::ApplicationService(login::v3::ApplicationService {
identifier,
user,
}) => {
debug!("Got appservice login type");
if !body.from_appservice {
info!("User tried logging in as an appservice, but request body is not from a known/registered appservice");
return Err(Error::BadRequest(
ErrorKind::Forbidden,
"Forbidden login type.",
));
};
let username = if let UserIdentifier::UserIdOrLocalpart(user_id) = identifier {
let username = if let Some(UserIdentifier::UserIdOrLocalpart(user_id)) = identifier {
user_id.to_lowercase()
} else if let Some(user_id) = user {
warn!("Appservice \"{}\" is attempting to login with the deprecated \"user\" field at \"/_matrix/client/v3/login\". conduwuit implements this deprecated behaviour, but this is destined to be removed in a future Matrix release.", user_id);
user_id.to_lowercase()
} else {
return Err(Error::BadRequest(ErrorKind::Forbidden, "Bad login type."));
};
UserId::parse_with_server_name(username, services().globals.server_name()).map_err(
|_| Error::BadRequest(ErrorKind::InvalidUsername, "Username is invalid."),
|e| {
warn!("Failed to parse username from appservice logging in: {}", e);
Error::BadRequest(ErrorKind::InvalidUsername, "Username is invalid.")
},
)?
}
_ => {
warn!("Unsupported or unknown login type: {:?}", &body.login_info);
debug!("JSON body: {:?}", &body.json_body);
return Err(Error::BadRequest(
ErrorKind::Unknown,
"Unsupported login type.",
"Unsupported or unknown login type.",
));
}
};

View file

@ -12,7 +12,7 @@ use ruma::{
serde::Raw,
EventId, RoomId, UserId,
};
use tracing::log::warn;
use tracing::{error, log::warn};
/// # `PUT /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}`
///
@ -105,7 +105,7 @@ pub async fn get_state_events_route(
})
}
/// # `GET /_matrix/client/r0/rooms/{roomid}/state/{eventType}/{stateKey}`
/// # `GET /_matrix/client/v3/rooms/{roomid}/state/{eventType}/{stateKey}`
///
/// Get single state event of a room.
///
@ -139,12 +139,14 @@ pub async fn get_state_events_for_key_route(
})?;
Ok(get_state_events_for_key::v3::Response {
content: serde_json::from_str(event.content.get())
.map_err(|_| Error::bad_database("Invalid event content in database"))?,
content: serde_json::from_str(event.content.get()).map_err(|e| {
error!("Invalid event content in database: {}", e);
Error::bad_database("Invalid event content in database")
})?,
})
}
/// # `GET /_matrix/client/r0/rooms/{roomid}/state/{eventType}`
/// # `GET /_matrix/client/v3/rooms/{roomid}/state/{eventType}`
///
/// Get single state event of a room.
///
@ -178,8 +180,10 @@ pub async fn get_state_events_for_empty_key_route(
})?;
Ok(get_state_events_for_key::v3::Response {
content: serde_json::from_str(event.content.get())
.map_err(|_| Error::bad_database("Invalid event content in database"))?,
content: serde_json::from_str(event.content.get()).map_err(|e| {
error!("Invalid event content in database: {}", e);
Error::bad_database("Invalid event content in database")
})?,
}
.into())
}

View file

@ -318,7 +318,7 @@ async fn run_server() -> io::Result<()> {
let socket_perms = config.unix_socket_perms.to_string();
let octal_perms = u32::from_str_radix(&socket_perms, 8).unwrap();
let listener = UnixListener::bind(path.clone()).unwrap();
let listener = UnixListener::bind(path.clone())?;
tokio::fs::set_permissions(path, Permissions::from_mode(octal_perms))
.await
.unwrap();