Recipe edit (WIP): add API to set some recipe values

This commit is contained in:
Greg Burri 2024-12-23 01:37:01 +01:00
parent c6dfff065c
commit dd05a673d9
20 changed files with 690 additions and 2189 deletions

View file

@ -0,0 +1,31 @@
use axum::{
debug_handler,
extract::{Extension, State},
response::{IntoResponse, Result},
};
// use tracing::{event, Level};
use crate::{
data::{db, model},
html_templates::*,
};
#[debug_handler]
pub async fn recipes_list_fragments(
State(connection): State<db::Connection>,
Extension(user): Extension<Option<model::User>>,
) -> Result<impl IntoResponse> {
let recipes = Recipes {
published: connection.get_all_published_recipe_titles().await?,
unpublished: if let Some(user) = user.as_ref() {
connection
.get_all_unpublished_recipe_titles(user.id)
.await?
} else {
vec![]
},
current_id: None,
};
Ok(RecipesListFragmentTemplate { user, recipes })
}

View file

@ -35,18 +35,23 @@ pub async fn edit_recipe(
if let Some(user) = user {
let recipe = connection.get_recipe(recipe_id).await?.unwrap();
if recipe.user_id == user.id {
let recipes = Recipes {
published: connection.get_all_published_recipe_titles().await?,
unpublished: connection
.get_all_unpublished_recipe_titles(user.id)
.await?,
current_id: Some(recipe_id),
};
Ok(RecipeEditTemplate {
user: Some(user),
recipes: Recipes {
list: connection.get_all_recipe_titles().await?,
current_id: Some(recipe_id),
},
recipes,
recipe,
languages: consts::LANGUAGES,
}
.into_response())
} else {
Ok(MessageTemplate::new("Unable to edit this recipe").into_response())
Ok(MessageTemplate::new("Not allowed to edit this recipe").into_response())
}
} else {
Ok(MessageTemplate::new("Not logged in").into_response())
@ -59,17 +64,37 @@ pub async fn view(
Extension(user): Extension<Option<model::User>>,
Path(recipe_id): Path<i64>,
) -> Result<Response> {
let recipes = connection.get_all_recipe_titles().await?;
match connection.get_recipe(recipe_id).await? {
Some(recipe) => Ok(RecipeViewTemplate {
user,
recipes: Recipes {
list: recipes,
current_id: Some(recipe.id),
},
recipe,
Some(recipe) => {
if !recipe.is_published
&& (user.is_none() || recipe.user_id != user.as_ref().unwrap().id)
{
return Ok(MessageTemplate::new_with_user(
&format!("Not allowed the view the recipe {}", recipe_id),
user,
)
.into_response());
}
let recipes = Recipes {
published: connection.get_all_published_recipe_titles().await?,
unpublished: if let Some(user) = user.as_ref() {
connection
.get_all_unpublished_recipe_titles(user.id)
.await?
} else {
vec![]
},
current_id: Some(recipe_id),
};
Ok(RecipeViewTemplate {
user,
recipes,
recipe,
}
.into_response())
}
.into_response()),
None => Ok(MessageTemplate::new_with_user(
&format!("Cannot find the recipe {}", recipe_id),
user,

View file

@ -81,6 +81,103 @@ pub async fn update_user(
Ok(StatusCode::OK)
}
async fn check_user_rights(
connection: &db::Connection,
user: &Option<model::User>,
recipe_id: i64,
) -> Result<()> {
if user.is_none()
|| !connection
.can_edit_recipe(user.as_ref().unwrap().id, recipe_id)
.await?
{
Err(ErrorResponse::from(ron_error(
StatusCode::UNAUTHORIZED,
"Action not authorized",
)))
} else {
Ok(())
}
}
#[debug_handler]
pub async fn set_recipe_title(
State(connection): State<db::Connection>,
Extension(user): Extension<Option<model::User>>,
ExtractRon(ron): ExtractRon<common::ron_api::SetRecipeTitle>,
) -> Result<StatusCode> {
check_user_rights(&connection, &user, ron.recipe_id).await?;
connection
.set_recipe_title(ron.recipe_id, &ron.title)
.await?;
Ok(StatusCode::OK)
}
#[debug_handler]
pub async fn set_recipe_description(
State(connection): State<db::Connection>,
Extension(user): Extension<Option<model::User>>,
ExtractRon(ron): ExtractRon<common::ron_api::SetRecipeDescription>,
) -> Result<StatusCode> {
check_user_rights(&connection, &user, ron.recipe_id).await?;
connection
.set_recipe_description(ron.recipe_id, &ron.description)
.await?;
Ok(StatusCode::OK)
}
#[debug_handler]
pub async fn set_estimated_time(
State(connection): State<db::Connection>,
Extension(user): Extension<Option<model::User>>,
ExtractRon(ron): ExtractRon<common::ron_api::SetRecipeEstimatedTime>,
) -> Result<StatusCode> {
check_user_rights(&connection, &user, ron.recipe_id).await?;
connection
.set_recipe_estimated_time(ron.recipe_id, ron.estimated_time)
.await?;
Ok(StatusCode::OK)
}
#[debug_handler]
pub async fn set_difficulty(
State(connection): State<db::Connection>,
Extension(user): Extension<Option<model::User>>,
ExtractRon(ron): ExtractRon<common::ron_api::SetRecipeDifficulty>,
) -> Result<StatusCode> {
check_user_rights(&connection, &user, ron.recipe_id).await?;
connection
.set_recipe_difficulty(ron.recipe_id, ron.difficulty)
.await?;
Ok(StatusCode::OK)
}
#[debug_handler]
pub async fn set_language(
State(connection): State<db::Connection>,
Extension(user): Extension<Option<model::User>>,
ExtractRon(ron): ExtractRon<common::ron_api::SetRecipeLanguage>,
) -> Result<StatusCode> {
check_user_rights(&connection, &user, ron.recipe_id).await?;
connection
.set_recipe_language(ron.recipe_id, &ron.lang)
.await?;
Ok(StatusCode::OK)
}
#[debug_handler]
pub async fn set_is_published(
State(connection): State<db::Connection>,
Extension(user): Extension<Option<model::User>>,
ExtractRon(ron): ExtractRon<common::ron_api::SetIsPublished>,
) -> Result<StatusCode> {
check_user_rights(&connection, &user, ron.recipe_id).await?;
connection
.set_recipe_is_published(ron.recipe_id, ron.is_published)
.await?;
Ok(StatusCode::OK)
}
///// 404 /////
#[debug_handler]
pub async fn not_found(Extension(_user): Extension<Option<model::User>>) -> impl IntoResponse {