From 3c1e3cd38ec0de22c86fa09e8ec27bb4fdc93a32 Mon Sep 17 00:00:00 2001 From: Magnus Jensen Date: Sat, 4 Mar 2023 00:20:04 +0100 Subject: [PATCH] Fix version name can be empty string (#537) --- src/routes/project_creation.rs | 5 ++++- src/routes/projects.rs | 7 +++++-- src/routes/version_creation.rs | 5 ++++- src/routes/versions.rs | 7 +++++-- src/util/validate.rs | 27 +++++++++++++++++++++++++++ 5 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/routes/project_creation.rs b/src/routes/project_creation.rs index f516ef475..f0e4efb6d 100644 --- a/src/routes/project_creation.rs +++ b/src/routes/project_creation.rs @@ -140,7 +140,10 @@ fn default_requested_status() -> ProjectStatus { #[derive(Serialize, Deserialize, Validate, Clone)] struct ProjectCreateData { - #[validate(length(min = 3, max = 64))] + #[validate( + length(min = 3, max = 64), + custom(function = "crate::util::validate::validate_name") + )] #[serde(alias = "mod_name")] /// The title or name of the project. pub title: String, diff --git a/src/routes/projects.rs b/src/routes/projects.rs index ed8b19ee8..fb4b0c0ec 100644 --- a/src/routes/projects.rs +++ b/src/routes/projects.rs @@ -289,7 +289,10 @@ pub async fn dependency_list( /// A project returned from the API #[derive(Serialize, Deserialize, Validate)] pub struct EditProject { - #[validate(length(min = 3, max = 64))] + #[validate( + length(min = 3, max = 64), + custom(function = "crate::util::validate::validate_name") + )] pub title: Option, #[validate(length(min = 3, max = 256))] pub description: Option, @@ -441,7 +444,7 @@ pub async fn project_edit( SET title = $1 WHERE (id = $2) ", - title, + title.trim(), id as database::models::ids::ProjectId, ) .execute(&mut *transaction) diff --git a/src/routes/version_creation.rs b/src/routes/version_creation.rs index d319b91ef..34d00bb1e 100644 --- a/src/routes/version_creation.rs +++ b/src/routes/version_creation.rs @@ -41,7 +41,10 @@ pub struct InitialVersionData { regex = "crate::util::validate::RE_URL_SAFE" )] pub version_number: String, - #[validate(length(min = 1, max = 64))] + #[validate( + length(min = 1, max = 64), + custom(function = "crate::util::validate::validate_name") + )] #[serde(alias = "name")] pub version_title: String, #[validate(length(max = 65536))] diff --git a/src/routes/versions.rs b/src/routes/versions.rs index 7f135a0bd..320d141b5 100644 --- a/src/routes/versions.rs +++ b/src/routes/versions.rs @@ -216,7 +216,10 @@ pub async fn version_get( #[derive(Serialize, Deserialize, Validate)] pub struct EditVersion { - #[validate(length(min = 1, max = 64))] + #[validate( + length(min = 1, max = 64), + custom(function = "crate::util::validate::validate_name") + )] pub name: Option, #[validate( length(min = 1, max = 32), @@ -309,7 +312,7 @@ pub async fn version_edit( SET name = $1 WHERE (id = $2) ", - name, + name.trim(), id as database::models::ids::VersionId, ) .execute(&mut *transaction) diff --git a/src/util/validate.rs b/src/util/validate.rs index 253657749..91938185e 100644 --- a/src/util/validate.rs +++ b/src/util/validate.rs @@ -97,3 +97,30 @@ pub fn validate_url(value: &str) -> Result<(), validator::ValidationError> { Ok(()) } + +pub fn validate_name(value: &str) -> Result<(), validator::ValidationError> { + if value.trim().is_empty() { + return Err(validator::ValidationError::new( + "Name cannot contain only whitespace.", + )); + } + + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn validate_name_with_valid_input() { + let result = validate_name("My Test mod"); + assert!(result.is_ok()); + } + + #[test] + fn validate_name_with_invalid_input_returns_error() { + let result = validate_name(" "); + assert!(result.is_err()); + } +}