diff options
-rw-r--r-- | Cargo.lock | 2 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/controller/login.rs | 7 | ||||
-rw-r--r-- | src/utils/cookie.rs | 15 |
4 files changed, 18 insertions, 8 deletions
@@ -161,6 +161,8 @@ dependencies = [ "hmac", "hyper", "log", + "rand", + "rand_core", "serde", "serde_json", "serde_urlencoded", @@ -13,6 +13,8 @@ hmac = "0.12" hex = "0.4" hyper = { version = "0.14", features = ["full"] } log = "0.4" +rand = { version = "0.8", features = ["getrandom"] } +rand_core = "0.6.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_urlencoded = "0.7" diff --git a/src/controller/login.rs b/src/controller/login.rs index 9757c25..036e6fc 100644 --- a/src/controller/login.rs +++ b/src/controller/login.rs @@ -4,7 +4,6 @@ use hyper::{Body, Response}; use sqlx::sqlite::SqlitePool; use std::collections::HashMap; use tera::{Context, Tera}; -use uuid::Uuid; use crate::controller::utils::with_headers; use crate::controller::wallet::Wallet; @@ -29,7 +28,6 @@ pub async fn page( utils::template(assets, templates, "login.html", context) } -// TODO rewrite pub async fn login( config: &Config, assets: &HashMap<String, String>, @@ -43,8 +41,7 @@ pub async fn login( { Some(hash) => match bcrypt::verify(login.password, &hash) { Ok(true) => { - // TODO generate truly random instead of uuid - let login_token = Uuid::new_v4(); + let login_token = cookie::generate_token(); if db::users::set_login_token( &pool, @@ -53,7 +50,7 @@ pub async fn login( ) .await { - match cookie::login(config, login_token) { + match cookie::login(config, &login_token) { Ok(str) => with_headers( utils::redirect("/"), vec![(SET_COOKIE, &str)], diff --git a/src/utils/cookie.rs b/src/utils/cookie.rs index c716936..826efa9 100644 --- a/src/utils/cookie.rs +++ b/src/utils/cookie.rs @@ -1,10 +1,13 @@ -use uuid::Uuid; +use hex; +use rand_core::{OsRng, RngCore}; use crate::crypto::signed; use crate::model::config::Config; -pub fn login(config: &Config, token: Uuid) -> Result<String, String> { - let signed_token = signed::sign(&config.auth_secret, &token.to_string())?; +const TOKEN_BYTES: usize = 20; + +pub fn login(config: &Config, token: &str) -> Result<String, String> { + let signed_token = signed::sign(&config.auth_secret, token)?; Ok(cookie(config, &signed_token, 24 * 60 * 60)) } @@ -19,6 +22,12 @@ pub fn extract_token(config: &Config, cookie: &str) -> Result<String, String> { signed::verify(&config.auth_secret, signed_cookie) } +pub fn generate_token() -> String { + let mut token = [0u8; TOKEN_BYTES]; + OsRng.fill_bytes(&mut token); + hex::encode(token) +} + fn cookie(config: &Config, token: &str, max_age_seconds: i32) -> String { let mut xs = vec![ format!("TOKEN={token}"), |