weird login
This commit is contained in:
parent
9c0e3e4fa7
commit
959f6c08df
110
Cargo.lock
generated
110
Cargo.lock
generated
@ -17,6 +17,41 @@ version = "2.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aead"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
|
||||||
|
dependencies = [
|
||||||
|
"crypto-common",
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aes"
|
||||||
|
version = "0.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cipher",
|
||||||
|
"cpufeatures",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aes-gcm"
|
||||||
|
version = "0.10.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
|
||||||
|
dependencies = [
|
||||||
|
"aead",
|
||||||
|
"aes",
|
||||||
|
"cipher",
|
||||||
|
"ctr",
|
||||||
|
"ghash",
|
||||||
|
"subtle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.1.3"
|
version = "1.1.3"
|
||||||
@ -274,6 +309,16 @@ dependencies = [
|
|||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cipher"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
||||||
|
dependencies = [
|
||||||
|
"crypto-common",
|
||||||
|
"inout",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "concurrent-queue"
|
name = "concurrent-queue"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@ -295,7 +340,11 @@ version = "0.18.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
|
checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aes-gcm",
|
||||||
|
"base64",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
|
"rand",
|
||||||
|
"subtle",
|
||||||
"time",
|
"time",
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
@ -371,9 +420,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
|
"rand_core",
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ctr"
|
||||||
|
version = "0.9.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
|
||||||
|
dependencies = [
|
||||||
|
"cipher",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "der"
|
name = "der"
|
||||||
version = "0.7.9"
|
version = "0.7.9"
|
||||||
@ -646,6 +705,16 @@ dependencies = [
|
|||||||
"wasi 0.14.2+wasi-0.2.4",
|
"wasi 0.14.2+wasi-0.2.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ghash"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1"
|
||||||
|
dependencies = [
|
||||||
|
"opaque-debug",
|
||||||
|
"polyval",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
version = "0.31.1"
|
version = "0.31.1"
|
||||||
@ -1011,6 +1080,15 @@ dependencies = [
|
|||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inout"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
@ -1151,9 +1229,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.8.7"
|
version = "0.8.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ff70ce3e48ae43fa075863cef62e8b43b71a4f2382229920e0df362592919430"
|
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler2",
|
"adler2",
|
||||||
]
|
]
|
||||||
@ -1246,6 +1324,12 @@ version = "1.21.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opaque-debug"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking"
|
name = "parking"
|
||||||
version = "2.2.1"
|
version = "2.2.1"
|
||||||
@ -1329,6 +1413,18 @@ version = "0.3.32"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "polyval"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"opaque-debug",
|
||||||
|
"universal-hash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "powerfmt"
|
name = "powerfmt"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@ -2383,6 +2479,16 @@ version = "0.1.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
|
checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "universal-hash"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
|
||||||
|
dependencies = [
|
||||||
|
"crypto-common",
|
||||||
|
"subtle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unsafe-libyaml"
|
name = "unsafe-libyaml"
|
||||||
version = "0.2.11"
|
version = "0.2.11"
|
||||||
|
@ -5,7 +5,7 @@ edition = "2024"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = "0.8"
|
axum = "0.8"
|
||||||
axum-extra = { version = "0.10", features = [ "cookie" ]}
|
axum-extra = { version = "0.10", features = [ "cookie", "cookie-private" ]}
|
||||||
chrono = { version = "0.4", features = ["serde"]}
|
chrono = { version = "0.4", features = ["serde"]}
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
maud = { version = "0.27", features = ["axum"] }
|
maud = { version = "0.27", features = ["axum"] }
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
use crate::page;
|
use crate::{page, AppState};
|
||||||
use axum::{routing::get, Router};
|
use axum::{routing::get, Router};
|
||||||
use maud::{html, Markup};
|
use maud::{html, Markup};
|
||||||
use sqlx::SqlitePool;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use tower_sessions::Session;
|
use tower_sessions::Session;
|
||||||
|
|
||||||
pub(crate) mod route;
|
pub(crate) mod route;
|
||||||
@ -35,7 +33,7 @@ async fn index(session: Session) -> Markup {
|
|||||||
page(content, session, false).await
|
page(content, session, false).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn routes() -> Router<Arc<SqlitePool>> {
|
pub(super) fn routes() -> Router<AppState> {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/", get(index))
|
.route("/", get(index))
|
||||||
.nest("/station", station::routes())
|
.nest("/station", station::routes())
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
use crate::admin::{station::Station, team::Team};
|
use crate::{
|
||||||
|
admin::{station::Station, team::Team},
|
||||||
|
AppState,
|
||||||
|
};
|
||||||
use axum::Router;
|
use axum::Router;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{FromRow, Row, SqlitePool};
|
use sqlx::{FromRow, Row, SqlitePool};
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
mod web;
|
mod web;
|
||||||
|
|
||||||
@ -195,6 +197,6 @@ DROP TABLE temp_pos;",
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn routes() -> Router<Arc<SqlitePool>> {
|
pub(super) fn routes() -> Router<AppState> {
|
||||||
web::routes()
|
web::routes()
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use super::Route;
|
use super::Route;
|
||||||
use crate::{admin::station::Station, err, page, succ};
|
use crate::{admin::station::Station, err, page, succ, AppState};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::State,
|
extract::State,
|
||||||
response::{IntoResponse, Redirect},
|
response::{IntoResponse, Redirect},
|
||||||
@ -53,7 +53,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
}
|
}
|
||||||
h2 { "Neue Route" }
|
h2 { "Neue Route" }
|
||||||
form action="/admin/route" method="post" {
|
form action="/admin/route" method="post" {
|
||||||
fieldset role="team" {
|
fieldset role="group" {
|
||||||
input type="text" name="name" placeholder="Routenname" required;
|
input type="text" name="name" placeholder="Routenname" required;
|
||||||
input type="submit" value="Neue Route";
|
input type="submit" value="Neue Route";
|
||||||
}
|
}
|
||||||
@ -374,7 +374,7 @@ async fn move_station_higher(
|
|||||||
Redirect::to(&format!("/admin/route/{route_id}"))
|
Redirect::to(&format!("/admin/route/{route_id}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn routes() -> Router<Arc<SqlitePool>> {
|
pub(super) fn routes() -> Router<AppState> {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/", get(index))
|
.route("/", get(index))
|
||||||
.route("/", post(create))
|
.route("/", post(create))
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
use crate::admin::route::Route;
|
use crate::{admin::route::Route, AppState};
|
||||||
use axum::Router;
|
use axum::Router;
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{FromRow, SqlitePool};
|
use sqlx::{FromRow, SqlitePool};
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
mod web;
|
mod web;
|
||||||
|
|
||||||
@ -14,7 +13,7 @@ pub(crate) struct Station {
|
|||||||
notes: Option<String>,
|
notes: Option<String>,
|
||||||
amount_people: Option<i64>,
|
amount_people: Option<i64>,
|
||||||
last_login: Option<NaiveDateTime>, // TODO use proper timestamp (NaiveDateTime?)
|
last_login: Option<NaiveDateTime>, // TODO use proper timestamp (NaiveDateTime?)
|
||||||
pw: String,
|
pub(crate) pw: String,
|
||||||
lat: Option<f64>,
|
lat: Option<f64>,
|
||||||
lng: Option<f64>,
|
lng: Option<f64>,
|
||||||
}
|
}
|
||||||
@ -139,6 +138,6 @@ impl Station {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn routes() -> Router<Arc<SqlitePool>> {
|
pub(super) fn routes() -> Router<AppState> {
|
||||||
web::routes()
|
web::routes()
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{admin::station::Station, er, err, partials::page, suc, succ};
|
use crate::{admin::station::Station, er, err, partials::page, suc, succ, AppState};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::State,
|
extract::State,
|
||||||
response::{IntoResponse, Redirect},
|
response::{IntoResponse, Redirect},
|
||||||
@ -450,7 +450,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
}
|
}
|
||||||
h2 { (t!("station_new")) }
|
h2 { (t!("station_new")) }
|
||||||
form action="/admin/station" method="post" {
|
form action="/admin/station" method="post" {
|
||||||
fieldset role="team" {
|
fieldset role="group" {
|
||||||
input type="text" name="name" placeholder=(t!("station_name")) required;
|
input type="text" name="name" placeholder=(t!("station_name")) required;
|
||||||
input type="submit" value=(t!("station_new"));
|
input type="submit" value=(t!("station_new"));
|
||||||
}
|
}
|
||||||
@ -459,7 +459,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
page(content, session, false).await
|
page(content, session, false).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn routes() -> Router<Arc<SqlitePool>> {
|
pub(super) fn routes() -> Router<AppState> {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/", get(index))
|
.route("/", get(index))
|
||||||
.route("/", post(create))
|
.route("/", post(create))
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
use crate::admin::{route::Route, station::Station};
|
use crate::{
|
||||||
|
admin::{route::Route, station::Station},
|
||||||
|
AppState,
|
||||||
|
};
|
||||||
use axum::Router;
|
use axum::Router;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{FromRow, SqlitePool};
|
use sqlx::{FromRow, SqlitePool};
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
mod web;
|
mod web;
|
||||||
|
|
||||||
@ -165,6 +167,6 @@ impl Team {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn routes() -> Router<Arc<SqlitePool>> {
|
pub(super) fn routes() -> Router<AppState> {
|
||||||
web::routes()
|
web::routes()
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
use super::{CreateError, Team};
|
use super::{CreateError, Team};
|
||||||
use crate::{admin::route::Route, admin::station::Station, err, partials::page, pl, succ};
|
use crate::{
|
||||||
|
admin::{route::Route, station::Station},
|
||||||
|
err,
|
||||||
|
partials::page,
|
||||||
|
pl, succ, AppState,
|
||||||
|
};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::State,
|
extract::State,
|
||||||
response::{IntoResponse, Redirect},
|
response::{IntoResponse, Redirect},
|
||||||
@ -497,7 +502,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
} @else {
|
} @else {
|
||||||
form action="/admin/team" method="post" {
|
form action="/admin/team" method="post" {
|
||||||
@if routes.len() == 1 {
|
@if routes.len() == 1 {
|
||||||
fieldset role="team" {
|
fieldset role="group" {
|
||||||
input type="text" name="name" placeholder="Teamnamen" required;
|
input type="text" name="name" placeholder="Teamnamen" required;
|
||||||
input type="hidden" name="route_id" value=(routes[0].id) ;
|
input type="hidden" name="route_id" value=(routes[0].id) ;
|
||||||
input type="submit" value="Neues Team";
|
input type="submit" value="Neues Team";
|
||||||
@ -519,7 +524,7 @@ async fn index(State(db): State<Arc<SqlitePool>>, session: Session) -> Markup {
|
|||||||
page(content, session, false).await
|
page(content, session, false).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn routes() -> Router<Arc<SqlitePool>> {
|
pub(super) fn routes() -> Router<AppState> {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/", get(index))
|
.route("/", get(index))
|
||||||
.route("/", post(create))
|
.route("/", post(create))
|
||||||
|
29
src/lib.rs
29
src/lib.rs
@ -4,12 +4,12 @@ extern crate rust_i18n;
|
|||||||
i18n!("locales", fallback = "de-AT");
|
i18n!("locales", fallback = "de-AT");
|
||||||
|
|
||||||
use admin::station::Station;
|
use admin::station::Station;
|
||||||
use axum::{body::Body, response::Response, routing::get, Router};
|
use axum::{body::Body, extract::FromRef, response::Response, routing::get, Router};
|
||||||
use partials::page;
|
use partials::page;
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
use tower_sessions::{MemoryStore, SessionManagerLayer};
|
use tower_sessions::{cookie::Key, MemoryStore, SessionManagerLayer};
|
||||||
|
|
||||||
pub(crate) mod admin;
|
pub(crate) mod admin;
|
||||||
mod partials;
|
mod partials;
|
||||||
@ -102,11 +102,34 @@ async fn serve_marker_png() -> Response<Body> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct AppState {
|
||||||
|
db: Arc<SqlitePool>,
|
||||||
|
key: Key,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromRef<AppState> for Key {
|
||||||
|
fn from_ref(state: &AppState) -> Self {
|
||||||
|
state.key.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromRef<AppState> for Arc<SqlitePool> {
|
||||||
|
fn from_ref(state: &AppState) -> Self {
|
||||||
|
state.db.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Starts the main application.
|
/// Starts the main application.
|
||||||
pub async fn start(listener: TcpListener, db: SqlitePool) {
|
pub async fn start(listener: TcpListener, db: SqlitePool) {
|
||||||
let session_store = MemoryStore::default();
|
let session_store = MemoryStore::default();
|
||||||
let session_layer = SessionManagerLayer::new(session_store);
|
let session_layer = SessionManagerLayer::new(session_store);
|
||||||
|
|
||||||
|
let state = AppState {
|
||||||
|
db: Arc::new(db),
|
||||||
|
key: Key::generate(),
|
||||||
|
};
|
||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.nest("/s", station::routes()) // TODO: maybe switch to "/"
|
.nest("/s", station::routes()) // TODO: maybe switch to "/"
|
||||||
.nest("/admin", admin::routes())
|
.nest("/admin", admin::routes())
|
||||||
@ -115,7 +138,7 @@ pub async fn start(listener: TcpListener, db: SqlitePool) {
|
|||||||
.route("/leaflet.css", get(serve_leaflet_css))
|
.route("/leaflet.css", get(serve_leaflet_css))
|
||||||
.route("/leaflet.js", get(serve_leaflet_js))
|
.route("/leaflet.js", get(serve_leaflet_js))
|
||||||
.route("/marker.png", get(serve_marker_png))
|
.route("/marker.png", get(serve_marker_png))
|
||||||
.with_state(Arc::new(db))
|
.with_state(state)
|
||||||
.layer(session_layer);
|
.layer(session_layer);
|
||||||
|
|
||||||
axum::serve(listener, app).await.unwrap();
|
axum::serve(listener, app).await.unwrap();
|
||||||
|
131
src/station.rs
131
src/station.rs
@ -1,12 +1,13 @@
|
|||||||
use crate::{err, partials, succ, Station};
|
use crate::{err, partials, succ, AppState, Station};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::State,
|
extract::State,
|
||||||
response::{IntoResponse, Redirect},
|
response::{IntoResponse, Redirect},
|
||||||
routing::get,
|
routing::{get, post},
|
||||||
Router,
|
Form, Router,
|
||||||
};
|
};
|
||||||
use axum_extra::extract::CookieJar;
|
use axum_extra::extract::{CookieJar, PrivateCookieJar};
|
||||||
use maud::{html, Markup, PreEscaped};
|
use maud::{html, Markup, PreEscaped};
|
||||||
|
use serde::Deserialize;
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tower_sessions::{cookie::Cookie, Session};
|
use tower_sessions::{cookie::Cookie, Session};
|
||||||
@ -91,8 +92,11 @@ async fn view(
|
|||||||
State(db): State<Arc<SqlitePool>>,
|
State(db): State<Arc<SqlitePool>>,
|
||||||
session: Session,
|
session: Session,
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
|
pjar: PrivateCookieJar,
|
||||||
axum::extract::Path(id): axum::extract::Path<i64>,
|
axum::extract::Path(id): axum::extract::Path<i64>,
|
||||||
) -> Result<(CookieJar, Markup), (CookieJar, impl IntoResponse)> {
|
) -> Result<(CookieJar, PrivateCookieJar, Markup), (CookieJar, PrivateCookieJar, impl IntoResponse)>
|
||||||
|
{
|
||||||
|
// Station selector
|
||||||
let (mut jar, current_station_cookie) = get_station_cookie(&db, jar).await;
|
let (mut jar, current_station_cookie) = get_station_cookie(&db, jar).await;
|
||||||
if current_station_cookie.is_none() {
|
if current_station_cookie.is_none() {
|
||||||
jar = jar.add(Cookie::new("station_id", id.to_string()));
|
jar = jar.add(Cookie::new("station_id", id.to_string()));
|
||||||
@ -106,6 +110,7 @@ async fn view(
|
|||||||
err!(session, "Du hast versucht eine neue Station zu öffnen obwohl du bereits eine andere Station offen hattest. Welche möchtest du nun verwenden?");
|
err!(session, "Du hast versucht eine neue Station zu öffnen obwohl du bereits eine andere Station offen hattest. Welche möchtest du nun verwenden?");
|
||||||
return Ok((
|
return Ok((
|
||||||
jar,
|
jar,
|
||||||
|
pjar,
|
||||||
decide_between_stations(¤t_station_cookie, &station, session).await,
|
decide_between_stations(¤t_station_cookie, &station, session).await,
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
@ -113,12 +118,27 @@ async fn view(
|
|||||||
err!(session, "Du hast versucht eine Station öffnen, die es nicht gibt. Nachdem du vorher schonmal eine andere Station (die es gibt) geöffnet hattest, bist du nun zu dieser weitergeleitet worden. Wenn du das nicht willst, logg dich bitte aus.");
|
err!(session, "Du hast versucht eine Station öffnen, die es nicht gibt. Nachdem du vorher schonmal eine andere Station (die es gibt) geöffnet hattest, bist du nun zu dieser weitergeleitet worden. Wenn du das nicht willst, logg dich bitte aus.");
|
||||||
return Err((
|
return Err((
|
||||||
jar,
|
jar,
|
||||||
|
pjar,
|
||||||
Redirect::to(&format!("/s/{}", current_station_cookie.id)),
|
Redirect::to(&format!("/s/{}", current_station_cookie.id)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let station = Station::find_by_id(&db, id).await.unwrap();
|
let station = Station::find_by_id(&db, id).await.unwrap();
|
||||||
|
|
||||||
|
let mut pjar = pjar;
|
||||||
|
|
||||||
|
// PW Checker
|
||||||
|
if let Some(pw) = pjar.get("pw") {
|
||||||
|
if pw.value() != station.pw {
|
||||||
|
pjar = pjar.remove(Cookie::from("station_id"));
|
||||||
|
err!(session, "Du hattest einen falschen Code für Station {} gespeichert. Bitte gibt den richtigen ein:", station.name );
|
||||||
|
return Err((jar, pjar, Redirect::to(&format!("/s/code",))));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err((jar, pjar, Redirect::to(&format!("/s/code",))));
|
||||||
|
}
|
||||||
|
|
||||||
let content = html! {
|
let content = html! {
|
||||||
nav {
|
nav {
|
||||||
ul {
|
ul {
|
||||||
@ -131,9 +151,75 @@ async fn view(
|
|||||||
h1 { "test" }
|
h1 { "test" }
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((jar, partials::page(content, session, false).await))
|
Ok((jar, pjar, partials::page(content, session, false).await))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn code(
|
||||||
|
State(db): State<Arc<SqlitePool>>,
|
||||||
|
session: Session,
|
||||||
|
jar: CookieJar,
|
||||||
|
pjar: PrivateCookieJar,
|
||||||
|
) -> Result<(CookieJar, PrivateCookieJar, Markup), (CookieJar, PrivateCookieJar, impl IntoResponse)>
|
||||||
|
{
|
||||||
|
let (jar, current_station_cookie) = get_station_cookie(&db, jar).await;
|
||||||
|
let Some(station) = current_station_cookie else {
|
||||||
|
return Err((jar, pjar, Redirect::to("/s")));
|
||||||
|
};
|
||||||
|
|
||||||
|
let content = html! {
|
||||||
|
nav {
|
||||||
|
ul {
|
||||||
|
li { strong { (format!("Station {}", station.name)) } }
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
li { a href="/s/station-logout" { "Station wechseln" } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h1 { "Code eingeben" }
|
||||||
|
form action="/s/station-login" method="post" {
|
||||||
|
fieldset role="group" {
|
||||||
|
input type="text" name="pw" placeholder="Code" required;
|
||||||
|
input type="submit" value="Login";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((jar, pjar, partials::page(content, session, false).await))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct LoginForm {
|
||||||
|
pw: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn login(
|
||||||
|
State(db): State<Arc<SqlitePool>>,
|
||||||
|
session: Session,
|
||||||
|
jar: CookieJar,
|
||||||
|
pjar: PrivateCookieJar,
|
||||||
|
Form(form): Form<LoginForm>,
|
||||||
|
) -> (CookieJar, PrivateCookieJar, impl IntoResponse) {
|
||||||
|
let (jar, current_station_cookie) = get_station_cookie(&db, jar).await;
|
||||||
|
let Some(station) = current_station_cookie else {
|
||||||
|
return (jar, pjar, Redirect::to("/s"));
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut pjar = pjar;
|
||||||
|
|
||||||
|
if form.pw == station.pw {
|
||||||
|
pjar = pjar.add(Cookie::new("pw", form.pw));
|
||||||
|
succ!(
|
||||||
|
session,
|
||||||
|
"Erfolgreich eingeloggt, viel Spaß beim bewerten :-)"
|
||||||
|
);
|
||||||
|
return (jar, pjar, Redirect::to(&format!("/s/{}", station.id)));
|
||||||
|
} else {
|
||||||
|
err!(session, "Falsches Passwort. Probiere es erneut.");
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
|
return (jar, pjar, Redirect::to("/s/code"));
|
||||||
|
}
|
||||||
|
}
|
||||||
async fn logout(session: Session, mut jar: CookieJar) -> (CookieJar, impl IntoResponse) {
|
async fn logout(session: Session, mut jar: CookieJar) -> (CookieJar, impl IntoResponse) {
|
||||||
jar = jar.remove(Cookie::from("station_id"));
|
jar = jar.remove(Cookie::from("station_id"));
|
||||||
|
|
||||||
@ -142,9 +228,40 @@ async fn logout(session: Session, mut jar: CookieJar) -> (CookieJar, impl IntoRe
|
|||||||
(jar, Redirect::to("/s"))
|
(jar, Redirect::to("/s"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn routes() -> Router<Arc<SqlitePool>> {
|
async fn quick_login(
|
||||||
|
State(db): State<Arc<SqlitePool>>,
|
||||||
|
session: Session,
|
||||||
|
jar: CookieJar,
|
||||||
|
pjar: PrivateCookieJar,
|
||||||
|
axum::extract::Path((id, code)): axum::extract::Path<(i64, String)>,
|
||||||
|
) -> (CookieJar, PrivateCookieJar, impl IntoResponse) {
|
||||||
|
if let Some(station) = Station::find_by_id(&db, id).await {
|
||||||
|
if station.pw == code {
|
||||||
|
succ!(
|
||||||
|
session,
|
||||||
|
"Erfolgreich eingeloggt, viel Spaß beim bewerten :-)"
|
||||||
|
);
|
||||||
|
let mut pjar = pjar.remove(Cookie::from("pw"));
|
||||||
|
let mut jar = jar.remove(Cookie::from("station_id"));
|
||||||
|
jar = jar.add(Cookie::new("station_id", id.to_string()));
|
||||||
|
pjar = pjar.add(Cookie::new("pw", code));
|
||||||
|
|
||||||
|
return (jar, pjar, Redirect::to(&format!("/s/{id}")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err!(
|
||||||
|
session,
|
||||||
|
"Falscher Quick-Einlogg-Link. Bitte nochmal scannen oder deine Station manuell auswählen:"
|
||||||
|
);
|
||||||
|
return (jar, pjar, Redirect::to("/s"));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn routes() -> Router<AppState> {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/", get(station_picker))
|
.route("/", get(station_picker))
|
||||||
.route("/{id}", get(view))
|
.route("/{id}", get(view))
|
||||||
|
.route("/code", get(code))
|
||||||
|
.route("/{id}/{code}", get(quick_login))
|
||||||
|
.route("/station-login", post(login))
|
||||||
.route("/station-logout", get(logout))
|
.route("/station-logout", get(logout))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user