use crate::logic::user::{AuthData, BcryptPassword, PasswordAuth};
use bcrypt::{hash_with_salt, verify, BcryptResult, DEFAULT_COST};
pub fn new_auth(acct: &str, password: &str) -> anyhow::Result<AuthData> {
let hashed = bcrypted_pw(acct, password)?;
let bcrypt_password = BcryptPassword {
crypted_password: hashed,
};
let auth_data = AuthData {
password_auth: PasswordAuth::BcryptPassword(bcrypt_password),
};
Ok(auth_data)
}
pub fn bcrypted_pw(acct: &str, password: &str) -> BcryptResult<String> {
let salt = md5::compute(acct.as_bytes());
let pw = hash_with_salt(password, DEFAULT_COST, salt.0)?;
Ok(pw.to_string())
}
pub fn verify_auth(password: &str, auth_data: &AuthData) -> anyhow::Result<bool> {
match &auth_data.password_auth {
PasswordAuth::BcryptPassword(bauth) => Ok(verify(password, &bauth.crypted_password)?),
}
}
#[cfg(test)]
mod auth_tests {
use super::{new_auth, verify_auth};
use crate::logic::user::auth::bcrypted_pw;
use bcrypt::{hash_with_salt, verify, DEFAULT_COST};
#[test]
fn test_bcrypt_auth() {
let a = "test@foo.example";
let p = "secretpassword";
let auth_data = new_auth(a, p).unwrap();
let verified = verify_auth(p, &auth_data).unwrap();
assert!(verified)
}
#[test]
fn test_multiple_auths() {
let a = "test@foo.example";
let p = "secretpassword";
let p1 = bcrypted_pw(a, p).unwrap();
println!("p1 = {}", p1);
assert!(verify(p, &p1).unwrap());
let p2 = bcrypted_pw(a, p).unwrap();
println!("p2 = {}", p2);
assert!(verify(p, &p2).unwrap());
assert_eq!(p1, p2);
}
#[test]
fn test_multiple_hashes() {
let salt: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
let p = "secretpassword";
let p1 = hash_with_salt(p, DEFAULT_COST, salt).unwrap().to_string();
assert!(verify(p, &p1).unwrap());
let p2 = hash_with_salt(p, DEFAULT_COST, salt).unwrap().to_string();
assert!(verify(p, &p2).unwrap());
assert_eq!(p1, p2);
}
}