Coverage for opt/mealie/lib/python3.12/site-packages/mealie/core/security/hasher.py: 83%
29 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-25 15:32 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-25 15:32 +0000
1from functools import lru_cache 1a
2from typing import Protocol 1a
4import bcrypt 1a
6from mealie.core.config import get_app_settings 1a
9class Hasher(Protocol): 1a
10 def hash(self, password: str) -> str: ... 10 ↛ exitline 10 didn't return from function 'hash' because 1a
12 def verify(self, password: str, hashed: str) -> bool: ... 12 ↛ exitline 12 didn't return from function 'verify' because 1a
15class FakeHasher: 1a
16 def hash(self, password: str) -> str: 1a
17 return password
19 def verify(self, password: str, hashed: str) -> bool: 1a
20 return password == hashed
23class BcryptHasher: 1a
24 def _get_password_bytes(self, password: str) -> bytes: 1a
25 return password.encode("utf-8")[:72] 1abcdefghijkl
27 def hash(self, password: str) -> str: 1a
28 password_bytes = self._get_password_bytes(password) 1ab
29 hashed = bcrypt.hashpw(password_bytes, bcrypt.gensalt()) 1ab
30 return hashed.decode("utf-8") 1ab
32 def verify(self, password: str, hashed: str) -> bool: 1a
33 password_bytes = self._get_password_bytes(password) 1cdefghijkl
34 hashed_bytes = hashed.encode("utf-8") 1cdefghijkl
35 return bcrypt.checkpw(password_bytes, hashed_bytes) 1cdefghijkml
38@lru_cache(maxsize=1) 1a
39def get_hasher() -> Hasher: 1a
40 settings = get_app_settings() 1a
42 if settings.TESTING: 42 ↛ 43line 42 didn't jump to line 43 because the condition on line 42 was never true1a
43 return FakeHasher()
45 return BcryptHasher() 1a