aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorF. Jason Park2024-08-11 21:55:32 -0700
committerF. Jason Park2024-09-06 16:02:12 -0700
commit80228d1f6eded7a042dfd29c3614b3214934b5c3 (patch)
tree9e861a33f1403b71725841d0884edf7cd4be4154
parent6cc87d07dd8aea1d1a1669df51a872adb7ccf9c5 (diff)
downloademacs-80228d1f6eded7a042dfd29c3614b3214934b5c3.tar.gz
emacs-80228d1f6eded7a042dfd29c3614b3214934b5c3.zip
Fix discrepancies in auth-source-pass vs netrc behavior
The option `auth-source-pass-extra-query-keywords' aims to make its back end hew as close to the other built-in ones as possible, except WRT features not yet implemented, such as arbitrary "attribute" retrieval and new entry creation. This change only concerns behavior exhibited when the option is enabled. * lisp/auth-source-pass.el (auth-source-pass--match-parts): Account for the case in which a query lacks a reference parameter for a `:port' or `:user' but still requires one or both via the `:require' keyword. Previously, such a query would fail even when an entry met this requirement by simply specifying a field with any non-null value corresponding to the required parameter. (auth-source-pass--find-match-many): Account for the baseline case where a matching entry lacks a secret and the user doesn't require one. Although this function doesn't currently return so-called "attributes" from the contents of a matching decrypted file, were it to eventually, this case would no longer be academic. * test/lisp/auth-source-pass-tests.el (auth-source-pass-extra-query-keywords--req-noparam-miss-netrc) (auth-source-pass-extra-query-keywords--req-noparam-miss) (auth-source-pass-extra-query-keywords--req-param-netrc) (auth-source-pass-extra-query-keywords--req-param): New tests. (auth-source-pass-extra-query-keywords--netrc-baseline): New test asserting behavior of netrc backend when passed a lone `:host' as a query parameter. (auth-source-pass-extra-query-keywords--baseline): Reverse expected outcome to match that of the netrc reference implementation. (bug#72441)
-rw-r--r--lisp/auth-source-pass.el19
-rw-r--r--test/lisp/auth-source-pass-tests.el54
2 files changed, 60 insertions, 13 deletions
diff --git a/lisp/auth-source-pass.el b/lisp/auth-source-pass.el
index 03fd1f35811..dd93d414d5e 100644
--- a/lisp/auth-source-pass.el
+++ b/lisp/auth-source-pass.el
@@ -271,11 +271,12 @@ HOSTS can be a string or a list of strings."
271 n))) 271 n)))
272 seen))) 272 seen)))
273 273
274(defun auth-source-pass--match-parts (parts key value require) 274(defun auth-source-pass--match-parts (cache key reference require)
275 (let ((mv (plist-get parts key))) 275 (let ((value (plist-get cache key)))
276 (if (memq key require) 276 (cond ((memq key require)
277 (and value (equal mv value)) 277 (if reference (equal value reference) value))
278 (or (not value) (not mv) (equal mv value))))) 278 ((and value reference) (equal value reference))
279 (t))))
279 280
280(defun auth-source-pass--find-match-many (hosts users ports require max) 281(defun auth-source-pass--find-match-many (hosts users ports require max)
281 "Return plists for valid combinations of HOSTS, USERS, PORTS." 282 "Return plists for valid combinations of HOSTS, USERS, PORTS."
@@ -290,17 +291,17 @@ HOSTS can be a string or a list of strings."
290 (dolist (user (or users (list u))) 291 (dolist (user (or users (list u)))
291 (dolist (port (or ports (list p))) 292 (dolist (port (or ports (list p)))
292 (dolist (e entries) 293 (dolist (e entries)
293 (when-let* 294 (when-let
294 ((m (or (gethash e seen) (auth-source-pass--retrieve-parsed 295 ((m (or (gethash e seen) (auth-source-pass--retrieve-parsed
295 seen e (integerp port)))) 296 seen e (integerp port))))
296 ((equal host (plist-get m :host))) 297 ((equal host (plist-get m :host)))
297 ((auth-source-pass--match-parts m :port port require)) 298 ((auth-source-pass--match-parts m :port port require))
298 ((auth-source-pass--match-parts m :user user require)) 299 ((auth-source-pass--match-parts m :user user require))
299 (parsed (auth-source-pass-parse-entry e))
300 ;; For now, ignore body-content pairs, if any, 300 ;; For now, ignore body-content pairs, if any,
301 ;; from `auth-source-pass--parse-data'. 301 ;; from `auth-source-pass--parse-data'.
302 (secret (or (auth-source-pass--get-attr 'secret parsed) 302 (secret (let ((parsed (auth-source-pass-parse-entry e)))
303 (not (memq :secret require))))) 303 (or (auth-source-pass--get-attr 'secret parsed)
304 (not (memq :secret require))))))
304 (push 305 (push
305 `( :host ,host ; prefer user-provided :host over h 306 `( :host ,host ; prefer user-provided :host over h
306 ,@(and-let* ((u (plist-get m :user))) (list :user u)) 307 ,@(and-let* ((u (plist-get m :user))) (list :user u))
diff --git a/test/lisp/auth-source-pass-tests.el b/test/lisp/auth-source-pass-tests.el
index 6455c3393d5..c54936c3f92 100644
--- a/test/lisp/auth-source-pass-tests.el
+++ b/test/lisp/auth-source-pass-tests.el
@@ -548,6 +548,44 @@ machine x.com port 42 password b
548 '((:host "x.com" :secret "a") 548 '((:host "x.com" :secret "a")
549 (:host "x.com" :port 42 :secret "b"))))))) 549 (:host "x.com" :port 42 :secret "b")))))))
550 550
551;; The query requires a user and doesn't specify a user to match against.
552;; The only entry matching the host lacks a user, so the search fails.
553
554(ert-deftest auth-source-pass-extra-query-keywords--req-noparam-miss-netrc ()
555 (ert-with-temp-file netrc-file
556 :text "machine foo password a\n"
557 (let ((auth-sources (list netrc-file))
558 (auth-source-do-cache nil))
559 (should-not (auth-source-search :host "foo" :require '(:user) :max 2)))))
560
561(ert-deftest auth-source-pass-extra-query-keywords--req-noparam-miss ()
562 (let ((auth-source-pass-extra-query-keywords t))
563 (auth-source-pass--with-store '(("foo" (secret . "a")))
564 (auth-source-pass-enable)
565 (should-not (auth-source-search :host "foo" :require '(:user) :max 2)))))
566
567;; The query requires a user but does not provide a reference value to
568;; match against. An entry matching the host that specifies a user is
569;; selected because any user will do.
570(ert-deftest auth-source-pass-extra-query-keywords--req-param-netrc ()
571 (ert-with-temp-file netrc-file
572 :text "machine foo login bob password a\n"
573 (let* ((auth-sources (list netrc-file))
574 (auth-source-do-cache nil)
575 (results (auth-source-search :host "foo" :require '(:user))))
576 (dolist (result results)
577 (setf (plist-get result :secret) (auth-info-password result)))
578 (should (equal results '((:host "foo" :user "bob" :secret "a")))))))
579
580(ert-deftest auth-source-pass-extra-query-keywords--req-param ()
581 (let ((auth-source-pass-extra-query-keywords t))
582 (auth-source-pass--with-store '(("foo/bob" (secret . "a")))
583 (auth-source-pass-enable)
584 (let ((results (auth-source-search :host "foo" :require '(:user))))
585 (dolist (result results)
586 (setf (plist-get result :secret) (auth-info-password result)))
587 (should (equal results '((:host "foo" :user "bob" :secret "a"))))))))
588
551;; No entry has the requested port, but :port is required, so search fails. 589;; No entry has the requested port, but :port is required, so search fails.
552 590
553(ert-deftest auth-source-pass-extra-query-keywords--wild-port-req-miss-netrc () 591(ert-deftest auth-source-pass-extra-query-keywords--wild-port-req-miss-netrc ()
@@ -629,14 +667,22 @@ machine Libera.Chat password b
629 '((:host "Libera.Chat" :secret "b"))))))) 667 '((:host "Libera.Chat" :secret "b")))))))
630 668
631 669
632;; A retrieved store entry mustn't be nil regardless of whether its 670;; An effectively empty entry in the store returns nothing but the
633;; path contains port or user components. 671;; :host field matching the given host parameter.
672
673(ert-deftest auth-source-pass-extra-query-keywords--netrc-baseline ()
674 (ert-with-temp-file netrc-file
675 :text "machine foo\n"
676 (let* ((auth-sources (list netrc-file))
677 (auth-source-do-cache nil)
678 (results (auth-source-search :host "foo")))
679 (should (equal results '((:host "foo")))))))
634 680
635(ert-deftest auth-source-pass-extra-query-keywords--baseline () 681(ert-deftest auth-source-pass-extra-query-keywords--baseline ()
636 (let ((auth-source-pass-extra-query-keywords t)) 682 (let ((auth-source-pass-extra-query-keywords t))
637 (auth-source-pass--with-store '(("x.com")) 683 (auth-source-pass--with-store '(("foo"))
638 (auth-source-pass-enable) 684 (auth-source-pass-enable)
639 (should-not (auth-source-search :host "x.com"))))) 685 (should (equal (auth-source-search :host "foo") '((:host "foo")))))))
640 686
641;; Output port type (int or string) matches that of input parameter. 687;; Output port type (int or string) matches that of input parameter.
642 688