mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-08 15:28:44 +00:00
Add Hypothesis password property tests
This commit is contained in:
@@ -162,9 +162,17 @@ class PasswordGenerator:
|
||||
password = self._shuffle_deterministically(password, dk)
|
||||
logger.debug(f"Extended password: {password}")
|
||||
|
||||
# Trim the password to the desired length
|
||||
# Trim the password to the desired length and enforce complexity on
|
||||
# the final result. Complexity enforcement is repeated here because
|
||||
# trimming may remove required character classes from the password
|
||||
# produced above when the requested length is shorter than the
|
||||
# initial entropy size.
|
||||
password = password[:length]
|
||||
logger.debug(f"Final password (trimmed to {length} chars): {password}")
|
||||
password = self._enforce_complexity(password, all_allowed, dk)
|
||||
password = self._shuffle_deterministically(password, dk)
|
||||
logger.debug(
|
||||
f"Final password (trimmed to {length} chars with complexity enforced): {password}"
|
||||
)
|
||||
|
||||
return password
|
||||
|
||||
|
@@ -16,3 +16,4 @@ websocket-client==1.7.0
|
||||
|
||||
websockets>=15.0.0
|
||||
tomli
|
||||
hypothesis
|
||||
|
44
src/tests/test_password_properties.py
Normal file
44
src/tests/test_password_properties.py
Normal file
@@ -0,0 +1,44 @@
|
||||
import sys
|
||||
import string
|
||||
from pathlib import Path
|
||||
from hypothesis import given, strategies as st
|
||||
|
||||
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
||||
|
||||
from password_manager.password_generation import PasswordGenerator
|
||||
|
||||
|
||||
class DummyEnc:
|
||||
def derive_seed_from_mnemonic(self, mnemonic):
|
||||
return b"\x00" * 32
|
||||
|
||||
|
||||
class DummyBIP85:
|
||||
def derive_entropy(self, index: int, bytes_len: int, app_no: int = 32) -> bytes:
|
||||
return bytes((index + i) % 256 for i in range(bytes_len))
|
||||
|
||||
|
||||
def make_generator():
|
||||
pg = PasswordGenerator.__new__(PasswordGenerator)
|
||||
pg.encryption_manager = DummyEnc()
|
||||
pg.bip85 = DummyBIP85()
|
||||
return pg
|
||||
|
||||
|
||||
@given(
|
||||
length=st.integers(min_value=8, max_value=64),
|
||||
index=st.integers(min_value=0, max_value=1000),
|
||||
)
|
||||
def test_password_properties(length, index):
|
||||
pg = make_generator()
|
||||
pw1 = pg.generate_password(length=length, index=index)
|
||||
pw2 = pg.generate_password(length=length, index=index)
|
||||
|
||||
assert pw1 == pw2
|
||||
assert len(pw1) == length
|
||||
|
||||
assert sum(c.isupper() for c in pw1) >= 2
|
||||
assert sum(c.islower() for c in pw1) >= 2
|
||||
assert sum(c.isdigit() for c in pw1) >= 2
|
||||
assert sum(c in string.punctuation for c in pw1) >= 2
|
||||
assert not any(c.isspace() for c in pw1)
|
Reference in New Issue
Block a user