From 8a6a8c0edfe09b370b4331cc784e892e00ca9f65 Mon Sep 17 00:00:00 2001 From: Piotr Dec Date: Tue, 4 Nov 2025 00:14:18 +0100 Subject: [PATCH] KP opened on request, changed delimiter --- app/services/mo.py | 2 +- app/services/passwords.py | 34 +++++++++++++--------------------- pyproject.toml | 1 + tests/files/test1/test.mo.yaml | 2 +- tests/test_mo.py | 1 + 5 files changed, 17 insertions(+), 23 deletions(-) diff --git a/app/services/mo.py b/app/services/mo.py index 9a35642..4606abe 100644 --- a/app/services/mo.py +++ b/app/services/mo.py @@ -13,7 +13,7 @@ class SimpleValueTemplate(Template): class ComplexValueTemplate(SimpleValueTemplate): - delimiter = '@' + delimiter = '%' @injectable diff --git a/app/services/passwords.py b/app/services/passwords.py index 408ec5e..39ff368 100644 --- a/app/services/passwords.py +++ b/app/services/passwords.py @@ -1,6 +1,8 @@ import os.path -import shutil +from contextlib import contextmanager +from typing import Any, Generator +import keyring from injectable import injectable from pykeepass import PyKeePass, create_database @@ -12,22 +14,16 @@ class Passwords: settings = get_settings() with open(settings.kp.secret, "r") as fh: - secret = fh.read().splitlines()[0] + keyring.set_password("karl", "kp", 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) + @contextmanager + def open(self, mode: str = "r") -> Generator[PyKeePass | Any, Any, None]: + kp = PyKeePass(self._path, password=keyring.get_password("karl", "kp")) \ + if os.path.exists(self._path) else create_database(self._path, password=keyring.get_password("karl", "kp")) + yield kp + if mode == "rw": + kp.save() def get_values(self, keys: list[str]) -> dict[str, str]: output = {} @@ -36,7 +32,8 @@ class Passwords: 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) + with self.open() as kp: + kp_entry = kp.find_entries(path=path, first=True, title=entry_name) output[k] = self._get_field_value(kp_entry, field_name) return output @@ -53,8 +50,3 @@ class Passwords: 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) diff --git a/pyproject.toml b/pyproject.toml index 1791992..71a9de1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ dependencies = [ "injectable==4.0.1", "py-automapper>=2.2.0", "fastapi-utils>=0.8.0", + "keyring>=25.6.0", ] [project.optional-dependencies] diff --git a/tests/files/test1/test.mo.yaml b/tests/files/test1/test.mo.yaml index 572b953..7fff584 100644 --- a/tests/files/test1/test.mo.yaml +++ b/tests/files/test1/test.mo.yaml @@ -1,3 +1,3 @@ value: ${sample} nested: ${some.nested.value} -custom: @{custom.field} +custom: %{custom.field} diff --git a/tests/test_mo.py b/tests/test_mo.py index f685e34..b3d25d4 100644 --- a/tests/test_mo.py +++ b/tests/test_mo.py @@ -17,6 +17,7 @@ class TestMo(TestCase): with open(target_path, 'r') as f: content = f.read() self.assertFalse(content.__contains__('${')) + self.assertFalse(content.__contains__('%{')) parsed = yaml.load(content, Loader=yaml.FullLoader) self.assertEqual('some_pass', parsed['value']) self.assertEqual('nested_pass', parsed['nested'])