diff options
| author | Damien Cassou | 2017-04-03 21:36:03 +0200 |
|---|---|---|
| committer | Ted Zlatanov | 2017-04-26 15:11:35 -0400 |
| commit | 14ff8b1fb60459c4c5cb147e07e3902dc569f8e0 (patch) | |
| tree | f2200f9516a295cc6ae28593eb2ca12d5efee1dd | |
| parent | c2d4ed8f2ee18d5e3fb56b31c2e1b784b1ea70e0 (diff) | |
| download | emacs-feature/auth-source-pass.tar.gz emacs-feature/auth-source-pass.zip | |
auth-source-pass: Add documentation; fix tests and indentation.feature/auth-source-pass
* doc/misc/auth.texi: Document new integration with Pass. Use @itemize
instead of @enumerate.
* lisp/auth-source-pass.el: Fix indentation.
(auth-source-pass--remove-directory-name): Remove.
* test/lisp/auth-source-pass-tests.el: Adjust test macros.
| -rw-r--r-- | doc/misc/auth.texi | 46 | ||||
| -rw-r--r-- | lisp/auth-source-pass.el | 17 | ||||
| -rw-r--r-- | test/lisp/auth-source-pass-tests.el | 243 |
3 files changed, 161 insertions, 145 deletions
diff --git a/doc/misc/auth.texi b/doc/misc/auth.texi index 29e55eda52c..94229e69f79 100644 --- a/doc/misc/auth.texi +++ b/doc/misc/auth.texi | |||
| @@ -85,8 +85,9 @@ password (known as the secret). | |||
| 85 | 85 | ||
| 86 | Similarly, the auth-source library supports multiple storage backend, | 86 | Similarly, the auth-source library supports multiple storage backend, |
| 87 | currently either the classic ``netrc'' backend, examples of which you | 87 | currently either the classic ``netrc'' backend, examples of which you |
| 88 | can see later in this document, or the Secret Service API@. This is | 88 | can see later in this document, the Secret Service API, and pass, the |
| 89 | done with EIEIO-based backends and you can write your own if you want. | 89 | standard unix password manager. This is done with EIEIO-based |
| 90 | backends and you can write your own if you want. | ||
| 90 | 91 | ||
| 91 | @node Help for users | 92 | @node Help for users |
| 92 | @chapter Help for users | 93 | @chapter Help for users |
| @@ -150,9 +151,9 @@ auth-source library is not loaded for some other reason. | |||
| 150 | @defvar auth-sources | 151 | @defvar auth-sources |
| 151 | 152 | ||
| 152 | The @code{auth-sources} variable tells the auth-source library where | 153 | The @code{auth-sources} variable tells the auth-source library where |
| 153 | your netrc files or Secret Service API collection items live for a | 154 | your netrc files, Secret Service API collection items, or your |
| 154 | particular host and protocol. While you can get fancy, the default | 155 | password store live for a particular host and protocol. While you can |
| 155 | and simplest configuration is: | 156 | get fancy, the default and simplest configuration is: |
| 156 | 157 | ||
| 157 | @lisp | 158 | @lisp |
| 158 | ;;; old default: required :host and :port, not needed anymore | 159 | ;;; old default: required :host and :port, not needed anymore |
| @@ -164,6 +165,9 @@ and simplest configuration is: | |||
| 164 | ;;; use the Secrets API @var{Login} collection | 165 | ;;; use the Secrets API @var{Login} collection |
| 165 | ;;; (@pxref{Secret Service API}) | 166 | ;;; (@pxref{Secret Service API}) |
| 166 | (setq auth-sources '("secrets:Login")) | 167 | (setq auth-sources '("secrets:Login")) |
| 168 | ;;; use pass (@file{~/.password-store}) | ||
| 169 | ;;; (@pxref{Pass, the Unix password store}) | ||
| 170 | (setq auth-sources '(password-store)) | ||
| 167 | @end lisp | 171 | @end lisp |
| 168 | 172 | ||
| 169 | By adding multiple entries to @code{auth-sources} with a particular | 173 | By adding multiple entries to @code{auth-sources} with a particular |
| @@ -402,6 +406,34 @@ then fall back to @file{~/.authinfo.gpg}. | |||
| 402 | "~/.authinfo.gpg")) | 406 | "~/.authinfo.gpg")) |
| 403 | @end example | 407 | @end example |
| 404 | 408 | ||
| 409 | @node Pass, the Unix password store | ||
| 410 | @chapter Pass, the Unix password store | ||
| 411 | |||
| 412 | @uref{http://www.passwordstore.org,,The standard unix password | ||
| 413 | manager} (or just @code{pass}) stores your passwords in | ||
| 414 | @code{gpg}-protected files following the Unix philosophy. | ||
| 415 | |||
| 416 | Emacs integration of @code{pass} follows the first approach suggested | ||
| 417 | by the pass project itself for data organization to find data. This | ||
| 418 | means that the filename of the file containing the password for a user | ||
| 419 | on a particular host must contain the host name. The file itself must | ||
| 420 | contain the password on the first line, as well as a @code{username} | ||
| 421 | field containing the username on a subsequent line. A @code{port} | ||
| 422 | field can be used to differentiate the authentication data for several | ||
| 423 | services with the same username on the same host. | ||
| 424 | |||
| 425 | Users of @code{pass} may also be interested in functionality provided | ||
| 426 | by other Emacs packages dealing with pass: | ||
| 427 | |||
| 428 | @itemize | ||
| 429 | @item | ||
| 430 | @uref{https://git.zx2c4.com/password-store/tree/contrib/emacs/password-store.el,,password-store}: library wrapping @code{pass}; | ||
| 431 | @item | ||
| 432 | @uref{https://github.com/NicolasPetton/pass,,pass}: major mode to manipulate the store and edit entries; | ||
| 433 | @item | ||
| 434 | @uref{https://github.com/jabranham/helm-pass,,helm-pass}: helm interface for pass. | ||
| 435 | @end itemize | ||
| 436 | |||
| 405 | @node Help for developers | 437 | @node Help for developers |
| 406 | @chapter Help for developers | 438 | @chapter Help for developers |
| 407 | 439 | ||
| @@ -517,14 +549,14 @@ or EasyPG Assistant | |||
| 517 | 549 | ||
| 518 | To quick start, here are some questions: | 550 | To quick start, here are some questions: |
| 519 | 551 | ||
| 520 | @enumerate | 552 | @itemize |
| 521 | @item | 553 | @item |
| 522 | Do you use GnuPG version 2 instead of GnuPG version 1? | 554 | Do you use GnuPG version 2 instead of GnuPG version 1? |
| 523 | @item | 555 | @item |
| 524 | Do you use symmetric encryption rather than public key encryption? | 556 | Do you use symmetric encryption rather than public key encryption? |
| 525 | @item | 557 | @item |
| 526 | Do you want to use gpg-agent? | 558 | Do you want to use gpg-agent? |
| 527 | @end enumerate | 559 | @end itemize |
| 528 | 560 | ||
| 529 | Here are configurations depending on your answers: | 561 | Here are configurations depending on your answers: |
| 530 | 562 | ||
diff --git a/lisp/auth-source-pass.el b/lisp/auth-source-pass.el index e59cfa2d25f..a83c7de0cc5 100644 --- a/lisp/auth-source-pass.el +++ b/lisp/auth-source-pass.el | |||
| @@ -39,8 +39,8 @@ | |||
| 39 | (require 'url-parse) | 39 | (require 'url-parse) |
| 40 | 40 | ||
| 41 | (cl-defun auth-source-pass-search (&rest spec | 41 | (cl-defun auth-source-pass-search (&rest spec |
| 42 | &key backend type host user port | 42 | &key backend type host user port |
| 43 | &allow-other-keys) | 43 | &allow-other-keys) |
| 44 | "Given a property list SPEC, return search matches from the :backend. | 44 | "Given a property list SPEC, return search matches from the :backend. |
| 45 | See `auth-source-search' for details on SPEC." | 45 | See `auth-source-search' for details on SPEC." |
| 46 | (cl-assert (or (null type) (eq type (oref backend type))) | 46 | (cl-assert (or (null type) (eq type (oref backend type))) |
| @@ -60,7 +60,7 @@ See `auth-source-search' for details on SPEC." | |||
| 60 | :user (or (auth-source-pass-get "user" entry) user) | 60 | :user (or (auth-source-pass-get "user" entry) user) |
| 61 | :secret (lambda () (auth-source-pass-get 'secret entry))))) | 61 | :secret (lambda () (auth-source-pass-get 'secret entry))))) |
| 62 | (auth-source-pass--do-debug "return %s as final result (plus hidden password)" | 62 | (auth-source-pass--do-debug "return %s as final result (plus hidden password)" |
| 63 | (seq-subseq retval 0 -2)) ;; remove password | 63 | (seq-subseq retval 0 -2)) ;; remove password |
| 64 | retval)))) | 64 | retval)))) |
| 65 | 65 | ||
| 66 | ;;;###autoload | 66 | ;;;###autoload |
| @@ -159,11 +159,6 @@ CONTENTS is the contents of a password-store formatted file." | |||
| 159 | (hostname hostname) | 159 | (hostname hostname) |
| 160 | (t host)))) | 160 | (t host)))) |
| 161 | 161 | ||
| 162 | (defun auth-source-pass--remove-directory-name (name) | ||
| 163 | "Remove directories from NAME. | ||
| 164 | E.g., if NAME is \"foo/bar\", return \"bar\"." | ||
| 165 | (replace-regexp-in-string ".*/" "" name)) | ||
| 166 | |||
| 167 | (defun auth-source-pass--do-debug (&rest msg) | 162 | (defun auth-source-pass--do-debug (&rest msg) |
| 168 | "Call `auth-source-do-debug` with MSG and a prefix." | 163 | "Call `auth-source-do-debug` with MSG and a prefix." |
| 169 | (apply #'auth-source-do-debug | 164 | (apply #'auth-source-do-debug |
| @@ -216,7 +211,7 @@ Only return valid entries as of `auth-source-pass--entry-valid-p'." | |||
| 216 | (member entryname (split-string entry "/")))) | 211 | (member entryname (split-string entry "/")))) |
| 217 | (and (= (length components-host-user) 2) | 212 | (and (= (length components-host-user) 2) |
| 218 | (string-equal user (cadr components-host-user)))) | 213 | (string-equal user (cadr components-host-user)))) |
| 219 | (string-equal entryname (auth-source-pass--remove-directory-name entry))) | 214 | (string-equal entryname (file-name-nondirectory entry))) |
| 220 | (auth-source-pass--entry-valid-p entry))) | 215 | (auth-source-pass--entry-valid-p entry))) |
| 221 | (auth-source-pass-entries))) | 216 | (auth-source-pass-entries))) |
| 222 | 217 | ||
| @@ -225,8 +220,8 @@ Only return valid entries as of `auth-source-pass--entry-valid-p'." | |||
| 225 | If USER is non nil, give precedence to entries containing a user field | 220 | If USER is non nil, give precedence to entries containing a user field |
| 226 | matching USER." | 221 | matching USER." |
| 227 | (auth-source-pass--do-debug "searching for '%s' in entry names (user: %s)" | 222 | (auth-source-pass--do-debug "searching for '%s' in entry names (user: %s)" |
| 228 | entryname | 223 | entryname |
| 229 | user) | 224 | user) |
| 230 | (let ((matching-entries (auth-source-pass--find-all-by-entry-name entryname user))) | 225 | (let ((matching-entries (auth-source-pass--find-all-by-entry-name entryname user))) |
| 231 | (pcase (length matching-entries) | 226 | (pcase (length matching-entries) |
| 232 | (0 (auth-source-pass--do-debug "no match found") | 227 | (0 (auth-source-pass--do-debug "no match found") |
diff --git a/test/lisp/auth-source-pass-tests.el b/test/lisp/auth-source-pass-tests.el index 1a7c9a70365..102611d2fae 100644 --- a/test/lisp/auth-source-pass-tests.el +++ b/test/lisp/auth-source-pass-tests.el | |||
| @@ -63,108 +63,102 @@ | |||
| 63 | This function is intended to be set to `auth-source-debug`." | 63 | This function is intended to be set to `auth-source-debug`." |
| 64 | (add-to-list 'auth-source-pass--debug-log (apply #'format msg) t)) | 64 | (add-to-list 'auth-source-pass--debug-log (apply #'format msg) t)) |
| 65 | 65 | ||
| 66 | (defmacro auth-source-pass--deftest (name arglist store &rest body) | 66 | (defmacro auth-source-pass--with-store (store &rest body) |
| 67 | "Define a new ert-test NAME with ARGLIST using STORE as password-store. | 67 | "Use STORE as password-store while executing BODY." |
| 68 | BODY is a sequence of instructions that will be evaluated. | 68 | (declare (indent 1)) |
| 69 | 69 | `(cl-letf (((symbol-function 'auth-source-pass-parse-entry) (lambda (entry) (cdr (cl-find entry ,store :key #'car :test #'string=))) ) | |
| 70 | This macro overrides `auth-source-pass-parse-entry' and `auth-source-pass-entries' to | 70 | ((symbol-function 'auth-source-pass-entries) (lambda () (mapcar #'car ,store))) |
| 71 | test code without touching the file system." | 71 | ((symbol-function 'auth-source-pass--entry-valid-p) (lambda (_entry) t))) |
| 72 | (declare (indent 3)) | 72 | (let ((auth-source-debug #'auth-source-pass--debug) |
| 73 | `(ert-deftest ,name ,arglist | 73 | (auth-source-pass--debug-log nil)) |
| 74 | (cl-letf (((symbol-function 'auth-source-pass-parse-entry) (lambda (entry) (cdr (cl-find entry ,store :key #'car :test #'string=))) ) | 74 | ,@body))) |
| 75 | ((symbol-function 'auth-source-pass-entries) (lambda () (mapcar #'car ,store))) | 75 | |
| 76 | ((symbol-function 'auth-source-pass--entry-valid-p) (lambda (_entry) t))) | 76 | (ert-deftest auth-source-pass-find-match-matching-at-entry-name () |
| 77 | (let ((auth-source-debug #'auth-source-pass--debug) | 77 | (auth-source-pass--with-store '(("foo")) |
| 78 | (auth-source-pass--debug-log nil)) | 78 | (should (equal (auth-source-pass--find-match "foo" nil) |
| 79 | ,@body)))) | 79 | "foo")))) |
| 80 | 80 | ||
| 81 | (auth-source-pass--deftest auth-source-pass-find-match-matching-at-entry-name () | 81 | (ert-deftest auth-source-pass-find-match-matching-at-entry-name-part () |
| 82 | '(("foo")) | 82 | (auth-source-pass--with-store '(("foo")) |
| 83 | (should (equal (auth-source-pass--find-match "foo" nil) | 83 | (should (equal (auth-source-pass--find-match "https://foo" nil) |
| 84 | "foo"))) | 84 | "foo")))) |
| 85 | 85 | ||
| 86 | (auth-source-pass--deftest auth-source-pass-find-match-matching-at-entry-name-part () | 86 | (ert-deftest auth-source-pass-find-match-matching-at-entry-name-ignoring-user () |
| 87 | '(("foo")) | 87 | (auth-source-pass--with-store '(("foo")) |
| 88 | (should (equal (auth-source-pass--find-match "https://foo" nil) | 88 | (should (equal (auth-source-pass--find-match "https://SomeUser@foo" nil) |
| 89 | "foo"))) | 89 | "foo")))) |
| 90 | 90 | ||
| 91 | (auth-source-pass--deftest auth-source-pass-find-match-matching-at-entry-name-ignoring-user () | 91 | (ert-deftest auth-source-pass-find-match-matching-at-entry-name-with-user () |
| 92 | '(("foo")) | 92 | (auth-source-pass--with-store '(("SomeUser@foo")) |
| 93 | (should (equal (auth-source-pass--find-match "https://SomeUser@foo" nil) | 93 | (should (equal (auth-source-pass--find-match "https://SomeUser@foo" nil) |
| 94 | "foo"))) | 94 | "SomeUser@foo")))) |
| 95 | 95 | ||
| 96 | (auth-source-pass--deftest auth-source-pass-find-match-matching-at-entry-name-with-user () | 96 | (ert-deftest auth-source-pass-find-match-matching-at-entry-name-prefer-full () |
| 97 | '(("SomeUser@foo")) | 97 | (auth-source-pass--with-store '(("SomeUser@foo") ("foo")) |
| 98 | (should (equal (auth-source-pass--find-match "https://SomeUser@foo" nil) | 98 | (should (equal (auth-source-pass--find-match "https://SomeUser@foo" nil) |
| 99 | "SomeUser@foo"))) | 99 | "SomeUser@foo")))) |
| 100 | 100 | ||
| 101 | (auth-source-pass--deftest auth-source-pass-find-match-matching-at-entry-name-prefer-full () | 101 | (ert-deftest auth-source-pass-find-match-matching-at-entry-name-prefer-full-reversed () |
| 102 | '(("SomeUser@foo") ("foo")) | 102 | (auth-source-pass--with-store '(("foo") ("SomeUser@foo")) |
| 103 | (should (equal (auth-source-pass--find-match "https://SomeUser@foo" nil) | 103 | (should (equal (auth-source-pass--find-match "https://SomeUser@foo" nil) |
| 104 | "SomeUser@foo"))) | 104 | "SomeUser@foo")))) |
| 105 | 105 | ||
| 106 | ;; same as previous one except the store is in another order | 106 | (ert-deftest auth-source-pass-find-match-matching-at-entry-name-without-subdomain () |
| 107 | (auth-source-pass--deftest auth-source-pass-find-match-matching-at-entry-name-prefer-full-reversed () | 107 | (auth-source-pass--with-store '(("bar.com")) |
| 108 | '(("foo") ("SomeUser@foo")) | 108 | (should (equal (auth-source-pass--find-match "foo.bar.com" nil) |
| 109 | (should (equal (auth-source-pass--find-match "https://SomeUser@foo" nil) | 109 | "bar.com")))) |
| 110 | "SomeUser@foo"))) | 110 | |
| 111 | 111 | (ert-deftest auth-source-pass-find-match-matching-at-entry-name-without-subdomain-with-user () | |
| 112 | (auth-source-pass--deftest auth-source-pass-find-match-matching-at-entry-name-without-subdomain () | 112 | (auth-source-pass--with-store '(("someone@bar.com")) |
| 113 | '(("bar.com")) | 113 | (should (equal (auth-source-pass--find-match "foo.bar.com" "someone") |
| 114 | (should (equal (auth-source-pass--find-match "foo.bar.com" nil) | 114 | "someone@bar.com")))) |
| 115 | "bar.com"))) | 115 | |
| 116 | 116 | (ert-deftest auth-source-pass-find-match-matching-at-entry-name-without-subdomain-with-bad-user () | |
| 117 | (auth-source-pass--deftest auth-source-pass-find-match-matching-at-entry-name-without-subdomain-with-user () | 117 | (auth-source-pass--with-store '(("someoneelse@bar.com")) |
| 118 | '(("someone@bar.com")) | 118 | (should (equal (auth-source-pass--find-match "foo.bar.com" "someone") |
| 119 | (should (equal (auth-source-pass--find-match "foo.bar.com" "someone") | 119 | nil)))) |
| 120 | "someone@bar.com"))) | 120 | |
| 121 | 121 | (ert-deftest auth-source-pass-find-match-matching-at-entry-name-without-subdomain-prefer-full () | |
| 122 | (auth-source-pass--deftest auth-source-pass-find-match-matching-at-entry-name-without-subdomain-with-bad-user () | 122 | (auth-source-pass--with-store '(("bar.com") ("foo.bar.com")) |
| 123 | '(("someoneelse@bar.com")) | 123 | (should (equal (auth-source-pass--find-match "foo.bar.com" nil) |
| 124 | (should (equal (auth-source-pass--find-match "foo.bar.com" "someone") | 124 | "foo.bar.com")))) |
| 125 | nil))) | 125 | |
| 126 | 126 | (ert-deftest auth-source-pass-dont-match-at-folder-name () | |
| 127 | (auth-source-pass--deftest auth-source-pass-find-match-matching-at-entry-name-without-subdomain-prefer-full () | 127 | (auth-source-pass--with-store '(("foo.bar.com/foo")) |
| 128 | '(("bar.com") ("foo.bar.com")) | 128 | (should (equal (auth-source-pass--find-match "foo.bar.com" nil) |
| 129 | (should (equal (auth-source-pass--find-match "foo.bar.com" nil) | 129 | nil)))) |
| 130 | "foo.bar.com"))) | 130 | |
| 131 | 131 | (ert-deftest auth-source-pass-search-with-user-first () | |
| 132 | (auth-source-pass--deftest auth-source-pass-dont-match-at-folder-name () | 132 | (auth-source-pass--with-store '(("foo") ("user@foo")) |
| 133 | '(("foo.bar.com/foo")) | 133 | (should (equal (auth-source-pass--find-match "foo" "user") |
| 134 | (should (equal (auth-source-pass--find-match "foo.bar.com" nil) | 134 | "user@foo")) |
| 135 | nil))) | 135 | (auth-source-pass--should-have-message-containing "Found 1 match"))) |
| 136 | 136 | ||
| 137 | (auth-source-pass--deftest auth-source-pass-search-with-user-first () | 137 | (ert-deftest auth-source-pass-give-priority-to-desired-user () |
| 138 | '(("foo") ("user@foo")) | 138 | (auth-source-pass--with-store '(("foo") ("subdir/foo" ("user" . "someone"))) |
| 139 | (should (equal (auth-source-pass--find-match "foo" "user") | 139 | (should (equal (auth-source-pass--find-match "foo" "someone") |
| 140 | "user@foo")) | 140 | "subdir/foo")) |
| 141 | (auth-source-pass--should-have-message-containing "Found 1 match")) | 141 | (auth-source-pass--should-have-message-containing "Found 2 matches") |
| 142 | 142 | (auth-source-pass--should-have-message-containing "matching user field"))) | |
| 143 | (auth-source-pass--deftest auth-source-pass-give-priority-to-desired-user () | 143 | |
| 144 | '(("foo") ("subdir/foo" ("user" . "someone"))) | 144 | (ert-deftest auth-source-pass-give-priority-to-desired-user-reversed () |
| 145 | (should (equal (auth-source-pass--find-match "foo" "someone") | 145 | (auth-source-pass--with-store '(("foo" ("user" . "someone")) ("subdir/foo")) |
| 146 | "subdir/foo")) | 146 | (should (equal (auth-source-pass--find-match "foo" "someone") |
| 147 | (auth-source-pass--should-have-message-containing "Found 2 matches") | 147 | "foo")) |
| 148 | (auth-source-pass--should-have-message-containing "matching user field")) | 148 | (auth-source-pass--should-have-message-containing "Found 2 matches") |
| 149 | 149 | (auth-source-pass--should-have-message-containing "matching user field"))) | |
| 150 | (auth-source-pass--deftest auth-source-pass-give-priority-to-desired-user-reversed () | 150 | |
| 151 | '(("foo" ("user" . "someone")) ("subdir/foo")) | 151 | (ert-deftest auth-source-pass-return-first-when-several-matches () |
| 152 | (should (equal (auth-source-pass--find-match "foo" "someone") | 152 | (auth-source-pass--with-store '(("foo") ("subdir/foo")) |
| 153 | "foo")) | 153 | (should (equal (auth-source-pass--find-match "foo" nil) |
| 154 | (auth-source-pass--should-have-message-containing "Found 2 matches") | 154 | "foo")) |
| 155 | (auth-source-pass--should-have-message-containing "matching user field")) | 155 | (auth-source-pass--should-have-message-containing "Found 2 matches") |
| 156 | 156 | (auth-source-pass--should-have-message-containing "the first one"))) | |
| 157 | (auth-source-pass--deftest auth-source-pass-return-first-when-several-matches () | 157 | |
| 158 | '(("foo") ("subdir/foo")) | 158 | (ert-deftest auth-source-pass-make-divansantana-happy () |
| 159 | (should (equal (auth-source-pass--find-match "foo" nil) | 159 | (auth-source-pass--with-store '(("host.com")) |
| 160 | "foo")) | 160 | (should (equal (auth-source-pass--find-match "smtp.host.com" "myusername@host.co.za") |
| 161 | (auth-source-pass--should-have-message-containing "Found 2 matches") | 161 | "host.com")))) |
| 162 | (auth-source-pass--should-have-message-containing "the first one")) | ||
| 163 | |||
| 164 | (auth-source-pass--deftest auth-source-pass-make-divansantana-happy () | ||
| 165 | '(("host.com")) | ||
| 166 | (should (equal (auth-source-pass--find-match "smtp.host.com" "myusername@host.co.za") | ||
| 167 | "host.com"))) | ||
| 168 | 162 | ||
| 169 | (ert-deftest auth-source-pass-hostname () | 163 | (ert-deftest auth-source-pass-hostname () |
| 170 | (should (equal (auth-source-pass--hostname "https://foo.bar") "foo.bar")) | 164 | (should (equal (auth-source-pass--hostname "https://foo.bar") "foo.bar")) |
| @@ -176,37 +170,32 @@ test code without touching the file system." | |||
| 176 | (should (equal (auth-source-pass--hostname-with-user "http://foo.bar") "foo.bar")) | 170 | (should (equal (auth-source-pass--hostname-with-user "http://foo.bar") "foo.bar")) |
| 177 | (should (equal (auth-source-pass--hostname-with-user "https://SomeUser@foo.bar") "SomeUser@foo.bar"))) | 171 | (should (equal (auth-source-pass--hostname-with-user "https://SomeUser@foo.bar") "SomeUser@foo.bar"))) |
| 178 | 172 | ||
| 179 | (defmacro auth-source-pass--deftest-build-result (name arglist store &rest body) | 173 | (defmacro auth-source-pass--with-store-find-foo (store &rest body) |
| 180 | "Define a new ert-test NAME with ARGLIST using STORE as password-store. | 174 | "Use STORE while executing BODY. \"foo\" is the matched entry." |
| 181 | BODY is a sequence of instructions that will be evaluated. | 175 | (declare (indent 1)) |
| 182 | 176 | `(auth-source-pass--with-store ,store | |
| 183 | This macro overrides `auth-source-pass-parse-entry', | ||
| 184 | `auth-source-pass-entries', and `auth-source-pass--find-match' to | ||
| 185 | ease testing." | ||
| 186 | (declare (indent 3)) | ||
| 187 | `(auth-source-pass--deftest ,name ,arglist ,store | ||
| 188 | (cl-letf (((symbol-function 'auth-source-pass-find-match) | 177 | (cl-letf (((symbol-function 'auth-source-pass-find-match) |
| 189 | (lambda (_host _user) | 178 | (lambda (_host _user) |
| 190 | "foo"))) | 179 | "foo"))) |
| 191 | ,@body))) | 180 | ,@body))) |
| 192 | 181 | ||
| 193 | (auth-source-pass--deftest-build-result auth-source-pass-build-result-return-parameters () | 182 | (ert-deftest auth-source-pass-build-result-return-parameters () |
| 194 | '(("foo")) | 183 | (auth-source-pass--with-store-find-foo '(("foo")) |
| 195 | (let ((result (auth-source-pass--build-result "foo" 512 "user"))) | 184 | (let ((result (auth-source-pass--build-result "foo" 512 "user"))) |
| 196 | (should (equal (plist-get result :port) 512)) | 185 | (should (equal (plist-get result :port) 512)) |
| 197 | (should (equal (plist-get result :user) "user")))) | 186 | (should (equal (plist-get result :user) "user"))))) |
| 198 | 187 | ||
| 199 | (auth-source-pass--deftest-build-result auth-source-pass-build-result-return-entry-values () | 188 | (ert-deftest auth-source-pass-build-result-return-entry-values () |
| 200 | '(("foo" ("port" . 512) ("user" . "anuser"))) | 189 | (auth-source-pass--with-store-find-foo '(("foo" ("port" . 512) ("user" . "anuser"))) |
| 201 | (let ((result (auth-source-pass--build-result "foo" nil nil))) | 190 | (let ((result (auth-source-pass--build-result "foo" nil nil))) |
| 202 | (should (equal (plist-get result :port) 512)) | 191 | (should (equal (plist-get result :port) 512)) |
| 203 | (should (equal (plist-get result :user) "anuser")))) | 192 | (should (equal (plist-get result :user) "anuser"))))) |
| 204 | 193 | ||
| 205 | (auth-source-pass--deftest-build-result auth-source-pass-build-result-entry-takes-precedence () | 194 | (ert-deftest auth-source-pass-build-result-entry-takes-precedence () |
| 206 | '(("foo" ("port" . 512) ("user" . "anuser"))) | 195 | (auth-source-pass--with-store-find-foo '(("foo" ("port" . 512) ("user" . "anuser"))) |
| 207 | (let ((result (auth-source-pass--build-result "foo" 1024 "anotheruser"))) | 196 | (let ((result (auth-source-pass--build-result "foo" 1024 "anotheruser"))) |
| 208 | (should (equal (plist-get result :port) 512)) | 197 | (should (equal (plist-get result :port) 512)) |
| 209 | (should (equal (plist-get result :user) "anuser")))) | 198 | (should (equal (plist-get result :user) "anuser"))))) |
| 210 | 199 | ||
| 211 | (ert-deftest auth-source-pass-only-return-entries-that-can-be-open () | 200 | (ert-deftest auth-source-pass-only-return-entries-that-can-be-open () |
| 212 | (cl-letf (((symbol-function 'auth-source-pass-entries) | 201 | (cl-letf (((symbol-function 'auth-source-pass-entries) |
| @@ -220,7 +209,7 @@ ease testing." | |||
| 220 | '("foo.site.com"))) | 209 | '("foo.site.com"))) |
| 221 | (should (equal (auth-source-pass--find-all-by-entry-name "bar.site.com" "someuser") | 210 | (should (equal (auth-source-pass--find-all-by-entry-name "bar.site.com" "someuser") |
| 222 | '())) | 211 | '())) |
| 223 | (should (equal (auth-pass--find-all-by-entry-name "baz.site.com" "scott") | 212 | (should (equal (auth-source-pass--find-all-by-entry-name "baz.site.com" "scott") |
| 224 | '("mail/baz.site.com/scott"))))) | 213 | '("mail/baz.site.com/scott"))))) |
| 225 | 214 | ||
| 226 | (ert-deftest auth-source-pass-entry-is-not-valid-when-unreadable () | 215 | (ert-deftest auth-source-pass-entry-is-not-valid-when-unreadable () |