From 3a4745319c7a2dda5c6b395974342240a28a64fd Mon Sep 17 00:00:00 2001 From: flo-ride <43076999+flo-ride@users.noreply.github.com> Date: Tue, 24 Dec 2024 16:00:43 +0100 Subject: [PATCH] fix(recipe): Add security for Recipes --- api/src/recipe/new.rs | 15 ++++++++++++++- entity/src/models/recipe.rs | 1 - entity/src/request/recipe.rs | 13 +++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/api/src/recipe/new.rs b/api/src/recipe/new.rs index 49e7646..9588112 100644 --- a/api/src/recipe/new.rs +++ b/api/src/recipe/new.rs @@ -48,12 +48,25 @@ pub async fn post_new_recipe( let recipe_model: ActiveModel = recipe.clone().try_into()?; // Verifiy that every product exist before mutating anything - service::Query::find_product_by_id(&conn, recipe.product) + let result_product = service::Query::find_product_by_id(&conn, recipe.product) .await? .ok_or(RecipeRequestError::ProductCannotBeFound(recipe.product))?; + if result_product.unit != entity::models::sea_orm_active_enums::Unit::Unit { + return Err(RecipeRequestError::ResultingProductIsNotUnit( + result_product.id, + result_product.unit.into(), + ) + .into()); + } + for ingredient in recipe.ingredients.clone() { TryInto::::try_into(ingredient.clone())?; + if ingredient.product == recipe.product { + return Err( + RecipeRequestError::IngredientCannotBeResultingProduct(ingredient.product).into(), + ); + } service::Query::find_product_by_id(&conn, ingredient.product) .await? diff --git a/entity/src/models/recipe.rs b/entity/src/models/recipe.rs index dcff0d7..09491d9 100644 --- a/entity/src/models/recipe.rs +++ b/entity/src/models/recipe.rs @@ -21,7 +21,6 @@ pub struct Model { #[sea_orm(primary_key, auto_increment = false, filter_single)] pub id: Uuid, /// Foreign key referencing the `product` table. - #[sea_orm(filter_single)] pub result_product_id: Uuid, /// Optional name of the recipe. pub name: Option, diff --git a/entity/src/request/recipe.rs b/entity/src/request/recipe.rs index 61f7fe4..0c5bb59 100644 --- a/entity/src/request/recipe.rs +++ b/entity/src/request/recipe.rs @@ -32,6 +32,10 @@ pub enum RecipeRequestError { ProductCannotBeFound(uuid::Uuid), /// Error if the ingredient product can't be found in the database. IngredientCannotBeFound(uuid::Uuid), + /// Error if the ingredient product is the same as the resulting product. + IngredientCannotBeResultingProduct(uuid::Uuid), + /// Error if the resulting Product unit is not an Unit. + ResultingProductIsNotUnit(uuid::Uuid, crate::response::r#enum::UnitResponse), /// Error if the recipe can't be found in the database. RecipeCannotBeFound(uuid::Uuid), } @@ -59,6 +63,15 @@ impl std::fmt::Display for RecipeRequestError { RecipeRequestError::IngredientCannotBeFound(product) => { write!(f, "Ingredient \"{product}\" cannot be found") } + RecipeRequestError::IngredientCannotBeResultingProduct(product) => { + write!( + f, + "Ingredient \"{product}\" cannot be the same as the resulting product" + ) + } + RecipeRequestError::ResultingProductIsNotUnit(product, unit) => { + write!(f, "Product \"{product}\" unit cannot be {unit:?}") + } RecipeRequestError::RecipeCannotBeFound(recipe) => { write!(f, "Recipe \"{recipe}\" cannot be found") }