[PATCH] emacs: Fix asynchronous get operations

Alex Griffin a at ajgrf.com
Tue Apr 28 20:52:11 CEST 2020

Currently `password-store-get' and `password-store-get-field' both block, even when provided with a callback. This is because `auth-source-pass-get' is synchronous, and it gets called before the functions even check if a callback was provided.

Fixing this without using synchronous functions was a little hairy, and I ended up using internal auth-source-pass functions. If you'd rather avoid that, I think it would be necessary to reimplement entry parsing, because none of the "user-facing" functions in auth-source-pass would work.
 contrib/emacs/password-store.el | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/contrib/emacs/password-store.el b/contrib/emacs/password-store.el
index ca8ae40..e051edb 100644
--- a/contrib/emacs/password-store.el
+++ b/contrib/emacs/password-store.el
@@ -232,25 +232,25 @@ ENTRY is the name of a password-store entry."

 Returns the first line of the password data.
 When CALLBACK is non-`NIL', call CALLBACK with the first line instead."
-  (let* ((inhibit-message t)
-         (secret (auth-source-pass-get 'secret entry)))
-    (if (not callback) secret
-      (password-store--run-show
-       entry
-       (lambda (_) (funcall callback secret))))))
+  (password-store-get-field entry 'secret callback))

 (defun password-store-get-field (entry field &optional callback)
   "Return FIELD for ENTRY.
-FIELD is a string, for instance \"url\".
+FIELD is a string, for instance \"url\".
 When CALLBACK is non-`NIL', call it with the line associated to FIELD instead.
 If FIELD equals to symbol secret, then this function reduces to `password-store-get'."
-  (let* ((inhibit-message t)
-         (secret (auth-source-pass-get field entry)))
-    (if (not callback) secret
+  (let ((inhibit-message t))
+    (if (not callback)
+        (auth-source-pass-get field entry)
-       (lambda (_) (and secret (funcall callback secret)))))))
+       (lambda (file-contents)
+         (let* ((data (cons `(secret . ,(auth-source-pass--parse-secret
+                                         file-contents))
+                            (auth-source-pass--parse-data file-contents)))
+                (secret (auth-source-pass--get-attr field data)))
+           (and secret (funcall callback secret))))))))


More information about the Password-Store mailing list