mirror of
https://github.com/gburd/nix-config.git
synced 2024-11-15 08:46:25 +00:00
138 lines
4.7 KiB
Diff
138 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
|