Actually hashed passwords

This commit is contained in:
Yash Karandikar 2022-08-13 15:19:39 -05:00
parent fa92459b96
commit 6d20e0757b
4 changed files with 48 additions and 2 deletions

30
Cargo.lock generated
View file

@ -114,6 +114,12 @@ version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "base64ct"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bdca834647821e0b13d9539a8634eb62d3501b6b6c2cec1722786ee6671b851"
[[package]]
name = "bitflags"
version = "1.3.2"
@ -831,12 +837,35 @@ dependencies = [
"regex",
]
[[package]]
name = "password-hash"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
dependencies = [
"base64ct",
"rand_core",
"subtle",
]
[[package]]
name = "paste"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9423e2b32f7a043629287a536f21951e8c6a82482d0acb1eeebfc90bc2225b22"
[[package]]
name = "pbkdf2"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
dependencies = [
"digest",
"hmac",
"password-hash",
"sha2",
]
[[package]]
name = "percent-encoding"
version = "2.1.0"
@ -1436,6 +1465,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"axum",
"pbkdf2",
"serde",
"sqlx",
"tera",

View file

@ -8,6 +8,7 @@ edition = "2021"
[dependencies]
anyhow = "1.0.61"
axum = "0.5.15"
pbkdf2 = "0.11.0"
serde = { version = "1.0.143", features = ["derive"] }
sqlx = { version = "0.6.1", features = ["runtime-tokio-rustls", "postgres"] }
tera = "1.16.0"

View file

@ -18,7 +18,7 @@ async fn main() -> anyhow::Result<()> {
.await?,
);
sqlx::query("create table if not exists users(id serial primary key, username text not null, password_hash text not null)").execute(&*pool).await?;
sqlx::query("create table if not exists users(id serial primary key, username text not null unique, password_hash text not null)").execute(&*pool).await?;
let mut tera = Arc::new(Tera::new("templates/**/*.html")?);

View file

@ -2,6 +2,10 @@ use axum::extract::Extension;
use axum::extract::Form;
use axum::response::Html;
use axum::response::Redirect;
use pbkdf2::{
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
Pbkdf2,
};
use serde::Deserialize;
use sqlx::{Pool, Postgres};
use std::sync::Arc;
@ -18,9 +22,20 @@ pub async fn create_user(
Form(data): Form<RawUser>,
Extension(pool): Extension<Arc<Pool<Postgres>>>,
) -> Result<Redirect, String> {
let handle = tokio::task::spawn_blocking(move || {
let salt = SaltString::generate(&mut OsRng);
let password_hash = Pbkdf2.hash_password(data.password.as_bytes(), &salt);
password_hash
.map(|p| p.to_string())
.map_err(|e| e.to_string())
});
let hash = handle.await.map_err(|e| e.to_string())??;
sqlx::query("INSERT INTO users (username, password_hash) VALUES ($1, $2)")
.bind(data.username)
.bind(data.password)
.bind(hash)
.execute(&*pool)
.await
.map_err(|e| e.to_string())?;