claw_crypto/
hash_service.rs1use crate::traits::HashServiceTrait;
2use bcrypt;
3
4pub struct HashService {
5 cost: u32,
6}
7
8impl HashService {
9 const MIN_COST: u32 = 4;
10
11 pub fn new(cost: u32) -> Self {
12 if cost < HashService::MIN_COST {
13 panic!("Minimum cost for HashService is {}", HashService::MIN_COST);
14 }
15 Self { cost }
16 }
17
18 #[cfg(test)]
19 pub(crate) fn with_min_cost() -> Self {
20 Self {
21 cost: HashService::MIN_COST,
22 }
23 }
24}
25
26impl Default for HashService {
27 fn default() -> Self {
28 Self {
29 cost: bcrypt::DEFAULT_COST,
30 }
31 }
32}
33
34impl HashServiceTrait for HashService {
35 fn hash(&self, string: &str) -> Result<String, ()> {
36 let result = bcrypt::hash(string, self.cost);
37 let hash = result.map_err(|_err| ())?;
38 Ok(hash)
39 }
40
41 fn verify(&self, token: &str, token_hash: &str) -> bool {
42 bcrypt::verify(token, token_hash).unwrap_or(false)
43 }
44}
45
46#[cfg(test)]
47mod test {
48 use super::*;
49
50 #[test]
51 fn it_hashes_input() {
52 let hash_service = HashService::with_min_cost();
53
54 let input = "this_should_garbled_by_the_hashing_algorithm";
55 let hashed = hash_service.hash(input).expect("Got unexpected error");
56
57 assert_ne!(input, hashed);
58 }
59
60 #[test]
61 fn it_returns_true_when_verifying_correct_token() {
62 let hash_service = HashService::with_min_cost();
63
64 let input = "this_should_garbled_by_the_hashing_algorithm";
65 let hashed = hash_service.hash(input).expect("Got unexpected error");
66 let is_correct = hash_service.verify(input, &hashed);
67
68 assert!(is_correct);
69 }
70
71 #[test]
72 fn it_returns_false_when_verifying_incorrect_token() {
73 let hash_service = HashService::with_min_cost();
74
75 let input = "this_should_garbled_by_the_hashing_algorithm";
76 let hashed = hash_service.hash(input).expect("Got unexpected error");
77 let is_correct = hash_service.verify("incorrect_input", &hashed);
78
79 assert!(!is_correct);
80 }
81}