FabulaVotes/src/truth.rs
trotFunky 1b4a934398 auth: Split off vote data from the user
Now that the application is going to have multiple pages, vote data makes no sense
to keep with the user.
The user struct will be used everywhere to check for authentication, which is not
the case for previous votes.

Create a new struct and function in src/vote.rs to retrieve existing votes and
use them in places where user.votes was used previously.
Remove vote-related code from src/auth.rs and the week number dependence that it
required.
2024-07-28 16:55:22 +01:00

119 lines
4.2 KiB
Rust

use rocket::form::Form;
use rocket::http::CookieJar;
use rocket::response::Redirect;
use rocket_db_pools::{sqlx, Connection};
use pulldown_cmark::{Parser, Options};
use rocket::fairing::AdHoc;
use sqlx::Row;
use crate::{auth, database, week};
#[derive(FromForm)]
pub struct TruthUpdateForm {
truth_raw_text: String,
truth_author: u8,
}
#[post("/<week>/edit/<truth_number>", data="<form>")]
pub async fn edit_truth(week: u8, truth_number: u8, form: Form<TruthUpdateForm>,
mut db: Connection<database::Db>, cookies: &CookieJar<'_>) -> Redirect {
let user = auth::get_user(&mut db, cookies).await;
if !user.is_admin {
cookies.add(("toast_error", "Vous n'avez pas la permission de changer la vérité."));
return Redirect::to(uri!(week::week(week)));
}
let mut options = Options::empty();
options.insert(Options::ENABLE_STRIKETHROUGH);
options.insert(Options::ENABLE_FOOTNOTES);
options.insert(Options::ENABLE_MATH);
options.insert(Options::ENABLE_TABLES);
let markdown_parser = Parser::new_ext(form.truth_raw_text.as_str(), options);
let mut rendered_markdown = String::new();
pulldown_cmark::html::push_html(&mut rendered_markdown, markdown_parser);
match sqlx::query("UPDATE Truths SET raw_text = $1, rendered_text = $2, author_id = $3 WHERE week == $4 AND number == $5;")
.bind(&form.truth_raw_text)
.bind(rendered_markdown)
.bind(form.truth_author)
.bind(week)
.bind(truth_number)
.fetch_optional(&mut **db)
.await {
Ok(_) => {
debug!("Truth successfully updated")
}
Err(error) => {
error!("Error while updating truth {truth_number} from week {week} : {error}");
cookies.add(("toast_error", "Il y a eu un problème lors du changement de la vérité"));
}
};
Redirect::to(uri!(week::week(week)))
}
#[post("/<week>/new_truth", data="<form>")]
pub async fn create_truth(week: u8, form: Form<TruthUpdateForm>,
mut db: Connection<database::Db>, cookies: &CookieJar<'_>) -> Redirect {
let user = auth::get_user(&mut db, cookies).await;
if !user.is_admin {
cookies.add(("toast_error", "Vous n'avez pas la permission d'ajouter de vérité."));
return Redirect::to(uri!(week::week(week)));
}
let truth_number: u8 = match sqlx::query("SELECT max(number) from Truths WHERE week == $1;")
.bind(week)
.fetch_one(&mut **db)
.await {
Ok(row) => match row.try_get::<u8, usize>(0).ok() {
Some(max_truth_number) => max_truth_number+1,
None => 0
},
Err(_) => 1 // If we can't fetch a row, this is the first one.
};
if truth_number == 0 {
error!("Error while getting max truth number.");
cookies.add(("toast_error", "Erreur lors de l'ajout de la vérité..."));
return Redirect::to(uri!(week::week(week)));
}
let mut options = Options::empty();
options.insert(Options::ENABLE_STRIKETHROUGH);
options.insert(Options::ENABLE_FOOTNOTES);
options.insert(Options::ENABLE_MATH);
options.insert(Options::ENABLE_TABLES);
let markdown_parser = Parser::new_ext(form.truth_raw_text.as_str(), options);
let mut rendered_markdown = String::new();
pulldown_cmark::html::push_html(&mut rendered_markdown, markdown_parser);
match sqlx::query("INSERT INTO Truths (week, number, rendered_text, raw_text, author_id) VALUES ($1, $2, $3, $4, $5);")
.bind(week)
.bind(truth_number)
.bind(rendered_markdown)
.bind(&form.truth_raw_text)
.bind(form.truth_author)
.fetch_optional(&mut **db)
.await {
Ok(_) => {
debug!("Truth successfully updated")
}
Err(error) => {
error!("Error while creating truth {truth_number} from week {week} : {error}");
cookies.add(("toast_error", "Il y a eu un problème lors du changement de la vérité"));
}
};
debug!("Truth was successfully added");
Redirect::to(uri!(week::week(week)))
}
pub fn stage() -> AdHoc {
AdHoc::on_ignite("Truth stage", |rocket| async {
rocket.mount("/", routes![create_truth, edit_truth])
})
}