diff options
| author | Loek Le Blansch <loek@pipeframe.xyz> | 2025-10-14 18:55:31 +0200 |
|---|---|---|
| committer | Loek Le Blansch <loek@pipeframe.xyz> | 2025-10-14 18:55:31 +0200 |
| commit | e8f200337975e9f8b8d57a5a0a3a2b25395cee88 (patch) | |
| tree | 07cfdfa9983c11f8454e0428475b95b3a5b1b02b /nmpass/store.py | |
initial commit (wip)
Diffstat (limited to 'nmpass/store.py')
| -rw-r--r-- | nmpass/store.py | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/nmpass/store.py b/nmpass/store.py new file mode 100644 index 0000000..08080ba --- /dev/null +++ b/nmpass/store.py @@ -0,0 +1,38 @@ +from subprocess import run, PIPE, DEVNULL +from os import environ, path + +NEWLINE = "\n" + +class PasswordStore(): + PASSWORD_STORE = "pass" + PASSWORD_STORE_DIR = path.join(environ["HOME"], ".password-store") + + def __init__(self): + if "PASSWORD_STORE_DIR" in environ: + self.PASSWORD_STORE_DIR = environ["PASSWORD_STORE_DIR"] + + # There's no way to check using the pass CLI whether a password name passed + # to `pass show` is a password or a directory, so this checks manually + def exists(self, name: str) -> bool: + return path.isfile(path.join(self.PASSWORD_STORE_DIR, f"{name}.gpg")) + + def retrieve(self, name: str, truncate: bool = True) -> str | None: + if not self.exists(name): + return None + cmd = (self.PASSWORD_STORE, 'show', name,) + proc = run(cmd, stdout=PIPE) + output = proc.stdout.decode() + if not truncate: + return output + return output.split(NEWLINE)[0] + + def store(self, name: str, password: str) -> None: + current = self.retrieve(name, False) + if current == None: + current = NEWLINE + to = current.find(NEWLINE) + current = f"{password}{current[to:]}" + + cmd = (self.PASSWORD_STORE, 'insert', '--multiline', '--force', name,) + run(cmd, input=current.encode(), stdout=DEVNULL, stderr=DEVNULL) + |