feat: async even for verify

This commit is contained in:
EETagent 2022-10-28 11:08:35 +02:00
parent 1d5352a168
commit 0636a92b01

View file

@ -1,10 +1,9 @@
use futures::io::{AsyncReadExt, AsyncWriteExt};
use argon2::{ use argon2::{
Argon2, PasswordHasher as ArgonPasswordHasher, PasswordVerifier as ArgonPasswordVerifier, Argon2, PasswordHasher as ArgonPasswordHasher, PasswordVerifier as ArgonPasswordVerifier,
}; };
use futures::io::{AsyncReadExt, AsyncWriteExt};
use rand::Rng; use rand::Rng;
/// Foolproof random 8 char string /// Foolproof random 8 char string
/// only uppercase letters (except for 0 and O) and numbers /// only uppercase letters (except for 0 and O) and numbers
/// TODO tests /// TODO tests
@ -13,13 +12,10 @@ pub fn random_8_char_string() -> String {
.sample_iter(&rand::distributions::Alphanumeric) .sample_iter(&rand::distributions::Alphanumeric)
.map(char::from); .map(char::from);
let mut s = String::new(); let mut s = String::new();
for c in iterator { // add all characters except for: lowercase chars, 0 and O for c in iterator {
if ('1'..='9').contains(&c) || // add all characters except for: lowercase chars, 0 and O
('A'..='N').contains(&c) || if ('1'..='9').contains(&c) || ('A'..='N').contains(&c) || ('P'..'Z').contains(&c) {
('P'..'Z').contains(&c)
{
s.push(c); s.push(c);
if s.len() == 8 { if s.len() == 8 {
break; break;
@ -29,7 +25,10 @@ pub fn random_8_char_string() -> String {
s s
} }
pub async fn hash_password(password_plaint_text: String) -> Result<String, argon2::password_hash::Error> { // TODO: No unwrap for spawn_blocking
pub async fn hash_password(
password_plaint_text: String,
) -> Result<String, argon2::password_hash::Error> {
let argon_config = Argon2::default(); let argon_config = Argon2::default();
let hash = tokio::task::spawn_blocking(move || { let hash = tokio::task::spawn_blocking(move || {
@ -38,20 +37,50 @@ pub async fn hash_password(password_plaint_text: String) -> Result<String, argon
let encrypted = argon_config.hash_password(password, salt); let encrypted = argon_config.hash_password(password, salt);
encrypted encrypted
}).await; })
.await.unwrap();
let result = hash.unwrap()?; let result = hash?;
return Ok(result.to_string()); return Ok(result.to_string());
} }
pub async fn encrypt_password(password_plaint_text: &str, key: &str) -> Result<String, age::EncryptError> { // TODO: No unwrap for spawn_blocking
pub async fn verify_password<'a>(
password_plaint_text: String,
hash: String,
) -> Result<bool, argon2::password_hash::Error> {
let argon_config = Argon2::default();
let result: Result<bool, argon2::password_hash::Error> = tokio::task::spawn_blocking(move || {
let parsed_hash = argon2::PasswordHash::new(&hash);
match parsed_hash {
Ok(parsed) => {
return Ok(argon_config
.verify_password(password_plaint_text.as_bytes(), &parsed)
.is_ok())
}
Err(error) => return Err(error),
}
})
.await
.unwrap();
result
}
pub async fn encrypt_password(
password_plaint_text: &str,
key: &str,
) -> Result<String, age::EncryptError> {
let encryptor = age::Encryptor::with_user_passphrase(age::secrecy::Secret::new(key.to_owned())); let encryptor = age::Encryptor::with_user_passphrase(age::secrecy::Secret::new(key.to_owned()));
let mut encrypt_buffer = Vec::new(); let mut encrypt_buffer = Vec::new();
let mut encrypt_writer = encryptor.wrap_async_output(&mut encrypt_buffer).await?; let mut encrypt_writer = encryptor.wrap_async_output(&mut encrypt_buffer).await?;
encrypt_writer.write_all(password_plaint_text.as_bytes()).await?; encrypt_writer
.write_all(password_plaint_text.as_bytes())
.await?;
encrypt_writer.flush().await?; encrypt_writer.flush().await?;
@ -72,22 +101,10 @@ pub async fn decrypt_password(
}; };
let mut decrypt_buffer = Vec::new(); let mut decrypt_buffer = Vec::new();
let mut decrypt_writer = decryptor.decrypt_async(&age::secrecy::Secret::new(key.to_owned()), None)?; let mut decrypt_writer =
decryptor.decrypt_async(&age::secrecy::Secret::new(key.to_owned()), None)?;
decrypt_writer.read_to_end(&mut decrypt_buffer).await?; decrypt_writer.read_to_end(&mut decrypt_buffer).await?;
Ok(String::from_utf8(decrypt_buffer)?) Ok(String::from_utf8(decrypt_buffer)?)
} }
pub fn verify_password(
password_plaint_text: &str,
hash: &str,
) -> Result<bool, argon2::password_hash::Error> {
let argon_config = Argon2::default();
let parsed_hash = argon2::PasswordHash::new(&hash)?;
return Ok(argon_config
.verify_password(password_plaint_text.as_bytes(), &parsed_hash)
.is_ok());
}