nix-config/overlays/pass-secret-service-native.diff
2023-09-26 14:39:38 -04:00

137 lines
4.7 KiB
Diff

diff --git a/Makefile b/Makefile
index 64222c2..65d4c33 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,7 @@ relgnupghome ::= test/.gnupghome
export GNUPGHOME ::= $(projectdir)/$(relgnupghome)
gpg_key_id ::= "8c2a59a7"
relpassstore ::= test/.test-password-store
+pass ::= pypass
export PASSWORD_STORE_DIR ::= $(projectdir)/$(relpassstore)
.PHONY: all test coverage style clean clean-pycache clean-build
@@ -10,7 +11,7 @@ export PASSWORD_STORE_DIR ::= $(projectdir)/$(relpassstore)
all: style test
test: | $(relpassstore)
- dbus-run-session -- pytest-3 -v test
+ dbus-run-session -- pytest-3 -v test --asyncio-mode=auto
coverage: | $(relpassstore)
dbus-run-session -- python3 -m coverage run -m pytest -v test
@@ -28,7 +29,7 @@ $(relgnupghome): test/test_key.asc test/test_ownertrust.txt
$(relpassstore): | $(relgnupghome)
@echo "===== Preparing password store in $(relpassstore) ====="
- pypass init -p $(relpassstore) $(gpg_key_id)
+ $(pass) init -p $(relpassstore) $(gpg_key_id)
clean: clean-test-environment clean-pycache clean-build
diff --git a/pass_secret_service/common/native_pass.py b/pass_secret_service/common/native_pass.py
new file mode 100644
index 0000000..b1a06aa
--- /dev/null
+++ b/pass_secret_service/common/native_pass.py
@@ -0,0 +1,30 @@
+import subprocess
+import os
+
+DEFAULT_PASS = "pass"
+
+class NativePasswordStore:
+ def __init__(self, use_pass=None, path=None):
+ self.pass_cmd = use_pass or DEFAULT_PASS
+ self.path = path
+
+ def _pass(self, *args, **kwargs):
+ env = os.environ
+ if self.path is not None:
+ env.update({'PASSWORD_STORE_DIR': self.path})
+
+ proc = subprocess.run([self.pass_cmd, *args],
+ check=True,
+ text=True,
+ capture_output=True,
+ env=env,
+ **kwargs
+ )
+
+ return proc
+
+ def get_decrypted_password(self, passname):
+ return self._pass("show", passname).stdout.removesuffix("\n")
+
+ def insert_password(self, passname, password):
+ self._pass("insert", "--echo", passname, input=password)
diff --git a/pass_secret_service/common/pass_store.py b/pass_secret_service/common/pass_store.py
index c1aa175..4f13438 100644
--- a/pass_secret_service/common/pass_store.py
+++ b/pass_secret_service/common/pass_store.py
@@ -2,19 +2,30 @@
import shutil
import uuid
import json
-from pypass import PasswordStore
+try:
+ from pypass import PasswordStore
-# Work around a typo in pypass
-if not hasattr(PasswordStore, "get_decrypted_password"):
- PasswordStore.get_decrypted_password = PasswordStore.get_decypted_password
+ # Work around a typo in pypass
+ if not hasattr(PasswordStore, "get_decrypted_password"):
+ PasswordStore.get_decrypted_password = PasswordStore.get_decypted_password
+
+except ImportError:
+ from .native_pass import NativePasswordStore
+ PasswordStore = NativePasswordStore
class PassStore:
PREFIX = "secret_service"
- def __init__(self, *args, **kwargs):
- self._store = PasswordStore(*args, **kwargs)
+ def __init__(self, *args, use_pass=None, **kwargs):
+ if not use_pass:
+ self._store = PasswordStore(*args, **kwargs)
+
+ else:
+ from .native_pass import NativePasswordStore
+ self._store = NativePasswordStore(use_pass=use_pass, **kwargs)
+
self.base_path = os.path.join(self._store.path, self.PREFIX)
if not os.path.exists(self.base_path):
os.makedirs(self.base_path)
diff --git a/pass_secret_service/pass_secret_service.py b/pass_secret_service/pass_secret_service.py
index 8c35db9..7dbcdf0 100755
--- a/pass_secret_service/pass_secret_service.py
+++ b/pass_secret_service/pass_secret_service.py
@@ -30,10 +30,10 @@ async def register_service(pass_store):
return service
-def _main(path, verbose):
+def _main(path, pass_, verbose):
if verbose:
logging.basicConfig(level=20)
- pass_store = PassStore(**({"path": path} if path else {}))
+ pass_store = PassStore(use_pass=pass_, **({"path": path} if path else {}))
mainloop = asyncio.get_event_loop()
mainloop.add_signal_handler(signal.SIGTERM, functools.partial(term_loop, mainloop))
mainloop.add_signal_handler(signal.SIGINT, functools.partial(term_loop, mainloop))
@@ -51,9 +51,10 @@ def _main(path, verbose):
@click.command()
@click.option("--path", help="path to the password store (optional)")
+@click.option("-e", "pass_", help="use given pass executable")
@click.option("-v", "--verbose", help="be verbose", is_flag=True, default=False)
-def main(path, verbose):
- _main(path, verbose)
+def main(path, pass_, verbose):
+ _main(path, pass_, verbose)
if __name__ == "__main__": # pragma: no cover