new-home-proxy 0.1.2

This is a part of the New Home IoT System. It is used to make the core available in the www.
use std::collections::HashMap;

use crate::auth::user::{HashingMethod, User};
use crate::proxy_error::ProxyResult;
use std::fs::File;

///
/// Used to validate the username and password in the client
///
pub struct UserAuthenticator {
    users: HashMap<String, User>,
}

impl UserAuthenticator {
    pub fn new(path: impl ToString) -> ProxyResult<Self> {
        Ok(Self {
            users: Self::get_users(path)?,
        })
    }

    /// Validates the given client credentials.
    ///
    /// # Return
    ///
    /// - true: when the given credentials are valid
    /// - false: when the given credentials are invalid
    ///
    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)
    }
}