73 lines
2.1 KiB
Python
73 lines
2.1 KiB
Python
import os.path
|
|
from contextlib import contextmanager
|
|
from typing import Any, Generator
|
|
|
|
import keyring
|
|
from injectable import injectable
|
|
from pykeepass import PyKeePass, create_database
|
|
|
|
class KeyRequest:
|
|
def __init__(self, prompt: str):
|
|
self.field_name = None
|
|
self.entry_name = None
|
|
self.path = None
|
|
self._parse_prompt(prompt)
|
|
|
|
def _parse_prompt(self, prompt: str):
|
|
|
|
pass
|
|
# k_parts = k.split("/")
|
|
# field_name = None
|
|
# match len(k_parts):
|
|
# case 1:
|
|
# field_name = 'password'
|
|
# case 2:
|
|
# field_name = k_parts[1]
|
|
# k = k_parts[0]
|
|
# case _:
|
|
# output[k] = None
|
|
# continue
|
|
# key_parts = k.split(".")
|
|
# path = key_parts[:-1] if len(key_parts) > 2 else None
|
|
# entry_name = key_parts[-1]
|
|
|
|
@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:
|
|
keyring.set_password("karl", "kp", fh.read().splitlines()[0])
|
|
self._path = settings.kp.file
|
|
|
|
@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 = {}
|
|
for k in keys:
|
|
request = KeyRequest(k)
|
|
with self.open() as kp:
|
|
kp_entry = kp.find_entries(path=request.path, first=True, title=request.entry_name)
|
|
output[k] = self._get_field_value(kp_entry, request.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)
|