From 8a7c321044125992147e1cc843f39a31e6ef0dd8 Mon Sep 17 00:00:00 2001 From: AINDUSTRIES Date: Sat, 5 Oct 2024 15:09:51 +0200 Subject: [PATCH] Fixed bug related to new Vote struct, id and submit date can be None (useful for posting new votes, ie without id and submit date) --- src/main.rs | 118 +++++++++++++++++------------------------ static/html/index.html | 2 +- static/js/index.js | 12 +---- 3 files changed, 53 insertions(+), 79 deletions(-) diff --git a/src/main.rs b/src/main.rs index 78b506e..5d7711a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use argon2::{ Argon2, }; use bytes::{Buf, Bytes}; -use chrono::{DateTime, Days, Utc}; +use chrono::{DateTime, Days, NaiveTime, Timelike, Utc}; #[cfg(target_os = "linux")] use daemonize::Daemonize; use http_body_util::{BodyExt, Full}; @@ -66,9 +66,10 @@ struct Player { name: String, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Debug)] struct Vote { - id: i64, + id: Option, + submit_date: Option, plus_player_id: i64, plus_nickname: String, plus_reason: String, @@ -100,9 +101,9 @@ async fn service( req: Request, db: Arc>, ) -> Result, Error> { - match req.method() { - &Method::GET => get(req, db).await, - &Method::POST => post(req, db).await, + match *req.method() { + Method::GET => get(req, db).await, + Method::POST => post(req, db).await, _ => Ok(Response::builder() .status(StatusCode::IM_A_TEAPOT) .body(Body::Empty) @@ -224,17 +225,13 @@ async fn get_data( let mut plus_results: HashMap = HashMap::new(); let mut minus_results: HashMap = HashMap::new(); - let _ = ids.iter().for_each(|x| { + ids.iter().for_each(|x| { let plus_id = x.0; - if !plus_results.contains_key(&plus_id) { - plus_results.insert(plus_id, 0); - } + plus_results.entry(plus_id).or_insert(0); *plus_results.get_mut(&plus_id).unwrap() += 1; let minus_id = x.1; - if !minus_results.contains_key(&minus_id) { - minus_results.insert(minus_id, 0); - } + minus_results.entry(minus_id).or_insert(0); *minus_results.get_mut(&minus_id).unwrap() += 1; }); @@ -260,11 +257,10 @@ async fn get_votes(req: &Request, db: Arc>) -> Vec { let date = date.to_str().unwrap(); - let parsed_date = date.parse::(); - if parsed_date.is_err() { - None + if let Ok(parsed_date) = date.parse::() { + DateTime::from_timestamp_millis(parsed_date) } else { - DateTime::from_timestamp_millis(parsed_date.unwrap()) + None } } None => Some(DateTime::from(SystemTime::now())), @@ -273,25 +269,14 @@ async fn get_votes(req: &Request, db: Arc>) -> Vec Result, Error> { let authorised = is_authorised(req, db.clone(), 3).await; if !authorised { - return get_page(&req, "/unauthorised", db).await; + return get_page(req, "/unauthorised", db).await; } match path { "/admin" => get_page(req, path, db).await, @@ -320,38 +305,19 @@ async fn get_admin( } "/admin/players" => { let pool = db.clone().lock().unwrap().clone(); - let players = sqlx::query!(r#"SELECT id, name FROM players"#) + let players = sqlx::query_as!(Player, r#"SELECT id, name FROM players"#) .fetch_all(&pool) .await .unwrap(); - let players: Vec = players - .iter() - .map(|x| Player { - id: x.id, - name: x.name.clone(), - }) - .collect(); let stringed = serde_json::to_string(&players).unwrap_or("".to_string()); Ok(Response::builder().body(Body::new(stringed)).unwrap()) } "/admin/votes" => { let pool = db.clone().lock().unwrap().clone(); - let votes = sqlx::query!(r#"SELECT * FROM votes"#) + let votes = sqlx::query_as!(Vote, r#"SELECT * FROM votes"#) .fetch_all(&pool) .await .unwrap(); - let votes: Vec = votes - .iter() - .map(|x| Vote { - id: x.id, - plus_player_id: x.plus_player_id, - plus_nickname: x.plus_nickname.clone(), - plus_reason: x.plus_reason.clone(), - minus_player_id: x.minus_player_id, - minus_nickname: x.minus_nickname.clone(), - minus_reason: x.minus_reason.clone(), - }) - .collect(); let stringed = serde_json::to_string(&votes).unwrap_or("".to_string()); Ok(Response::builder().body(Body::new(stringed)).unwrap()) } @@ -402,7 +368,21 @@ async fn post_vote( .body(Body::Empty) .unwrap()); } - ok().await + let date: DateTime = DateTime::from(SystemTime::now()); + let date = date.checked_add_days(Days::new(1)).unwrap(); + let date = date + .with_time(NaiveTime::from_hms_opt(0, 0, 0).unwrap()) + .unwrap(); + Ok(Response::builder() + .header( + SET_COOKIE, + format!( + "hasvoted=true; Expires={}; Secure; SameSite=Strict", + date.to_rfc2822() + ), + ) + .body(Body::Empty) + .unwrap()) } async fn post_player( @@ -550,16 +530,21 @@ async fn post_admin( }, "/admin/edit/vote" => match req_json::(req).await { Some(vote) => { + if vote.id.is_none() || vote.submit_date.is_none() { + return bad_request().await; + } let pool = db.clone().lock().unwrap().clone(); let _ = sqlx::query!( r#"UPDATE votes - SET plus_player_id = ?1, - plus_nickname = ?2, - plus_reason = ?3, - minus_player_id = ?4, - minus_nickname = ?5, - minus_reason = ?6 - WHERE id = ?7"#, + SET submit_date = ?1, + plus_player_id = ?2, + plus_nickname = ?3, + plus_reason = ?4, + minus_player_id = ?5, + minus_nickname = ?6, + minus_reason = ?7 + WHERE id = ?8"#, + vote.submit_date, vote.plus_player_id, vote.plus_nickname, vote.plus_reason, @@ -589,7 +574,7 @@ async fn post_admin( ok().await } _ => bad_request().await, - } + }, _ => bad_request().await, } } @@ -749,14 +734,11 @@ async fn is_authorised(req: &Request, db: Arc>, leve let perm = user.permissions as u8; perm >= level } - _ => match level { - 0 => true, - _ => false, - }, + _ => matches!(level, 0), } } -fn check_username(username: &String) -> bool { +fn check_username(username: &str) -> bool { if username.len() > 21 { return false; } @@ -768,7 +750,7 @@ fn check_username(username: &String) -> bool { true } -fn check_password(password: &String) -> bool { +fn check_password(password: &str) -> bool { // one symbol, 10 chars min, one capital letter, one number if password.len() < 10 { return false; diff --git a/static/html/index.html b/static/html/index.html index 6474231..51d73e8 100644 --- a/static/html/index.html +++ b/static/html/index.html @@ -11,7 +11,6 @@ -

Vote +

@@ -37,5 +36,6 @@ Résultats Archives
+ \ No newline at end of file diff --git a/static/js/index.js b/static/js/index.js index 4ce1531..8a98fb0 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -1,4 +1,5 @@ let vote = { + submit_date: null, plus_player_id: null, plus_nickname: "", plus_reason: "", @@ -11,7 +12,7 @@ let current_page = 0; async function main() { if (read_cookie()) { - showMessage("Merci pour ton vote!", "Ton vote a bien été prit en compte.", false, "info"); + showMessage("Merci pour ton vote!", "Ton vote a bien été pris en compte.", false, "info"); return; } let players = await fetch("/data/players").then(r => r.json()); @@ -95,7 +96,6 @@ async function main() { method: "post", body: JSON.stringify(vote) }) .then(r => r.status) === 200) { - set_cookie(); showMessage("Merci pour ton vote!", "Ton vote a bien été pris en compte.", false, "info"); } console.log(vote); @@ -160,14 +160,6 @@ function showMessage(title, description, canBeDismissed, type) { }) } -function set_cookie() { - let date = new Date(Date.now()); - date.setDate(date.getDate() + 1); - date.setHours(0, 0,0); - console.log(date); - document.cookie = `hasvoted=true; expires=${date.toUTCString()}; path=/`; -} - function read_cookie() { return document.cookie.includes("hasvoted=true"); }