diff --git a/Cargo.lock b/Cargo.lock index 20462ab..7fea9cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1267,6 +1267,16 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-bigint-dig" version = "0.8.4" @@ -1335,6 +1345,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking" version = "2.2.1" @@ -1924,6 +1940,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -2213,6 +2238,7 @@ dependencies = [ "tower-sessions", "tower-sessions-sqlx-store-chrono", "tracing", + "tracing-subscriber", ] [[package]] @@ -2293,6 +2319,16 @@ dependencies = [ "syn", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "time" version = "0.3.41" @@ -2562,6 +2598,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", ] [[package]] @@ -2655,6 +2717,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "vcpkg" version = "0.2.15" @@ -2784,6 +2852,22 @@ dependencies = [ "wasite", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.9" @@ -2793,6 +2877,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.61.0" diff --git a/Cargo.toml b/Cargo.toml index f53f874..906f47d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ thiserror = "2.0" async-trait = "0.1" password-auth = "1.0" tower-sessions-sqlx-store-chrono = { version = "0.14", features = ["sqlite"] } +tracing-subscriber = "0.3" [dev-dependencies] diff --git a/seeds.sql b/seeds.sql new file mode 100644 index 0000000..c0d3260 --- /dev/null +++ b/seeds.sql @@ -0,0 +1 @@ +insert into user(name, pw) values('a', '$argon2i$v=19$m=16,t=2,p=1$b2lmaG9pMzJvNDk$vXbHg45vkuMrQaP0XY184Q'); // pw = 123 diff --git a/src/admin/mod.rs b/src/admin/mod.rs index 8e73ba1..4cade01 100644 --- a/src/admin/mod.rs +++ b/src/admin/mod.rs @@ -11,6 +11,9 @@ pub(crate) mod team; async fn index(session: Session) -> Markup { let content = html! { h1 { (t!("app_name")) } + a href="/auth/logout" { + "Ausloggen" + } nav { ul { li { diff --git a/src/auth.rs b/src/auth.rs index 88fc5d4..7ff9729 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -19,14 +19,13 @@ pub type UserId = <::User as AuthUser>::Id; pub struct User { id: i64, name: String, - password: String, + pw: String, } #[derive(Debug, Clone, Deserialize)] pub struct Credentials { pub name: String, pub password: String, - pub next: Option, } impl AuthUser for User { @@ -37,7 +36,7 @@ impl AuthUser for User { } fn session_auth_hash(&self) -> &[u8] { - &self.password.as_bytes() + &self.pw.as_bytes() } } @@ -69,18 +68,18 @@ impl AuthnBackend for Backend { creds: Self::Credentials, ) -> Result, Self::Error> { let user: Option = - sqlx::query_as("select id, name, pw from user where name = ? ") + sqlx::query_as("SELECT id, name, pw FROM user WHERE name = ? ") .bind(creds.name) .fetch_optional(&self.db) .await?; // We're using password-based authentication--this works by comparing our form // input with an argon2 password hash. - Ok(user.filter(|user| verify_password(creds.password, &user.password).is_ok())) + Ok(user.filter(|user| verify_password(creds.password, &user.pw).is_ok())) } async fn get_user(&self, user_id: &UserId) -> Result, Self::Error> { - let user = sqlx::query_as("select id, name, pw from user where id = ?") + let user = sqlx::query_as("SELECT id, name, pw FROM user WHERE id = ?") .bind(user_id) .fetch_optional(&self.db) .await?; @@ -101,11 +100,22 @@ pub fn routes() -> Router { async fn login(session: Session) -> Markup { let content = html! { h1 { "Login" } + form action="/auth/login" method="post" { + label { + "Name" + input type="text" name="name"; + } + label { + "Passwort" + input type="password" name="password"; + } + input type="submit" value="Einloggen"; + } }; // TODO: generate okayish looking login page - page(content, session, false) + page(content, session, false).await } pub async fn login_post( @@ -118,12 +128,7 @@ pub async fn login_post( Ok(None) => { err!(session, "Invalid credentials"); - let mut login_url = "/auth/login".to_string(); - if let Some(next) = creds.next { - login_url = format!("{login_url}?next={next}"); - }; - - return Redirect::to(&login_url).into_response(); + return Redirect::to("/auth/login").into_response(); } Err(_) => return StatusCode::INTERNAL_SERVER_ERROR.into_response(), }; @@ -134,12 +139,7 @@ pub async fn login_post( succ!(session, "Successfully logged in as {}", user.name); - if let Some(ref next) = creds.next { - Redirect::to(next) - } else { - Redirect::to("/") - } - .into_response() + Redirect::to("/admin").into_response() } pub async fn logout(mut auth_session: AuthSession) -> impl IntoResponse { diff --git a/src/main.rs b/src/main.rs index 90e2894..ee2fd9d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,17 @@ use dotenv::dotenv; -use sqlx::{SqlitePool, pool::PoolOptions}; +use sqlx::{pool::PoolOptions, SqlitePool}; use std::env; +use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; #[tokio::main] async fn main() { dotenv().ok(); // load .env variables + // Logging + tracing_subscriber::registry() + .with(tracing_subscriber::fmt::layer()) + .init(); + // DB let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); let db: SqlitePool = PoolOptions::new().connect(&database_url).await.unwrap(); diff --git a/test_db.sh b/test_db.sh index 4237272..f348f15 100755 --- a/test_db.sh +++ b/test_db.sh @@ -3,4 +3,5 @@ rm -f db.sqlite touch db.sqlite sqlite3 db.sqlite < migration.sql +sqlite3 db.sqlite < seeds.sql