add username validation (length only)

This commit is contained in:
Joe Ardent 2023-05-16 12:24:53 -07:00
parent da5eefa73a
commit 93deaff565
3 changed files with 13 additions and 3 deletions

1
Cargo.lock generated
View file

@ -2792,6 +2792,7 @@ dependencies = [
"tower-http 0.4.0", "tower-http 0.4.0",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
"unicode-segmentation",
"uuid 1.3.1", "uuid 1.3.1",
] ]

View file

@ -22,3 +22,4 @@ thiserror = "1.0.40"
justerror = "1.1.0" justerror = "1.1.0"
password-hash = { version = "0.5.0", features = ["std", "getrandom"] } password-hash = { version = "0.5.0", features = ["std", "getrandom"] }
axum-login = { version = "0.5.0", features = ["sqlite", "sqlx"] } axum-login = { version = "0.5.0", features = ["sqlite", "sqlx"] }
unicode-segmentation = "1.10.1"

View file

@ -4,6 +4,7 @@ use argon2::{
}; };
use sqlx::{error::DatabaseError, Sqlite, SqlitePool}; use sqlx::{error::DatabaseError, Sqlite, SqlitePool};
use tracing::log::log; use tracing::log::log;
use unicode_segmentation::UnicodeSegmentation;
use uuid::Uuid; use uuid::Uuid;
const CREATE_QUERY: &str = const CREATE_QUERY: &str =
@ -44,9 +45,15 @@ pub async fn create_user(
password: &[u8], password: &[u8],
pool: &SqlitePool, pool: &SqlitePool,
) -> Result<User, CreateUserError> { ) -> Result<User, CreateUserError> {
let username = username.trim();
let name_len = username.graphemes(true).size_hint().1.unwrap();
// we are not ascii exclusivists around here
if !(1..=20).contains(&name_len) {
return Err(CreateUserErrorKind::BadUsername.into());
}
// Argon2 with default params (Argon2id v19) // Argon2 with default params (Argon2id v19)
let argon2 = Argon2::default(); let argon2 = Argon2::default();
let salt = SaltString::generate(&mut OsRng); let salt = SaltString::generate(&mut OsRng);
let pwhash = argon2 let pwhash = argon2
.hash_password(password, &salt) .hash_password(password, &salt)
@ -54,7 +61,8 @@ pub async fn create_user(
.to_string(); .to_string();
let id = Uuid::new_v4(); let id = Uuid::new_v4();
let id_bytes = id.as_bytes().as_slice(); let id_bytes = id.to_bytes_le();
let id_bytes = id_bytes.as_slice();
let res = sqlx::query(CREATE_QUERY) let res = sqlx::query(CREATE_QUERY)
.bind(id_bytes) .bind(id_bytes)
.bind(username) .bind(username)
@ -99,7 +107,7 @@ pub struct CreateUserError(#[from] CreateUserErrorKind);
#[non_exhaustive] #[non_exhaustive]
pub enum CreateUserErrorKind { pub enum CreateUserErrorKind {
AlreadyExists, AlreadyExists,
#[error(desc = "Usernames must be less than 20 characters long")] #[error(desc = "Usernames must be between 1 and 20 non-whitespace characters long")]
BadUsername, BadUsername,
PasswordMismatch, PasswordMismatch,
MissingFields, MissingFields,