Skip to content

Commit 7c24a31

Browse files
committed
avoid blocking request handling while checking passwords
1 parent f2c68da commit 7c24a31

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

src/render.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl<W: std::io::Write> HeaderContext<W> {
5151
Some("redirect") => self.redirect(&data).map(PageContext::Close),
5252
Some("json") => self.json(&data).map(PageContext::Close),
5353
Some("cookie") => self.add_cookie(&data).map(PageContext::Header),
54-
Some("authentication") => self.authentication(&data),
54+
Some("authentication") => self.authentication(&data).await,
5555
_ => self.start_body(data).await,
5656
}
5757
}
@@ -167,18 +167,17 @@ impl<W: std::io::Write> HeaderContext<W> {
167167
Ok(self.response.body(json_response))
168168
}
169169

170-
fn authentication(mut self, data: &JsonValue) -> anyhow::Result<PageContext<W>> {
171-
use argon2::Argon2;
172-
use password_hash::PasswordHash;
170+
async fn authentication(mut self, data: &JsonValue) -> anyhow::Result<PageContext<W>> {
173171
let password_hash = get_object_str(data, "password_hash");
174172
let password = get_object_str(data, "password");
175173
if let (Some(password), Some(password_hash)) = (password, password_hash) {
176-
match PasswordHash::new(password_hash)
177-
.map_err(|e| {
178-
anyhow::anyhow!("invalid value for the password_hash property: {}", e)
179-
})?
180-
.verify_password(&[&Argon2::default()], password)
181-
{
174+
log::debug!(
175+
"Authenticating user with password_hash = {:?}",
176+
password_hash
177+
);
178+
let verif_result =
179+
tokio::task::block_in_place(move || verify_password_sync(password_hash, password))?;
180+
match verif_result {
182181
Ok(()) => return Ok(PageContext::Header(self)),
183182
Err(e) => log::info!("User authentication failed: {}", e),
184183
}
@@ -219,6 +218,16 @@ impl<W: std::io::Write> HeaderContext<W> {
219218
}
220219
}
221220

221+
fn verify_password_sync(
222+
password_hash: &str,
223+
password: &str,
224+
) -> Result<Result<(), password_hash::Error>, anyhow::Error> {
225+
let hash = password_hash::PasswordHash::new(password_hash)
226+
.map_err(|e| anyhow::anyhow!("invalid value for the password_hash property: {}", e))?;
227+
let phfs = &[&argon2::Argon2::default() as &dyn password_hash::PasswordVerifier];
228+
Ok(hash.verify_password(phfs, password))
229+
}
230+
222231
fn get_backtrace(error: &anyhow::Error) -> Vec<String> {
223232
let mut backtrace = vec![];
224233
let mut source = error.source();

src/webserver/database/sql_pseudofunctions.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,13 @@ fn random_string(len: usize) -> String {
8585
}
8686

8787
fn hash_password(password: &str) -> anyhow::Result<String> {
88-
let phf = argon2::Argon2::default();
89-
let salt = password_hash::SaltString::generate(&mut password_hash::rand_core::OsRng);
90-
let password_hash = &password_hash::PasswordHash::generate(phf, password, &salt)
91-
.map_err(|e| anyhow!("Unable to hash password: {}", e))?;
92-
Ok(password_hash.to_string())
88+
tokio::task::block_in_place(|| {
89+
let phf = argon2::Argon2::default();
90+
let salt = password_hash::SaltString::generate(&mut password_hash::rand_core::OsRng);
91+
let password_hash = &password_hash::PasswordHash::generate(phf, password, &salt)
92+
.map_err(|e| anyhow!("Unable to hash password: {}", e))?;
93+
Ok(password_hash.to_string())
94+
})
9395
}
9496

9597
fn extract_basic_auth_username(request: &RequestInfo) -> anyhow::Result<&str> {

0 commit comments

Comments
 (0)