From 6e54b2928870e7dc0e5cf59b3e1e27e384c3d664 Mon Sep 17 00:00:00 2001 From: philipp Date: Thu, 16 Feb 2023 11:26:41 +0100 Subject: [PATCH] final touches --- Cargo.lock | 21 +++++++ Cargo.toml | 5 +- db.sqlite | Bin 57344 -> 57344 bytes migration/src/m20230209_063357_create_user.rs | 2 + src/models/all.rs | 27 ++++----- src/models/user.rs | 5 +- src/rest/mod.rs | 52 ++++++++++++++---- src/rest/restuser.rs | 18 ++++-- templates/index.html.tera | 4 ++ templates/name.html.tera | 5 ++ templates/user/index.html.tera | 7 +++ 11 files changed, 114 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ffee99..adcffea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1185,6 +1185,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "keccak" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +dependencies = [ + "cpufeatures", +] + [[package]] name = "kernel32-sys" version = "0.2.2" @@ -2071,11 +2080,13 @@ name = "rot" version = "0.1.0" dependencies = [ "chrono", + "hex", "rocket", "rocket_dyn_templates", "sea-orm", "sea-orm-migration", "serde", + "sha3", ] [[package]] @@ -2377,6 +2388,16 @@ dependencies = [ "digest", ] +[[package]] +name = "sha3" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +dependencies = [ + "digest", + "keccak", +] + [[package]] name = "sharded-slab" version = "0.1.4" diff --git a/Cargo.toml b/Cargo.toml index 92faafe..1207e8c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,8 @@ edition = "2021" sea-orm = { version = "^0", features = [ "sqlx-sqlite", "runtime-tokio-rustls", "macros" ] } sea-orm-migration = { version = "0.11", features = [ "runtime-tokio-rustls", "sqlx-sqlite" ] } serde = { version = "1.0", features = [ "derive" ]} -rocket = "0.5.0-rc.2" +rocket = { version = "0.5.0-rc.2", features = ["secrets"]} rocket_dyn_templates = { version = "0.1.0-rc.2", features= ["tera"] } chrono = { version = "0.4", features = ["serde"]} - +sha3 = "0.10" +hex = "0.4" diff --git a/db.sqlite b/db.sqlite index 69e8f0e2e6ac5b53004b35b5d5589e96a4cb1d09..04ccdc829c4db38d8928187a6db0ce867da5191b 100644 GIT binary patch delta 3248 zcmZved2AGA6u{@cXI>8~YSng25fxVE+L>8ADgyODImF6gjBeXqXf%Qr1iZ!x;%(G4 zidUlkp@={PR;`K$iNPC{ATff1#y^ZvL`?j{c;K6*E%Ve(Cfo1VH{bVr-@N_i-L{Rt zZ5#jK@eTYshG8tcbi4$-ram;mZAE(e<*sSTjH-`iAP0ly%T~MftFhU(cUyr4w4)`ueZzS-fIkr`23tU@mCj4;(HI z47Rk@zQ1b8rQcgxxw?jfj0CF~SOxoF2fP96;qhvH-C~HFSTVwrjs4FUm95qJtB;3x<&@%qf9PM|Rj40^3);8*w#K8Nk_3aqWx&l-UF z7N28>rCdiMLtD%aouWX75l@C8XY#p`M4VvDEU8ZGWMC6q1zpgIyAVKZ3KG-ID9V&; zO3QltN-8fgjf|?4x_f4DGSi%xs&aAZ+RF9i-cnep^aPctyW*64!yqU)J&qq1f|4CL zy+Pns3Xxr@_`PM{>-LM4QsnkVcFFHX8u^}In!(oQQ`A|D`mX6)vcwB2wmUt-ySlq= zx2Gp^L$_2c*{)sjUE3~ueo%J9pi~Y5zw8&v<;V{GLLv0axKs(J)zXrJ-3;u8AK*9m z7PoIZggW2M4kaVVd?SmQ@F^S0g46isVFME<;NT?&_P|Sc^YbvTos)7b!+68{?*zip zKU*Dpk{e8N+;;ZgQQUu`>?qaaU_S%Dz?hO2r8jGIl+=4i_5vzw2=l8qAA#vYQy?5!k21@IDN} zbMP>`32uje=!V&F4op-Qfoc6|{b=p6KCoW3)>@BPtF5J0k9CPP*|Mz`%QF8me=_%) zADXY3&zoz^JIrNfuQ|s&*L2KQ6O6x&1IAazN5<>MI^$8}PU8lnY+PzgF{%(FbU*_lVllgceeMm{oGAlA2*kq z#(7+h1NJZWNA^qhJ$&ByX;S|Gm`Y}6&X{7}EK8q5RK9drZK7$gJos7m>un?-pDhts@$Q z)*&Tm9S~xpbb%6-_9;PWj}nx2QxXpyJyES>92$hyHYI31krI?Xof4GJXGmD9m&v8!18Q21-!6o)VO5l-4LgX_XR`#xr#IXCLEYE?Ub+QA*G{+xQ_t>ul$T1f{dB9}<+#_I^R_ zM9DUPNKhI(&Ee(k7!g`C8H5BoF$xNBD+NB>LV*W2Q{ci)6gY4r1vaeAp1(mJD`N!- z!Ma#ZK?pZc5Wq4D3b2#{ANncqn(+A#_1Z?-Y`Y#`YqqQ1(bH1hbu`);Xy{lta8HNZ zF)H2eOpERw>Cm$qjE%bu*V75yv~~K3@2bk5tzkDOgKV{H*Lq{iraf}?r@>K510st;%QdN7lPWW&i2DUWAbd0UCi88wB5BR+n4L zr$}d7JNgdIoHg?O`kx6y8T3td99bT*wr z6J(g2CNGhrWFL8ge35J?>&UI7gLwRErV`Qmhc#sV%KD-8jP<1Tu(iYLv2L@jvV3cf zHO-RnS^P&lh>zj@_$mAdz7OAnZ^u{T9G;7tv21p~WB$o}*{qq*nopZwGVeFno6F5> z%)EJtIo(u@ca1lUUmHI%28=z%qsC67*H~dJH3H*Oqs36sIrJtviGGX@pnmja^Z?p` zR-$WBJGu;Agf#s<{fz#Keq2AOe_gK}*tJ8ehR^k@NvfoE0XfWZGt9|2Zr}W4-ANtn zwEe!vj=3R~;a-RSU1*B^*S4t$D;OWUcm)fh5iOz30zFILps&!M(C^c4(y#I^-a*&X zm2??hKR!MfAB-YQtOHOrc6$@m<83%`bcj(>o^gP-92y%TT5t8futfgL;>Ps57& zp803HdW(&<1fZz)!~9!8vv&(%_GUo$vw+S`fcA}bW-~6kAxl&j4nx1$37JI@bW&R|B%EMi`FF>TJdiI^xZCehFaiNvZ|d zbOD(YrxVzKc?Ou959rT}G0Zq#CgzNjy&TZ}1fcVAK>IR4c4?e;a0y_3E?{mBXE?U_ zxEb4T1I^xS!0aqQHx1~d0PUH8>|=4V;G=a$>rejTx;b;Lfc^|X?<0WOivZmgKxaCj z-CQSsk>#fmDI8yYxpPxNv(Miju~x4MFq;H)DWF3DZ3~d$3G(^J=bky?haq9>|N#ly4%%Zkv7^krQe z@7}U@4VJiceQ|Hsy=!{93{eqUqP8tPYjGl~L&bGHy*;JUNKT_C1$vsEq<^F5__2=D zg{IV+7(0+0{T@4vgrpX}pC3dtq}K66SUeagbdf+`r{ATI(sgtZ&vT51ZHk&s2!cBv zP;6Tq|H*=s?YBEYyUp6<$yM^Cs(icawn?yx1(S|t=h~fYn;5HF&xec!5q2swF$>na_6kT3S8z+H^gP{<>X%`@ac#|Bsv({trR#Kg)S&HM$91i99qH z@yVh8OMhGco&I8|AJzBkd-RH4)=PS)UepUZ(^Gm<7qnq*NE_5@+JM%tRkX5J(mJ)G zR?wK1(vq5>4y!}zpjuN0)PA+1merElsTS3O%G8vaR0U;N8Bzw7nlhmDD;1@zl$1`T zs1y{Yq?Dv0$iwoG+&w7Q)~uE=G%BzMY1xgaw+#UBDe8kUBnL8&GUNc~bpDoZ7) zQz}XYiAgCbDGB1RI3x~=HE}@f7b{{}EQy_BQ7ni|Oo>TRNDL>2_~`PFW>nD&@2jzx z>t}4XqrMFJ{3+TFnBNAN`vRcdnXZ;(r5- CvgI}a diff --git a/migration/src/m20230209_063357_create_user.rs b/migration/src/m20230209_063357_create_user.rs index cd6018a..21de6f7 100644 --- a/migration/src/m20230209_063357_create_user.rs +++ b/migration/src/m20230209_063357_create_user.rs @@ -19,6 +19,7 @@ impl MigrationTrait for Migration { .primary_key(), ) .col(ColumnDef::new(User::Name).string().not_null().unique_key()) + .col(ColumnDef::new(User::Pw).string()) .col( ColumnDef::new(User::IsCox) .boolean() @@ -49,6 +50,7 @@ pub enum User { Table, Id, Name, + Pw, IsCox, IsAdmin, } diff --git a/src/models/all.rs b/src/models/all.rs index 89500f1..95a73d1 100644 --- a/src/models/all.rs +++ b/src/models/all.rs @@ -1,4 +1,4 @@ -use sea_orm::{DatabaseConnection, ModelTrait}; +use sea_orm::{ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter}; use serde::Serialize; use super::{day, trip, user}; @@ -10,16 +10,8 @@ pub struct TripWithUser { } impl TripWithUser { - async fn new(trip: trip::Model, db: &DatabaseConnection) -> Self { - Self { - trip: trip.clone(), - user: trip - .find_related(user::Entity) - .one(db) - .await - .unwrap() - .unwrap(), - } + fn new(trip: trip::Model, user: user::Model) -> Self { + Self { trip, user } } } @@ -32,8 +24,17 @@ pub struct DayWithTrips { impl DayWithTrips { pub async fn new(day: day::Model, db: &DatabaseConnection) -> Self { let mut trips = Vec::new(); - for trip in day.find_related(trip::Entity).all(db).await.unwrap() { - trips.push(TripWithUser::new(trip, db).await); + + let trips_with_users: Vec<(trip::Model, Option)> = trip::Entity::find() + .filter(trip::Column::Day.eq(day.day)) + .find_also_related(user::Entity) + .all(db) + .await + .unwrap(); + println!("{:#?}", trips_with_users); + + for (trip, users) in trips_with_users { + trips.push(TripWithUser::new(trip, users.unwrap())); } Self { day, trips } diff --git a/src/models/user.rs b/src/models/user.rs index 5139e92..dc763cb 100644 --- a/src/models/user.rs +++ b/src/models/user.rs @@ -14,6 +14,7 @@ pub struct Model { #[sea_orm(primary_key)] pub id: i32, pub name: String, + pub pw: Option, pub is_cox: bool, pub is_admin: bool, } @@ -53,7 +54,7 @@ impl<'r> FromRequest<'r> for Model { type Error = UserError; async fn from_request(req: &'r Request<'_>) -> request::Outcome { - match req.cookies().get("name") { + match req.cookies().get_private("name") { Some(name) => { let db = req.guard::<&'r State>(); let name = name.value(); @@ -70,7 +71,7 @@ impl<'r> FromRequest<'r> for AdminUser { type Error = UserError; async fn from_request(req: &'r Request<'_>) -> request::Outcome { - match req.cookies().get("name") { + match req.cookies().get_private("name") { Some(name) => { let db = req.guard::<&'r State>(); let name = name.value(); diff --git a/src/rest/mod.rs b/src/rest/mod.rs index 8c78041..671be62 100644 --- a/src/rest/mod.rs +++ b/src/rest/mod.rs @@ -14,6 +14,7 @@ use rocket::{ }; use rocket_dyn_templates::{context, Template}; use sea_orm::{Database, DatabaseConnection}; +use sha3::{Digest, Sha3_256}; use super::models::{all::DayWithTrips, day, user}; @@ -35,17 +36,18 @@ impl Deref for NaiveDateForm { } } -#[get("/")] -async fn index(db: &State, user: user::Model) -> Template { +#[get("/?")] +async fn index(db: &State, user: user::Model, all: Option) -> Template { let mut data = Vec::new(); let mut show_next_n_days = 6; - if user.is_cox { - let end_of_year = NaiveDate::from_ymd_opt(Local::now().year(), 5, 31).unwrap(); - show_next_n_days = end_of_year - .signed_duration_since(Local::now().date_naive()) - .num_days() - + 1; + if let Some(_) = all { + if user.is_cox { + let end_of_year = NaiveDate::from_ymd_opt(Local::now().year(), 12, 31).unwrap(); + show_next_n_days = end_of_year + .signed_duration_since(Local::now().date_naive()) + .num_days(); + } } for i in 0..show_next_n_days { @@ -65,17 +67,45 @@ fn name() -> Template { #[derive(FromForm)] struct NameForm { name: String, + pw: Option, } #[put("/name", data = "")] -fn savename(name: Form, cookies: &CookieJar) -> Redirect { - cookies.add(Cookie::new("name", name.name.clone())); +async fn savename( + name: Form, + cookies: &CookieJar<'_>, + db: &State, +) -> Redirect { + let user = user::Model::find_or_create_user(&name.name, db.inner()).await; + match user.pw { + Some(pw) => { + match &name.pw { + Some(entered_pw) => { + let mut hasher = Sha3_256::new(); + hasher.update(entered_pw); + let entered_pw = hasher.finalize(); + + if hex::encode(entered_pw) == pw { + cookies.add_private(Cookie::new("name", name.name.clone())); + } else { + Redirect::to("/"); // Wrong PW + } + } + None => { + Redirect::to("/"); // No PW supplied + } + } + } + None => { + cookies.add_private(Cookie::new("name", name.name.clone())); + } + } Redirect::to("/") } #[get("/logout")] fn logout(cookies: &CookieJar) -> Redirect { - cookies.remove(Cookie::new("name", "")); + cookies.remove_private(Cookie::new("name", "")); Redirect::to("/") } diff --git a/src/rest/restuser.rs b/src/rest/restuser.rs index d2f5244..704d238 100644 --- a/src/rest/restuser.rs +++ b/src/rest/restuser.rs @@ -1,10 +1,9 @@ use rocket::{form::Form, response::Redirect, Route, State}; use rocket_dyn_templates::{context, Template}; use sea_orm::{ActiveModelTrait, DatabaseConnection, EntityTrait, Set}; +use sha3::{Digest, Sha3_256}; -use crate::models::{day, user}; - -use super::NaiveDateForm; +use crate::models::user; #[get("/")] async fn index(db: &State, user: user::AdminUser) -> Template { @@ -15,6 +14,7 @@ async fn index(db: &State, user: user::AdminUser) -> Templat #[derive(FromForm)] struct UserEditForm { + pw: Option, is_cox: bool, is_admin: bool, } @@ -26,12 +26,22 @@ async fn update( data: Form, _user: user::AdminUser, ) -> Redirect { - let new_user = user::ActiveModel { + let mut new_user = user::ActiveModel { id: Set(id), is_cox: Set(data.is_cox), is_admin: Set(data.is_admin), ..Default::default() }; + if let Some(pw) = &data.pw { + if pw != "" { + let mut hasher = Sha3_256::new(); + hasher.update(pw); + let entered_pw = hasher.finalize(); + + let pw = hex::encode(entered_pw); + new_user.pw = Set(Some(pw)); + } + } new_user.update(db.inner()).await.unwrap(); Redirect::to("/user") diff --git a/templates/index.html.tera b/templates/index.html.tera index d2ac294..779e533 100644 --- a/templates/index.html.tera +++ b/templates/index.html.tera @@ -83,5 +83,9 @@ {% endfor %} +{% if user.is_cox %} + Alle heurigen Ausfahrten anzeigen +{% endif %} + {% endblock content %} diff --git a/templates/name.html.tera b/templates/name.html.tera index 57e0bc8..c3d09b6 100644 --- a/templates/name.html.tera +++ b/templates/name.html.tera @@ -3,8 +3,13 @@
+ + + + +
{% endblock content %} diff --git a/templates/user/index.html.tera b/templates/user/index.html.tera index 858e734..740621d 100644 --- a/templates/user/index.html.tera +++ b/templates/user/index.html.tera @@ -5,6 +5,7 @@ Name + Pw Cox Admin Action @@ -16,6 +17,12 @@
{{user.name}} + + {% if user.pw %} + + {% endif %} + +