fix: consistent username validation across routes

fixes #187
This commit is contained in:
Paul Makles
2022-06-20 10:27:22 +01:00
parent f96541efab
commit 0585dd0c20
3 changed files with 12 additions and 10 deletions

View File

@@ -32,13 +32,10 @@ pub async fn req(
data.validate() data.validate()
.map_err(|error| Error::FailedValidation { error })?; .map_err(|error| Error::FailedValidation { error })?;
if db.is_username_taken(&data.username).await? { let username = User::validate_username(db, data.username).await?;
return Err(Error::UsernameTaken);
}
let user = User { let user = User {
id: session.user_id, id: session.user_id,
username: data.username, username,
..Default::default() ..Default::default()
}; };

View File

@@ -6,4 +6,4 @@ use regex::Regex;
/// Block zero width space /// Block zero width space
/// Block lookalike characters /// Block lookalike characters
pub static RE_USERNAME: Lazy<Regex> = pub static RE_USERNAME: Lazy<Regex> =
Lazy::new(|| Regex::new(r"^[^\u200BА-Яа-яΑ-Ωα-ω]+$").unwrap()); Lazy::new(|| Regex::new(r"^[^\u200BА-Яа-яΑ-Ωα-ω@#:\n]+$").unwrap());

View File

@@ -150,8 +150,8 @@ impl User {
Ok(db.fetch_server_count(&self.id).await? <= 100) Ok(db.fetch_server_count(&self.id).await? <= 100)
} }
/// Update a user's username /// Sanitise and validate a username can be used
pub async fn update_username(&mut self, db: &Database, username: String) -> Result<()> { pub async fn validate_username(db: &Database, username: String) -> Result<String> {
// Trim surrounding spaces // Trim surrounding spaces
let username = username.trim().to_string(); let username = username.trim().to_string();
@@ -173,7 +173,7 @@ impl User {
} }
// Ensure none of the following substrings show up in the username // Ensure none of the following substrings show up in the username
const BLOCKED_SUBSTRINGS: &[&str] = &["@", "#", ":", "```", "\n"]; const BLOCKED_SUBSTRINGS: &[&str] = &["```"];
for substr in BLOCKED_SUBSTRINGS { for substr in BLOCKED_SUBSTRINGS {
if username_lowercase.contains(substr) { if username_lowercase.contains(substr) {
@@ -186,10 +186,15 @@ impl User {
return Err(Error::UsernameTaken); return Err(Error::UsernameTaken);
} }
Ok(username)
}
/// Update a user's username
pub async fn update_username(&mut self, db: &Database, username: String) -> Result<()> {
self.update( self.update(
db, db,
PartialUser { PartialUser {
username: Some(username), username: Some(User::validate_username(db, username).await?),
..Default::default() ..Default::default()
}, },
vec![], vec![],