Compare commits
2 Commits
c07a304562
...
8a7c321044
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a7c321044 | |||
| 98dbcd11f1 |
118
src/main.rs
118
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<i64>,
|
||||
submit_date: Option<String>,
|
||||
plus_player_id: i64,
|
||||
plus_nickname: String,
|
||||
plus_reason: String,
|
||||
@@ -100,9 +101,9 @@ async fn service(
|
||||
req: Request<Incoming>,
|
||||
db: Arc<Mutex<SqlitePool>>,
|
||||
) -> Result<Response<Body>, 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<i64, i64> = HashMap::new();
|
||||
let mut minus_results: HashMap<i64, i64> = 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<Incoming>, db: Arc<Mutex<SqlitePool>>) -> Vec<V
|
||||
let date = match headers.get("Date-to-fetch") {
|
||||
Some(date) => {
|
||||
let date = date.to_str().unwrap();
|
||||
let parsed_date = date.parse::<i64>();
|
||||
if parsed_date.is_err() {
|
||||
None
|
||||
if let Ok(parsed_date) = date.parse::<i64>() {
|
||||
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<Incoming>, db: Arc<Mutex<SqlitePool>>) -> Vec<V
|
||||
return Vec::new();
|
||||
}
|
||||
let formatted_date = format!("{}", date.unwrap().format("%d/%m/%Y"));
|
||||
let items = sqlx::query!(
|
||||
sqlx::query_as!(
|
||||
Vote,
|
||||
r#"SELECT * FROM votes WHERE submit_date = ?1 ORDER BY id"#,
|
||||
formatted_date
|
||||
)
|
||||
.fetch_all(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
items
|
||||
.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()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn get_admin(
|
||||
@@ -301,7 +286,7 @@ async fn get_admin(
|
||||
) -> Result<Response<Body>, 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<Player> = 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<Vote> = 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<Utc> = 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::<Vote>(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<Incoming>, db: Arc<Mutex<SqlitePool>>, 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;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<div>
|
||||
<h1>Votes</h1>
|
||||
<h3 id="votes_number"></h3>
|
||||
<p>id, plus_id, plus_nickname, plus_reason, minus_id, minus_nickname, minus_reason</p>
|
||||
<p>id, submit_date, plus_id, plus_nickname, plus_reason, minus_id, minus_nickname, minus_reason</p>
|
||||
<div id="votes"></div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
<link rel="stylesheet" href="static/css/index.css">
|
||||
</head>
|
||||
<body>
|
||||
<a href="/login" class="login" id="login">Se connecter</a>
|
||||
<div id="app" class="app">
|
||||
<h1 id="app_title">Vote +</h1>
|
||||
<label for="player_id">Pour qui votes tu?</label>
|
||||
@@ -37,5 +36,6 @@
|
||||
<a href="/results">Résultats</a>
|
||||
<a href="/archives">Archives</a>
|
||||
</div>
|
||||
<a href="/login" class="login" id="login">Se connecter</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -80,6 +80,8 @@ async function run() {
|
||||
item.style.display = "flex";
|
||||
let id = document.createElement("p");
|
||||
id.textContent = vote["id"];
|
||||
let submit_date = document.createElement("input");
|
||||
submit_date.value = vote["submit_date"];
|
||||
let plus_id = document.createElement("input");
|
||||
plus_id.type = "number";
|
||||
plus_id.value = vote["plus_player_id"];
|
||||
@@ -98,10 +100,11 @@ async function run() {
|
||||
edit.textContent = "Edit";
|
||||
let del = document.createElement("button");
|
||||
del.textContent = "Delete";
|
||||
item.append(id,plus_id,plus_nickname,plus_reason,minus_id,minus_nickname,minus_reason, edit, del);
|
||||
item.append(id,submit_date,plus_id,plus_nickname,plus_reason,minus_id,minus_nickname,minus_reason, edit, del);
|
||||
votesDiv.append(item);
|
||||
edit.addEventListener("click", async () => {
|
||||
await fetch("/admin/edit/vote", {method: "POST", body: JSON.stringify({"id": votes[i]["id"],
|
||||
"submit_date": submit_date.value,
|
||||
"plus_player_id": parseInt(plus_id.value),
|
||||
"plus_nickname": plus_nickname.value,
|
||||
"plus_reason": plus_reason.value,
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user