8002ac735ed13429a25f9a5d7e774a5704e17db9
[recipes.git] / backend / src / hash.rs
1 use std::{string::String};
2
3 use argon2::{
4 password_hash::{
5 rand_core::OsRng,
6 PasswordHash, PasswordHasher, PasswordVerifier, SaltString
7 },
8 Argon2
9 };
10
11 pub fn hash(password: &str) -> Result<String, Box<dyn std::error::Error>> {
12 let salt = SaltString::generate(&mut OsRng);
13 let argon2 = Argon2::default();
14 argon2.hash_password(password.as_bytes(), &salt).map(|h| h.to_string()).map_err(|e| e.into())
15 }
16
17 pub fn verify_password(password: &str, hashed_password: &str) -> Result<bool, Box<dyn std::error::Error>> {
18 let argon2 = Argon2::default();
19 let parsed_hash = PasswordHash::new(hashed_password)?;
20 Ok(argon2.verify_password(password.as_bytes(), &parsed_hash).is_ok())
21 }
22
23 #[cfg(test)]
24 mod test {
25 use super::*;
26
27 #[test]
28 fn simple_case() -> Result<(), Box<dyn std::error::Error>> {
29 let password = "12345";
30 let hash = hash(password)?;
31 println!("hash: {}", &hash);
32 assert!(verify_password(password, &hash)?);
33 assert!(!verify_password("54321", &hash)?);
34 Ok(())
35 }
36
37 #[test]
38 fn password_with_special_characters() -> Result<(), Box<dyn std::error::Error>> {
39 let password = "éà ä_\\😺🎮🇨🇭";
40 let hash = hash(password)?;
41 println!("hash: {}", &hash);
42 assert!(verify_password(password, &hash)?);
43 Ok(())
44 }
45 }