Add configurable password policy

This commit is contained in:
thePR0M3TH3AN
2025-07-13 13:00:02 -04:00
parent c0269801f8
commit b4dfd4b292
9 changed files with 145 additions and 11 deletions

View File

@@ -50,6 +50,10 @@ class ConfigManager:
"backup_interval": 0,
"secret_mode_enabled": False,
"clipboard_clear_delay": 45,
"min_uppercase": 2,
"min_lowercase": 2,
"min_digits": 2,
"min_special": 2,
}
try:
data = self.vault.load_config()
@@ -66,6 +70,10 @@ class ConfigManager:
data.setdefault("backup_interval", 0)
data.setdefault("secret_mode_enabled", False)
data.setdefault("clipboard_clear_delay", 45)
data.setdefault("min_uppercase", 2)
data.setdefault("min_lowercase", 2)
data.setdefault("min_digits", 2)
data.setdefault("min_special", 2)
# Migrate legacy hashed_password.enc if present and password_hash is missing
legacy_file = self.fingerprint_dir / "hashed_password.enc"
@@ -218,3 +226,36 @@ class ConfigManager:
"""Retrieve the backup interval in seconds."""
config = self.load_config(require_pin=False)
return float(config.get("backup_interval", 0))
# Password policy settings
def get_password_policy(self) -> "PasswordPolicy":
"""Return the password complexity policy."""
from password_manager.password_generation import PasswordPolicy
cfg = self.load_config(require_pin=False)
return PasswordPolicy(
min_uppercase=int(cfg.get("min_uppercase", 2)),
min_lowercase=int(cfg.get("min_lowercase", 2)),
min_digits=int(cfg.get("min_digits", 2)),
min_special=int(cfg.get("min_special", 2)),
)
def set_min_uppercase(self, count: int) -> None:
cfg = self.load_config(require_pin=False)
cfg["min_uppercase"] = int(count)
self.save_config(cfg)
def set_min_lowercase(self, count: int) -> None:
cfg = self.load_config(require_pin=False)
cfg["min_lowercase"] = int(count)
self.save_config(cfg)
def set_min_digits(self, count: int) -> None:
cfg = self.load_config(require_pin=False)
cfg["min_digits"] = int(count)
self.save_config(cfg)
def set_min_special(self, count: int) -> None:
cfg = self.load_config(require_pin=False)
cfg["min_special"] = int(count)
self.save_config(cfg)

View File

@@ -976,6 +976,7 @@ class PasswordManager:
encryption_manager=self.encryption_manager,
parent_seed=self.parent_seed,
bip85=self.bip85,
policy=self.config_manager.get_password_policy(),
)
# Load relay configuration and initialize NostrClient

View File

@@ -21,6 +21,7 @@ import random
import traceback
import base64
from typing import Optional
from dataclasses import dataclass
from termcolor import colored
from pathlib import Path
import shutil
@@ -48,6 +49,16 @@ from password_manager.encryption import EncryptionManager
logger = logging.getLogger(__name__)
@dataclass
class PasswordPolicy:
"""Minimum complexity requirements for generated passwords."""
min_uppercase: int = 2
min_lowercase: int = 2
min_digits: int = 2
min_special: int = 2
class PasswordGenerator:
"""
PasswordGenerator Class
@@ -58,7 +69,11 @@ class PasswordGenerator:
"""
def __init__(
self, encryption_manager: EncryptionManager, parent_seed: str, bip85: BIP85
self,
encryption_manager: EncryptionManager,
parent_seed: str,
bip85: BIP85,
policy: PasswordPolicy | None = None,
):
"""
Initializes the PasswordGenerator with the encryption manager, parent seed, and BIP85 instance.
@@ -72,6 +87,7 @@ class PasswordGenerator:
self.encryption_manager = encryption_manager
self.parent_seed = parent_seed
self.bip85 = bip85
self.policy = policy or PasswordPolicy()
# Derive seed bytes from parent_seed using BIP39 (handled by EncryptionManager)
self.seed_bytes = self.encryption_manager.derive_seed_from_mnemonic(
@@ -224,11 +240,11 @@ class PasswordGenerator:
f"Current character counts - Upper: {current_upper}, Lower: {current_lower}, Digits: {current_digits}, Special: {current_special}"
)
# Set minimum counts
min_upper = 2
min_lower = 2
min_digits = 2
min_special = 2
# Set minimum counts from policy
min_upper = self.policy.min_uppercase
min_lower = self.policy.min_lowercase
min_digits = self.policy.min_digits
min_special = self.policy.min_special
# Initialize derived key index
dk_index = 0