Split up MasterPass::verify into 2 functions: MasterPass::get and master_pass::Model::verify, refactored check_master_pass
This commit is contained in:
parent
1fb004f949
commit
e39762916d
@ -1,7 +1,6 @@
|
||||
use rand::{rngs::OsRng, RngCore};
|
||||
use scrypt::{scrypt, Params};
|
||||
use sea_orm::{entity::prelude::*, ActiveValue::Set, QuerySelect};
|
||||
use tokio::task::spawn_blocking;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
||||
#[sea_orm(table_name = "master_pass")]
|
||||
@ -28,6 +27,14 @@ fn hash_password(password: &[u8], salt: &[u8]) -> crate::Result<Vec<u8>> {
|
||||
Ok(password_hash)
|
||||
}
|
||||
|
||||
impl Model {
|
||||
/// Checks that the given password hash matches the one of the model
|
||||
pub fn verify(&self, password: &str) -> crate::Result<bool> {
|
||||
let hashed = hash_password(password.as_bytes(), &self.salt)?;
|
||||
Ok(hashed == self.password_hash)
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModel {
|
||||
/// Hashes the password and creates an ActiveModel with all fields set to Set variant
|
||||
#[inline]
|
||||
@ -44,21 +51,10 @@ impl ActiveModel {
|
||||
}
|
||||
|
||||
impl Entity {
|
||||
/// Verifies the provided master password against the one from DB
|
||||
/// Gets the master password from the database
|
||||
#[inline]
|
||||
pub async fn verify_master_pass(
|
||||
user_id: u64,
|
||||
master_pass: String,
|
||||
db: &DatabaseConnection,
|
||||
) -> crate::Result<Option<bool>> {
|
||||
let model = match Self::find_by_id(user_id).one(db).await? {
|
||||
Some(model) => model,
|
||||
None => return Ok(None),
|
||||
};
|
||||
let salt = model.salt;
|
||||
let password_hash =
|
||||
spawn_blocking(move || hash_password(master_pass.as_bytes(), &salt)).await??;
|
||||
Ok(Some(password_hash == model.password_hash))
|
||||
pub async fn get(user_id: u64, db: &DatabaseConnection) -> crate::Result<Option<Model>> {
|
||||
Self::find_by_id(user_id).one(db).await.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Checks if the master password for the user exists
|
||||
@ -75,7 +71,7 @@ impl Entity {
|
||||
|
||||
/// Removes a master password of the user from the database
|
||||
pub async fn remove(user_id: u64, db: &DatabaseConnection) -> crate::Result<()> {
|
||||
Self::delete_by_id(user_id).exec(db)?;
|
||||
Self::delete_by_id(user_id).exec(db).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ use crate::{
|
||||
};
|
||||
use sea_orm::prelude::*;
|
||||
use teloxide::{adaptors::Throttle, prelude::*};
|
||||
use tokio::task::spawn_blocking;
|
||||
|
||||
/// Returns true if the provided master password is valid
|
||||
#[inline]
|
||||
@ -15,23 +16,25 @@ pub async fn check_master_pass<'a>(
|
||||
master_pass: &'a str,
|
||||
) -> crate::Result<bool> {
|
||||
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
||||
let result = MasterPass::verify_master_pass(user_id, master_pass.to_owned(), db).await;
|
||||
match result {
|
||||
Ok(Some(true)) => Ok(true),
|
||||
Ok(Some(false)) => {
|
||||
bot.send_message(msg.chat.id, "Wrong master password")
|
||||
.reply_markup(deletion_markup())
|
||||
.await?;
|
||||
Ok(false)
|
||||
let model = MasterPass::get(user_id, db).await?;
|
||||
let is_valid = match model {
|
||||
Some(model) => {
|
||||
let master_pass = master_pass.to_owned();
|
||||
spawn_blocking(move || model.verify(&master_pass)).await??
|
||||
}
|
||||
Ok(None) => {
|
||||
None => {
|
||||
bot.send_message(msg.chat.id, "No master password set")
|
||||
.reply_markup(deletion_markup())
|
||||
.await?;
|
||||
Ok(false)
|
||||
return Ok(false);
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
};
|
||||
if !is_valid {
|
||||
bot.send_message(msg.chat.id, "Wrong master password")
|
||||
.reply_markup(deletion_markup())
|
||||
.await?;
|
||||
}
|
||||
Ok(is_valid)
|
||||
}
|
||||
|
||||
pub async fn get_master_pass(
|
||||
|
Loading…
Reference in New Issue
Block a user