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)