Sign up/in/out and authentication.
[recipes.git] / backend / src / hash.rs
index 3dd45a9..ecdaf45 100644 (file)
@@ -13,4 +13,34 @@ pub fn hash(password: &str) -> Result<String, Box<dyn std::error::Error>> {
     let salt = SaltString::generate(&mut OsRng);
     let argon2 = Argon2::default();
     argon2.hash_password(password.as_bytes(), &salt).map(|h| h.to_string()).map_err(|e| e.into())
+}
+
+pub fn verify_password(password: &str, hashed_password: &str) -> Result<bool, Box<dyn std::error::Error>> {
+    let argon2 = Argon2::default();
+    let parsed_hash = PasswordHash::new(hashed_password)?;
+    Ok(argon2.verify_password(password.as_bytes(), &parsed_hash).is_ok())
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn simple_case() -> Result<(), Box<dyn std::error::Error>> {
+        let password = "12345";
+        let hash = hash(password)?;
+        println!("hash: {}", &hash);
+        assert!(verify_password(password, &hash)?);
+        assert!(!verify_password("54321", &hash)?);
+        Ok(())
+    }
+
+    #[test]
+    fn password_with_special_characters() -> Result<(), Box<dyn std::error::Error>> {
+        let password = "éà ä_\\😺🎮🇨🇭";
+        let hash = hash(password)?;
+        println!("hash: {}", &hash);
+        assert!(verify_password(password, &hash)?);
+        Ok(())
+    }
 }
\ No newline at end of file