diff --git a/Cargo.lock b/Cargo.lock index ae3db85..14afd09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -578,7 +578,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fabula_votes_server" -version = "1.0.0" +version = "1.1.0" dependencies = [ "argon2", "blake2", diff --git a/Cargo.toml b/Cargo.toml index 27aca85..57936af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ name = "fabula_votes_server" license = "MPL-2.0" readme = "README.md" authors = ["trotFunky"] -version = "1.0.0" +version = "1.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/db/03_create-week-table.sql b/db/03_create-week-table.sql new file mode 100644 index 0000000..1b24dd7 --- /dev/null +++ b/db/03_create-week-table.sql @@ -0,0 +1,10 @@ +CREATE TABLE IF NOT EXISTS Weeks ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + number INTEGER NOT NULL CHECK (number > 0), + is_last_week INTEGER NOT NULL, + rendered_text VARCHAR NOT NULL, + raw_text VARCHAR NOT NULL +); + +-- This is to upgrade from version 1.0 to 1.1 with an existing database +INSERT INTO Weeks (number, is_last_week, rendered_text, raw_text) VALUES (1, 1, "", ""); diff --git a/src/auth.rs b/src/auth.rs index 4b9df6c..1902291 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -8,7 +8,6 @@ use std::time::{SystemTime, UNIX_EPOCH}; use argon2::{Argon2, PasswordHash, PasswordVerifier}; use blake2::{Blake2b512, Digest}; use blake2::digest::FixedOutput; -use sqlx::Error; use crate::database_records::{AuthTokens, PlayerLoginInfo, Vote}; use crate::database; use database::Db; diff --git a/src/database_records.rs b/src/database_records.rs index 89c116a..b647a2c 100644 --- a/src/database_records.rs +++ b/src/database_records.rs @@ -58,3 +58,12 @@ pub struct VotingData { pub struct AuthTokens { pub token: String, } + +#[derive(sqlx::FromRow, Deserialize, Serialize)] +#[serde(crate = "rocket::serde")] +pub struct Week { + pub number: u8, + pub is_last_week: bool, + pub rendered_text: String, + pub raw_text: String, +} diff --git a/src/main.rs b/src/main.rs index 60bfd1f..da44b02 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,76 +9,23 @@ use rocket::serde::{Serialize, Deserialize, json::Json}; use rocket_dyn_templates::{Template, context}; use rocket_db_pools::{sqlx, sqlx::Row, Database, Connection}; +use sqlx::Error; -mod database_records; mod auth; -mod vote; mod truth; +mod vote; +mod week; + mod database; +mod database_records; use database::Db; use database_records::*; use auth::User; -#[get("/")] -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 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") - .bind(user.id) - .fetch_all(&mut **db).await { - Ok(v) => v, - Err(error) => { - println!("Some error while getting players : {error}"); - Vec::::new() - } - } - } else { - Vec::::new() - }; - - // 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") - .bind(week_number) - .fetch_all(&mut **db).await { - Ok(v) => v, - Err(error) => { - error!("Error while getting truths : {error}"); - Vec::::new() - } - }; - - Template::render("index", context! { - week_number: week_number, - truths: truths, - user: user, - other_players: other_players, - }) - } else { - let truths: Vec = match sqlx::query_as("SELECT id, number, author_id, rendered_text FROM Truths WHERE week == $1 ORDER BY number") - .bind(week_number) - .fetch_all(&mut **db).await { - Ok(v) => v, - Err(error) => { - error!("Error while getting truths : {error}"); - Vec::::new() - } - }; - - Template::render("index", context! { - week_number: week_number, - truths: truths, - user: user, - other_players: other_players, - }) - } -} - #[get("/")] async fn index(mut db: Connection) -> Redirect { - let current_week: u8 = match sqlx::query("SELECT max(week) AS last_week FROM Truths;") + let current_week: u8 = match sqlx::query("SELECT number FROM Weeks WHERE is_last_week == 1;") .fetch_one(&mut **db).await { Ok(v) => v.try_get(0).ok().unwrap_or_else(|| 1), // If error, go back to 1 Err(error) => { @@ -87,14 +34,14 @@ async fn index(mut db: Connection) -> Redirect { } }; - Redirect::to(uri!("/", week(week_number = if current_week == 0 {1} else {current_week}))) + Redirect::to(uri!(week::week(week_number = if current_week == 0 {1} else {current_week}))) } #[launch] fn rocket() -> _ { rocket::build() .mount("/", FileServer::from(relative!("static_files"))) - .mount("/", routes![index, vote::fetch_vote_data, vote::vote, truth::create_truth, truth::edit_truth, week, auth::login]) + .mount("/", routes![index, vote::fetch_vote_data, vote::vote, truth::create_truth, truth::edit_truth, week::week, week::update_week, auth::login]) .attach(database::stage()) .attach(Template::fairing()) } diff --git a/src/vote.rs b/src/vote.rs index e5426df..395c06c 100644 --- a/src/vote.rs +++ b/src/vote.rs @@ -10,7 +10,6 @@ use rocket::serde::json::Json; use rocket_db_pools::{sqlx, Connection}; use crate::{auth, database}; -use crate::database::Db; use crate::database_records::{Vote, VotingData}; #[derive(FromForm)] diff --git a/src/week.rs b/src/week.rs new file mode 100644 index 0000000..cbc2e9e --- /dev/null +++ b/src/week.rs @@ -0,0 +1,116 @@ +use pulldown_cmark::{Options, Parser}; +use rocket::fairing::AdHoc; +use rocket::form::Form; +use rocket::http::CookieJar; +use rocket::response::Redirect; + +use rocket_db_pools::{sqlx, Connection}; +use rocket_dyn_templates::{context, Template}; +use crate::auth; +use crate::auth::User; +use crate::database::Db; +use crate::database_records::{DisplayTruth, Player, Truth, Week}; + +#[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 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") + .bind(user.id) + .fetch_all(&mut **db).await { + Ok(v) => v, + Err(error) => { + println!("Some error while getting players : {error}"); + Vec::::new() + } + } + } else { + Vec::::new() + }; + + let week_data: Week = match sqlx::query_as("SELECT number, is_last_week, rendered_text, raw_text FROM Weeks WHERE number == $1") + .bind(week_number) + .fetch_one(&mut **db) + .await { + Ok(week) => week, + Err(error) => { + error!("Error while retrieving week data : {error}"); + Week {number: 0, is_last_week: true, rendered_text: "".to_string(), raw_text: "".to_string() } + } + }; + + // 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") + .bind(week_number) + .fetch_all(&mut **db).await { + Ok(v) => v, + Err(error) => { + error!("Error while getting truths : {error}"); + Vec::::new() + } + }; + + Template::render("index", context! { + week_data: week_data, + truths: truths, + user: user, + other_players: other_players, + }) + } else { + let truths: Vec = match sqlx::query_as("SELECT id, number, author_id, rendered_text FROM Truths WHERE week == $1 ORDER BY number") + .bind(week_number) + .fetch_all(&mut **db).await { + Ok(v) => v, + Err(error) => { + error!("Error while getting truths : {error}"); + Vec::::new() + } + }; + + Template::render("index", context! { + week_data: week_data, + truths: truths, + user: user, + other_players: other_players, + }) + } +} + +#[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; + if !user.is_admin { + cookies.add(("toast_error", "Vous n'avez pas la permission de changer la semaine.")); + return Redirect::to(uri!("/")); + } + + 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(raw_intro.as_str(), options); + + let mut rendered_markdown = String::new(); + pulldown_cmark::html::push_html(&mut rendered_markdown, markdown_parser); + + match sqlx::query("UPDATE Weeks SET raw_text = $1, rendered_text = $2 WHERE number == $3;") + .bind(&raw_intro.as_str()) + .bind(rendered_markdown) + .bind(week) + .fetch_optional(&mut **db) + .await { + Ok(_) => { + debug!("Week successfully updated") + } + Err(error) => { + error!("Error while updating week {week} data : {error}"); + cookies.add(("toast_error", "Il y a eu un problème lors du changement de la semaine")); + } + }; + + Redirect::to(uri!("/")) +} diff --git a/static_files/style.css b/static_files/style.css index 7482b04..3de7065 100644 --- a/static_files/style.css +++ b/static_files/style.css @@ -23,7 +23,7 @@ padding-bottom: 2em; } -.truth_editor { +.editor { width: 100%; height: 6eM; font-size: large; diff --git a/templates/editable_truth.tera b/templates/editable_truth.tera index 0b94cb6..22d3470 100644 --- a/templates/editable_truth.tera +++ b/templates/editable_truth.tera @@ -2,7 +2,7 @@

Vérité {{ truth.number }}

{{ truth.rendered_text | safe }}


-
+ {% include "truth_editor" %}
diff --git a/templates/index.html.tera b/templates/index.html.tera index 851acce..ae99a96 100644 --- a/templates/index.html.tera +++ b/templates/index.html.tera @@ -33,11 +33,25 @@ {% endif %} -

Semaine {{ week_number }}

+

Semaine {{ week_data.number }}

+
+ {{ week_data.rendered_text | safe }} + {%- if user.is_admin == true -%} +
+
+ + +
+ {% endif %} +
{% if user.logged_in == true and user.is_admin == false %} -
+ {% endif %} {# Truths start at 1 but the array starts at 0 #} @@ -77,7 +91,7 @@ {% if user.is_admin == true %}

Nouvelle vérité

- + {% include "truth_editor" %}
diff --git a/templates/truth_editor.html.tera b/templates/truth_editor.html.tera index 894dac4..615ed3e 100644 --- a/templates/truth_editor.html.tera +++ b/templates/truth_editor.html.tera @@ -1,4 +1,4 @@ -