diff --git a/README.md b/README.md index e289d5b..949ac31 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ A list of things that could be implemented/added to the application, some of the - [x] Use fairings for the different elements - [ ] Use guards for User calls ? - [ ] Use SQLite Row ID for User IDs rather than regular IDs, for randomness ? + - [x] Split user from vote data # Dependencies diff --git a/src/auth.rs b/src/auth.rs index 34c0bec..672b79d 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -9,7 +9,7 @@ use argon2::{Argon2, PasswordHash, PasswordVerifier}; use blake2::{Blake2b512, Digest}; use blake2::digest::FixedOutput; use rocket::fairing::AdHoc; -use crate::database_records::{AuthTokens, PlayerLoginInfo, Vote}; +use crate::database_records::{AuthTokens, PlayerLoginInfo}; use crate::{database, week}; use database::Db; @@ -21,11 +21,9 @@ pub struct User { pub is_admin: bool, pub id: u16, pub name: String, - pub has_week_vote: bool, - pub votes: Vec } -pub async fn get_user(week: u8, db: &mut Connection, cookies: &CookieJar<'_>) -> User { +pub async fn get_user(db: &mut Connection, cookies: &CookieJar<'_>) -> User { let auth_token: Option = match cookies.get_private("auth_token") { Some(cookie) => Some(cookie.value().to_string()), None => None @@ -87,27 +85,12 @@ pub async fn get_user(week: u8, db: &mut Connection, cookies: &CookieJar<'_> (String::new(), false) }; - // TODO: Move to src/vote.rs - let votes: Vec = if logged_in && !is_admin { - sqlx::query_as("SELECT Votes.* FROM Votes JOIN Truths ON Votes.truth_id == Truths.id AND Truths.week == $1 WHERE voter_id == $2 ORDER BY Truths.number;") - .bind(week) - .bind(&id_str) - .fetch_all(&mut ***db).await.unwrap_or_else(|error| { - error!("Error while getting votes : {error}"); - Vec::::new() - }) - } else { - Vec::::new() - }; - if logged_in { User { logged_in, is_admin, id: id_str.parse::().unwrap(), name, - has_week_vote: if votes.is_empty() { false } else { true }, - votes } } else { User { @@ -115,8 +98,6 @@ pub async fn get_user(week: u8, db: &mut Connection, cookies: &CookieJar<'_> is_admin: false, id: 0, name, - has_week_vote: false, - votes } } } diff --git a/src/truth.rs b/src/truth.rs index b9df46a..f3b6add 100644 --- a/src/truth.rs +++ b/src/truth.rs @@ -18,7 +18,7 @@ pub struct TruthUpdateForm { #[post("//edit/", data="
")] pub async fn edit_truth(week: u8, truth_number: u8, form: Form, mut db: Connection, cookies: &CookieJar<'_>) -> Redirect { - let user = auth::get_user(week, &mut db, cookies).await; + 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))); @@ -57,7 +57,7 @@ pub async fn edit_truth(week: u8, truth_number: u8, form: Form, #[post("//new_truth", data="")] pub async fn create_truth(week: u8, form: Form, mut db: Connection, cookies: &CookieJar<'_>) -> Redirect { - let user = auth::get_user(week, &mut db, cookies).await; + 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))); diff --git a/src/vote.rs b/src/vote.rs index ff1e555..550707c 100644 --- a/src/vote.rs +++ b/src/vote.rs @@ -12,6 +12,29 @@ use rocket_db_pools::{sqlx, Connection}; use crate::{auth, database, week}; use crate::database_records::{Vote, VotingData}; +#[derive(Serialize, Deserialize)] +#[serde(crate = "rocket::serde")] +pub struct WeeklyUserVotes { + pub has_week_vote: bool, + pub votes: Vec +} + +pub async fn get_weekly_user_votes(week: u8, user: &auth::User, db: &mut Connection) -> WeeklyUserVotes { + let votes: Vec = if user.logged_in && !user.is_admin { + sqlx::query_as("SELECT Votes.* FROM Votes JOIN Truths ON Votes.truth_id == Truths.id AND Truths.week == $1 WHERE voter_id == $2 ORDER BY Truths.number;") + .bind(week) + .bind(user.id) + .fetch_all(&mut ***db).await.unwrap_or_else(|error| { + error!("Error while getting votes : {error}"); + Vec::::new() + }) + } else { + Vec::::new() + }; + + WeeklyUserVotes {has_week_vote: if votes.is_empty() { false } else { true }, votes} +} + #[derive(FromForm)] pub struct VoteForm { truth_votes: HashMap @@ -20,7 +43,7 @@ pub struct VoteForm { #[post("//vote", data="")] pub async fn vote(week: u8, form: Form, mut db: Connection, cookies: &CookieJar<'_>) -> Redirect { - let user = auth::get_user(week, &mut db, cookies).await; + let user = auth::get_user(&mut db, cookies).await; if !user.logged_in { cookies.add(("toast_error", "Vous n'avez pas la permission de changer de vote.")); @@ -37,9 +60,11 @@ pub async fn vote(week: u8, form: Form, } ); + let existing_votes = get_weekly_user_votes(week, &user, &mut db).await; + let mut had_error = false; for (truth_id, voted_id) in filtered_votes { - match user.votes.iter().find(|vote: &&Vote| {vote.truth_id == *truth_id}) { + match existing_votes.votes.iter().find(|vote: &&Vote| {vote.truth_id == *truth_id}) { Some(vote) => { if *voted_id == vote.voted_id { continue; @@ -97,7 +122,7 @@ pub struct VoteData { // TODO: Cache vote count ? Maintain in state ? #[get("//votes", format = "application/json")] pub async fn fetch_vote_data(week: u8, mut db: Connection, cookies: &CookieJar<'_>) -> Option> { - let user = auth::get_user(week, &mut db, cookies).await; + let user = auth::get_user(&mut db, cookies).await; let raw_votes: Vec = sqlx::query_as(" SELECT Players.name as votes_for, Truths.number as truth_number, count(*) as votes FROM Votes JOIN Players ON Votes.voted_id == Players.id diff --git a/src/week.rs b/src/week.rs index 5168b1c..06bbbb6 100644 --- a/src/week.rs +++ b/src/week.rs @@ -7,14 +7,15 @@ use rocket::response::Redirect; use rocket_db_pools::{sqlx, Connection}; use rocket_dyn_templates::{context, Template}; use sqlx::{Acquire, Executor}; -use crate::auth; +use crate::{auth, vote}; use crate::auth::User; use crate::database::Db; use crate::database_records::{DisplayTruth, Player, Truth, Week}; +use crate::vote::WeeklyUserVotes; #[get("/")] pub async fn week(week_number: u8, mut db: Connection, cookies: &CookieJar<'_>) -> Template { - let user: User = auth::get_user(week_number, &mut db, cookies).await; + let user: User = auth::get_user(&mut db, cookies).await; let other_players = if user.logged_in { match sqlx::query_as("SELECT id, name FROM Players WHERE id <> $1 AND is_admin == 0 ORDER BY name") @@ -41,6 +42,8 @@ pub async fn week(week_number: u8, mut db: Connection, cookies: &CookieJar<' } }; + let vote_data: WeeklyUserVotes = vote::get_weekly_user_votes(week_number,&user, &mut db).await; + // FIXME : This is fucking *trash* but fucking hell mate if user.is_admin { let truths: Vec = match sqlx::query_as("SELECT * FROM Truths WHERE week == $1 ORDER BY number") @@ -58,6 +61,7 @@ pub async fn week(week_number: u8, mut db: Connection, cookies: &CookieJar<' truths: truths, user: user, other_players: other_players, + vote_data: vote_data }) } else { let truths: Vec = match sqlx::query_as("SELECT id, number, author_id, rendered_text FROM Truths WHERE week == $1 ORDER BY number") @@ -75,6 +79,7 @@ pub async fn week(week_number: u8, mut db: Connection, cookies: &CookieJar<' truths: truths, user: user, other_players: other_players, + vote_data: vote_data }) } } @@ -82,7 +87,7 @@ pub async fn week(week_number: u8, mut db: Connection, cookies: &CookieJar<' #[post("//edit", data="")] pub async fn update_week(week: u8, raw_intro: Form, mut db: Connection, cookies: &CookieJar<'_>) -> Redirect { - let user = auth::get_user(week, &mut db, cookies).await; + 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 semaine.")); return Redirect::to(uri!(week(week))); @@ -118,7 +123,7 @@ pub async fn update_week(week: u8, raw_intro: Form, #[post("//set_last")] pub async fn set_last_week(week: u8, mut db: Connection, cookies: &CookieJar<'_>) -> Redirect { - let user = auth::get_user(week, &mut db, cookies).await; + 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 semaine.")); return Redirect::to(uri!(week(week))); @@ -173,7 +178,7 @@ pub async fn set_last_week(week: u8, mut db: Connection, cookies: &CookieJar #[get("//create")] pub async fn create_week(week: u8, mut db: Connection, cookies: &CookieJar<'_>) -> Redirect { - let user = auth::get_user(week, &mut db, cookies).await; + 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 semaine.")); return Redirect::to(uri!(week(week - 1))); diff --git a/templates/weeks/index.html.tera b/templates/weeks/index.html.tera index ddf8c70..b3527d5 100644 --- a/templates/weeks/index.html.tera +++ b/templates/weeks/index.html.tera @@ -22,7 +22,7 @@ {%- endmacro display -%} {# Remove the form if all votes are locked, to reduce confusion. #} -{% set lock_truth_form = user.votes | length + 1 == truths | length and week_data.is_last_week != true %} +{% set lock_truth_form = vote_data.votes | length + 1 == truths | length and week_data.is_last_week != true %} {% block body %} @@ -91,7 +91,7 @@ {% if user.logged_in == true and user.is_admin == false and not lock_truth_form %}