support_kit/encryption/
password_control.rs1use crate::{Configuration, Environment, PasswordError};
2use argon2::{password_hash::SaltString, Argon2, Params, PasswordHasher, PasswordVerifier};
3
4pub struct PasswordControl {
5 params: Params,
6}
7
8impl PasswordControl {
9 pub fn test() -> Self {
10 let params = Params::new(8, 1, 1, Some(32)).unwrap();
11 Self { params }
12 }
13
14 pub fn from_config(config: Configuration) -> Self {
15 if let Some(Environment::Test) = config.environment {
16 Self::test()
17 } else {
18 Self::default()
19 }
20 }
21
22 pub fn hasher(&self) -> Argon2<'static> {
23 Argon2::new(
24 argon2::Algorithm::Argon2id,
25 argon2::Version::V0x13,
26 self.params.clone(),
27 )
28 }
29
30 #[tracing::instrument(level = "debug", name = "Generate password", skip(self, password))]
32 pub fn generate_password_hash(&self, password: &str) -> crate::Result<String> {
33 let salt = SaltString::generate(&mut rand::thread_rng());
34
35 Ok(self
36 .hasher()
37 .hash_password(password.as_bytes(), &salt)
38 .map_err(PasswordError::from)?
39 .to_string())
40 }
41
42 #[tracing::instrument(
44 level = "debug",
45 name = "Verifying password",
46 skip(self, password, password_hash)
47 )]
48 pub fn validate_password_hash(
49 &self,
50 password: &str,
51 password_hash: &str,
52 ) -> Result<(), argon2::password_hash::Error> {
53 let password = String::from(password);
54 let password_hash = String::from(password_hash);
55
56 let hash = argon2::PasswordHash::new(&password_hash)?;
57
58 self.hasher().verify_password(password.as_bytes(), &hash)
59 }
60}
61
62impl Default for PasswordControl {
63 fn default() -> Self {
64 let params = Params::default();
65 Self { params }
66 }
67}