1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
use crate::Error; use std::fmt; const N_ITER: u32 = 1_000; #[derive(Serialize, Deserialize, Clone)] #[serde(transparent)] pub struct Cred { cred: String, } impl fmt::Debug for Cred { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "Cred {{ ... }}") } } impl Cred { pub fn derive(secret: &str) -> Result<Cred, Error> { let cred = pbkdf2::pbkdf2_simple(secret, N_ITER).map_err(Error::internal)?; Ok(Cred { cred }) } pub fn verify(&self, attempt: &str) -> Result<(), Error> { pbkdf2::pbkdf2_check(attempt, self.cred.as_str()).map_err(Error::internal) } pub fn as_str(&self) -> &str { self.cred.as_str() } } impl From<String> for Cred { fn from(s: String) -> Self { Cred { cred: s } } } #[cfg(test)] mod tests { use super::*; #[test] fn derive_and_verify() { let pass = "hogehoge"; let cred = Cred::derive(pass).unwrap(); assert!(cred.verify(pass).is_ok()); assert!(cred.verify("invalid").is_err()); } }