use std::collections::HashMap;
use crate::auth::user::{HashingMethod, User};
use crate::proxy_error::ProxyResult;
use std::fs::File;
pub struct UserAuthenticator {
users: HashMap<String, User>,
}
impl UserAuthenticator {
pub fn new(path: impl ToString) -> ProxyResult<Self> {
Ok(Self {
users: Self::get_users(path)?,
})
}
pub fn validate_credentials(&self, username: String, password: String) -> bool {
if !self.users.contains_key(&username) {
return false;
}
let user = self.users.get(&username).unwrap();
match &user.hashing_method {
HashingMethod::BCrypt => self.validate_bcrypt(password, user.password.clone()),
HashingMethod::Plaintext => self.validate_plaintext(password, user.password.clone()),
}
}
fn validate_bcrypt(&self, password: String, hash: String) -> bool {
match bcrypt::verify(password, hash.as_str()) {
Ok(valid) => valid,
Err(_) => false,
}
}
fn validate_plaintext(&self, password: String, user_password: String) -> bool {
password == user_password
}
fn get_users(path: impl ToString) -> ProxyResult<HashMap<String, User>> {
let cwd = std::env::current_dir().unwrap();
let users_file = File::open(cwd.join(path.to_string()))?;
let users: Vec<User> = serde_yaml::from_reader(users_file)?;
let mut users_map: HashMap<String, User> = Default::default();
for user in users {
users_map.insert(user.name.clone(), user);
}
Ok(users_map)
}
}