add username validation (length only)
This commit is contained in:
parent
da5eefa73a
commit
93deaff565
3 changed files with 13 additions and 3 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -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",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
14
src/users.rs
14
src/users.rs
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue