import os.path import shutil from injectable import injectable from pykeepass import PyKeePass, create_database @injectable(singleton=True) class Passwords: def __init__(self): from app.config import get_settings settings = get_settings() with open(settings.kp.secret, "r") as fh: secret = fh.read().splitlines()[0] self._path = settings.kp.file self._kp_org = self._open_or_create(self._path, secret) self._kp = self._open_lock(self._path, secret) @staticmethod def _open_or_create(path, password) -> PyKeePass: if os.path.exists(path): return PyKeePass(path, password=password) return create_database(path, password) @staticmethod def _open_lock(path, password) -> PyKeePass: lock_path = path + ".lock" shutil.copyfile(path, lock_path) return Passwords._open_or_create(lock_path, password) def get_values(self, keys: list[str]) -> dict[str, str]: output = {} for k in keys: key_parts = k.split(".") path = key_parts[:-1] if len(key_parts) > 2 else None entry_name = key_parts[-2] field_name = key_parts[-1] kp_entry = self._kp_org.find_entries(path=path, first=True, title=entry_name) output[k] = self._get_field_value(kp_entry, field_name) return output @staticmethod def _get_field_value(kp_entry, field_name): if kp_entry is None: return None match field_name: case "username": return kp_entry.username case "password": return kp_entry.password case "url": return kp_entry.url case _: return kp_entry.get_custom_property(field_name) def save(self): # nadpisz plik źródłowy zmianami z lock self._kp.save() shutil.copyfile(self._path + ".lock", self._path)