HomeDisk/src/database/user.rs

94 lines
2.4 KiB
Rust

use crypto_utils::sha::{Algorithm, CryptographicHash};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// SQL user entry
#[derive(Debug, Serialize, Deserialize)]
pub struct User {
pub id: String,
pub username: String,
pub password: String,
}
impl User {
/// The function create a unique UUID and compute SHA-512 hash from salted user password
/// and returns the [User] type.
///
/// **Note**: This function **does not** create a user in database!
pub fn new(username: &str, password: &str, gen_uuid: bool) -> Self {
// change username to lowercase
let username = username.to_lowercase();
// salting the password
let password = format!("{username}${password}");
// hash the password using SHA-512 algorithm and encode it into String.
let password = hex::encode(CryptographicHash::hash(
Algorithm::SHA512,
password.as_bytes(),
));
// generate UUID
let id = if gen_uuid {
Uuid::new_v4().to_string()
} else {
"none".to_string()
};
Self {
id,
username,
password,
}
}
/// The function returns the directory where the user files is located.
pub fn user_dir(&self, storage: &str) -> String {
format!("{storage}/{username}", username = self.username)
}
}
#[cfg(test)]
mod tests {
use super::*;
/// Check if the username is in lowercase.
#[test]
fn test_username_is_lowercase() {
// example user data
let username = "MeDZiK";
let password = "password";
// expected username
let username_expected = "medzik";
let user = User::new(username, password, false);
// username validation
assert_eq!(user.username, username_expected)
}
/// Check if the password is hashed.
#[test]
fn test_password_hashed() {
// example user data
let username = "username";
let password = "password";
let user = User::new(username, password, false);
assert_ne!(user.password, password)
}
#[test]
fn test_user_dir() {
let storage_dir: &str = "/storage";
let user = User::new("medzik", "whatever", false);
let user_dir = user.user_dir(storage_dir);
assert_eq!(user_dir, "/storage/medzik");
}
}