fix registering when clients dont use UIAA
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Patrick Michl 2022-06-26 22:45:05 +02:00
parent 29093c51e3
commit 8ada363a92
6 changed files with 331 additions and 45 deletions

265
Cargo.lock generated
View File

@ -8,7 +8,7 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [
"getrandom",
"getrandom 0.2.6",
"once_cell",
"version_check",
]
@ -152,7 +152,16 @@ version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388"
dependencies = [
"digest",
"digest 0.10.3",
]
[[package]]
name = "block-buffer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
"generic-array",
]
[[package]]
@ -194,6 +203,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "const-oid"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b"
[[package]]
name = "cpufeatures"
version = "0.2.2"
@ -248,13 +263,44 @@ dependencies = [
"typenum",
]
[[package]]
name = "curve25519-dalek"
version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0"
dependencies = [
"byteorder",
"digest 0.9.0",
"rand_core 0.5.1",
"subtle",
"zeroize",
]
[[package]]
name = "der"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4"
dependencies = [
"const-oid",
]
[[package]]
name = "digest"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array",
]
[[package]]
name = "digest"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
dependencies = [
"block-buffer",
"block-buffer 0.10.2",
"crypto-common",
"subtle",
]
@ -265,6 +311,29 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]]
name = "ed25519"
version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369"
dependencies = [
"signature",
]
[[package]]
name = "ed25519-dalek"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"
dependencies = [
"curve25519-dalek",
"ed25519",
"rand 0.7.3",
"serde",
"sha2 0.9.9",
"zeroize",
]
[[package]]
name = "either"
version = "1.6.1"
@ -382,6 +451,17 @@ dependencies = [
"version_check",
]
[[package]]
name = "getrandom"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.2.6"
@ -649,7 +729,7 @@ dependencies = [
"axum",
"axum-macros",
"http",
"rand",
"rand 0.8.5",
"ruma",
"serde",
"serde_json",
@ -747,6 +827,12 @@ version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]]
name = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "parking_lot"
version = "0.11.2"
@ -802,7 +888,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e029e94abc8fb0065241c308f1ac6bc8d20f450e8f7c5f0b25cd9b8d526ba294"
dependencies = [
"base64ct",
"rand_core",
"rand_core 0.6.3",
"subtle",
]
@ -850,6 +936,17 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkcs8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447"
dependencies = [
"der",
"spki",
"zeroize",
]
[[package]]
name = "pkg-config"
version = "0.3.25"
@ -890,6 +987,19 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom 0.1.16",
"libc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
"rand_hc",
]
[[package]]
name = "rand"
version = "0.8.5"
@ -897,8 +1007,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_chacha 0.3.1",
"rand_core 0.6.3",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core 0.5.1",
]
[[package]]
@ -908,7 +1028,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.6.3",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom 0.1.16",
]
[[package]]
@ -917,7 +1046,16 @@ version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
"getrandom 0.2.6",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core 0.5.1",
]
[[package]]
@ -978,6 +1116,8 @@ dependencies = [
"js_int",
"ruma-client-api",
"ruma-common",
"ruma-signatures",
"ruma-state-res",
]
[[package]]
@ -1044,6 +1184,38 @@ dependencies = [
"syn",
]
[[package]]
name = "ruma-signatures"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c747652a4f8c5fd83a703f183c73738b2ed8565a740636c045e064ae77f9b51"
dependencies = [
"base64",
"ed25519-dalek",
"pkcs8",
"rand 0.7.3",
"ruma-common",
"serde_json",
"sha2 0.9.9",
"thiserror",
"tracing",
]
[[package]]
name = "ruma-state-res"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9b742ca53b37ec3b3cfba1f27bf64be775550aeadf971deb05e4b93cdd27fbe"
dependencies = [
"itertools",
"js_int",
"ruma-common",
"serde",
"serde_json",
"thiserror",
"tracing",
]
[[package]]
name = "rustls"
version = "0.19.1"
@ -1122,6 +1294,19 @@ dependencies = [
"serde",
]
[[package]]
name = "sha2"
version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
dependencies = [
"block-buffer 0.9.0",
"cfg-if",
"cpufeatures",
"digest 0.9.0",
"opaque-debug",
]
[[package]]
name = "sha2"
version = "0.10.2"
@ -1130,7 +1315,7 @@ checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
"digest 0.10.3",
]
[[package]]
@ -1151,6 +1336,12 @@ dependencies = [
"libc",
]
[[package]]
name = "signature"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f054c6c1a6e95179d6f23ed974060dcefb2d9388bb7256900badad682c499de4"
[[package]]
name = "slab"
version = "0.4.6"
@ -1188,6 +1379,15 @@ dependencies = [
"lock_api",
]
[[package]]
name = "spki"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32"
dependencies = [
"der",
]
[[package]]
name = "sqlformat"
version = "0.1.8"
@ -1243,7 +1443,7 @@ dependencies = [
"percent-encoding",
"rustls",
"serde",
"sha2",
"sha2 0.10.2",
"smallvec",
"sqlformat",
"sqlx-rt",
@ -1270,7 +1470,7 @@ dependencies = [
"quote",
"serde",
"serde_json",
"sha2",
"sha2 0.10.2",
"sqlx-core",
"sqlx-rt",
"syn",
@ -1321,6 +1521,18 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8"
[[package]]
name = "synstructure"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
dependencies = [
"proc-macro2",
"quote",
"syn",
"unicode-xid",
]
[[package]]
name = "thiserror"
version = "1.0.30"
@ -1621,7 +1833,7 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cfcd319456c4d6ea10087ed423473267e1a071f3bc0aa89f80d60997843c6f0"
dependencies = [
"getrandom",
"getrandom 0.2.6",
]
[[package]]
@ -1652,6 +1864,12 @@ dependencies = [
"try-lock",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
@ -1817,3 +2035,24 @@ name = "windows_x86_64_msvc"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9"
[[package]]
name = "zeroize"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
dependencies = [
"zeroize_derive",
]
[[package]]
name = "zeroize_derive"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17"
dependencies = [
"proc-macro2",
"quote",
"syn",
"synstructure",
]

View File

@ -19,6 +19,6 @@ thiserror = "1.0"
argon2 = { version = "0.4", features = ["std"] }
rand = { version = "0.8.5", features = ["std"] }
uuid = { version = "1.0", features = ["v4"] }
ruma = { version = "0.6.4", features = ["client-api"] }
ruma = { version = "0.6.4", features = ["client-api", "compat"] }
axum-macros = "0.2.2"
http = "0.2.8"

View File

@ -14,6 +14,7 @@ use crate::{
},
models::{devices::Device, sessions::Session, users::User},
ruma_wrapper::{RumaRequest, RumaResponse},
types::user_id::UserId,
Config,
};
@ -40,6 +41,7 @@ async fn get_login() -> Result<RumaResponse<session::get_login_types::v3::Respon
#[tracing::instrument(skip_all)]
async fn post_login(
Extension(config): Extension<Arc<Config>>,
Extension(db): Extension<SqlitePool>,
RumaRequest(req): RumaRequest<session::login::v3::IncomingRequest>,
) -> Result<RumaResponse<session::login::v3::Response>, ApiError> {
@ -51,16 +53,18 @@ async fn post_login(
let user_id = if let IncomingUserIdentifier::UserIdOrLocalpart(user_id) =
incoming_password.identifier
{
ruma::UserId::parse(user_id).map_err(|e| anyhow::anyhow!(e))?
let user_id = UserId::new(&user_id, config.server_name())?;
ruma::UserId::parse(user_id.to_string())
.map_err(|_| AuthenticationError::InvalidUserId)?
} else {
return Err(AuthenticationError::InvalidUserId.into())
return Err(AuthenticationError::InvalidUserId.into());
};
let db_user = User::find_by_user_id(&db, user_id.as_str()).await?;
db_user
.password_correct(&password)
.ok()
.ok_or(AuthenticationError::Forbidden)?;
.map_err(|_| AuthenticationError::Forbidden)?;
let device = if let Some(device_id) = req.device_id {
Device::find_for_user(&db, &db_user, device_id.as_str()).await?
@ -81,7 +85,7 @@ async fn post_login(
ruma::OwnedDeviceId::from(device.device_id),
);
return Ok(RumaResponse(response));
Ok(RumaResponse(response))
}
_ => todo!(),
}
@ -94,11 +98,14 @@ async fn get_username_available(
Query(params): Query<HashMap<String, String>>,
) -> Result<RumaResponse<account::get_username_availability::v3::Response>, ApiError> {
use account::get_username_availability::v3::*;
tracing::debug!("username_available hit");
let username = params
.get("username")
.ok_or(RegistrationError::MissingUserId)?;
let user_id = ruma::UserId::parse(username).map_err(|_| RegistrationError::InvalidUserId)?;
let user_id = UserId::new(username, config.server_name())?;
let user_id =
ruma::UserId::parse(user_id.to_string()).map_err(|_| RegistrationError::InvalidUserId)?;
let exists = User::exists(&db, &user_id).await?;
Ok(RumaResponse(Response::new(!exists)))
@ -111,6 +118,7 @@ async fn post_register(
RumaRequest(req): RumaRequest<account::register::v3::IncomingRequest>,
) -> Result<RumaResponse<account::register::v3::Response>, ApiError> {
use account::register::v3::*;
tracing::debug!("Register hit");
config
.enable_registration()
@ -124,9 +132,12 @@ async fn post_register(
let user_id = if let IncomingUserIdentifier::UserIdOrLocalpart(user_id) =
incoming_password.identifier
{
ruma::UserId::parse(user_id).map_err(|e| anyhow::anyhow!(e))?
let user_id = UserId::new(&user_id, config.server_name())?;
ruma::UserId::parse(user_id.to_string())
.map_err(|_| AuthenticationError::InvalidUserId)?
} else {
Err(AuthenticationError::InvalidUserId)?
return Err(AuthenticationError::InvalidUserId.into());
};
if User::exists(&db, &user_id).await? {
@ -156,14 +167,57 @@ async fn post_register(
response.access_token = Some(session.key);
}
if !req.inhibit_login {
response.device_id = Some(ruma::OwnedDeviceId::from(device.device_id));
response.device_id = Some(device.device_id.into());
}
return Ok(RumaResponse(response));
Ok(RumaResponse(response))
}
_ => todo!(),
},
None => Err(RegistrationError::AdditionalAuthenticationInformation)?,
// For clients not following using UIAA
None => {
let password = req
.password
.ok_or("password missing")
.map_err(|e| anyhow::anyhow!(e))?;
let user_id = if let Some(username) = req.username {
let user_id = UserId::new(&username, config.server_name())?;
ruma::UserId::parse(user_id.to_string()).map_err(|e| anyhow::anyhow!(e))?
} else {
return Err(AuthenticationError::InvalidUserId.into());
};
unreachable!()
if User::exists(&db, &user_id).await? {
return Err(RegistrationError::UserIdTaken.into());
}
let display_name = req
.initial_device_display_name
.unwrap_or_else(|| "Random Display Name".into());
let user = User::new(&user_id, &user_id.to_string(), &password)?
.create(&db)
.await?;
let device = Device::new(
&user,
uuid::Uuid::new_v4().to_string().as_ref(),
&display_name,
)?
.create(&db)
.await?;
let mut response =
Response::new(ruma::UserId::parse(&user.user_id).map_err(|e| anyhow::anyhow!(e))?);
if !req.inhibit_login {
let session = Session::new(&device)?.create(&db).await?;
response.access_token = Some(session.key);
}
if !req.inhibit_login {
response.device_id = Some(ruma::OwnedDeviceId::from(device.device_id));
}
Ok(RumaResponse(response))
}
}
}

View File

@ -12,5 +12,10 @@ use ruma::api::client::discovery;
async fn get_client_versions() -> RumaResponse<discovery::get_supported_versions::Response> {
use discovery::get_supported_versions::*;
RumaResponse(Response::new(vec!["v1.2".into()]))
RumaResponse(Response::new(vec![
"r0.5.0".to_owned(),
"r0.6.0".to_owned(),
"v1.1".to_owned(),
"v1.2".to_owned(),
]))
}

View File

@ -100,40 +100,28 @@ mod tests {
#[test]
fn parse_ipv6_without_port() {
let server_name = ServerName::new("[::1]").unwrap();
assert_eq!(
server_name.hostname,
Hostname::IPv6("::1".parse().unwrap())
);
assert_eq!(server_name.hostname, Hostname::IPv6("::1".parse().unwrap()));
assert_eq!(server_name.port, None);
}
#[test]
fn parse_ipv6_with_port() {
let server_name = ServerName::new("[::1]:8080").unwrap();
assert_eq!(
server_name.hostname,
Hostname::IPv6("::1".parse().unwrap())
);
assert_eq!(server_name.hostname, Hostname::IPv6("::1".parse().unwrap()));
assert_eq!(server_name.port, Some(8080));
}
#[test]
fn parse_fqdn_without_port() {
let server_name = ServerName::new("example.com").unwrap();
assert_eq!(
server_name.hostname,
Hostname::Fqdn("example.com".into())
);
assert_eq!(server_name.hostname, Hostname::Fqdn("example.com".into()));
assert_eq!(server_name.port, None);
}
#[test]
fn parse_fqdn_with_port() {
let server_name = ServerName::new("example.com:8080").unwrap();
assert_eq!(
server_name.hostname,
Hostname::Fqdn("example.com".into())
);
assert_eq!(server_name.hostname, Hostname::Fqdn("example.com".into()));
assert_eq!(server_name.port, Some(8080));
}
}