aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorF. Jason Park2022-11-01 22:46:24 -0700
committerF. Jason Park2022-11-16 21:34:36 -0800
commit2cf9e699ef0fc43a4eadaf00a1ed2f876765c64d (patch)
treec01e9bdcd25372207f94650315d1596ae445454d /test
parent0147e1ed831151dddac65727886d5a70bbab9f02 (diff)
downloademacs-2cf9e699ef0fc43a4eadaf00a1ed2f876765c64d.tar.gz
emacs-2cf9e699ef0fc43a4eadaf00a1ed2f876765c64d.zip
Make auth-source-pass behave more like other backends
* lisp/auth-source-pass.el (auth-source-pass-extra-query-keywords): Add new option to bring search behavior more in line with other backends. (auth-source-pass-search): Add new keyword params `max' and `require' and consider new option `auth-source-pass-extra-query-keywords' for dispatch. (auth-source-pass--match-regexp, auth-source-pass--retrieve-parsed, auth-source-pass--match-parts): Add supporting variable and helpers. (auth-source-pass--build-result-many, auth-source-pass--find-match-many): Add "-many" variants for existing workhorse functions. * test/lisp/auth-source-pass-tests.el: Require `ert-x'. (auth-source-pass-can-start-from-auth-source-search): Ensure `auth-source-pass-extra-query-keywords' is enabled around test body. (auth-source-pass-extra-query-keywords--wild-port-miss-netrc, auth-source-pass-extra-query-keywords--wild-port-miss, auth-source-pass-extra-query-keywords--wild-port-hit-netrc, auth-source-pass-extra-query-keywords--wild-port-hit, auth-source-pass-extra-query-keywords--wild-port-req-miss-netrc, auth-source-pass-extra-query-keywords--wild-port-req-miss, auth-source-pass-extra-query-keywords--netrc-akib, auth-source-pass-extra-query-keywords--akib, auth-source-pass-extra-query-keywords--netrc-host, auth-source-pass-extra-query-keywords--host, auth-source-pass-extra-query-keywords--baseline, auth-source-pass-extra-query-keywords--port-type, auth-source-pass-extra-query-keywords--hosts-first, auth-source-pass-extra-query-keywords--ambiguous-user-host, auth-source-pass-extra-query-keywords--suffixed-user, auth-source-pass-extra-query-keywords--user-priorities): Add juxtaposed netrc and extra-query-keywords pairs to demo optional extra-compliant behavior. * doc/misc/auth.texi: Add option `auth-source-pass-extra-query-keywords' to auth-source-pass section. * etc/NEWS: Mention `auth-source-pass-extra-query-keywords' in Emacs 29.1 package changes section. (Bug#58985.) Special thanks to Akib Azmain Turja <akib@disroot.org> for helping improve this patch.
Diffstat (limited to 'test')
-rw-r--r--test/lisp/auth-source-pass-tests.el267
1 files changed, 265 insertions, 2 deletions
diff --git a/test/lisp/auth-source-pass-tests.el b/test/lisp/auth-source-pass-tests.el
index f5147a7ce07..8bcb2739bb3 100644
--- a/test/lisp/auth-source-pass-tests.el
+++ b/test/lisp/auth-source-pass-tests.el
@@ -25,7 +25,7 @@
25 25
26;;; Code: 26;;; Code:
27 27
28(require 'ert) 28(require 'ert-x)
29 29
30(require 'auth-source-pass) 30(require 'auth-source-pass)
31 31
@@ -466,7 +466,10 @@ HOSTNAME, USER and PORT are passed unchanged to
466(ert-deftest auth-source-pass-can-start-from-auth-source-search () 466(ert-deftest auth-source-pass-can-start-from-auth-source-search ()
467 (auth-source-pass--with-store '(("gitlab.com" ("user" . "someone"))) 467 (auth-source-pass--with-store '(("gitlab.com" ("user" . "someone")))
468 (auth-source-pass-enable) 468 (auth-source-pass-enable)
469 (let ((result (car (auth-source-search :host "gitlab.com")))) 469 ;; This also asserts an aspect of traditional search behavior
470 ;; relative to `auth-source-pass-extra-query-keywords'.
471 (let* ((auth-source-pass-extra-query-keywords nil)
472 (result (car (auth-source-search :host "gitlab.com"))))
470 (should (equal (plist-get result :user) "someone")) 473 (should (equal (plist-get result :user) "someone"))
471 (should (equal (plist-get result :host) "gitlab.com"))))) 474 (should (equal (plist-get result :host) "gitlab.com")))))
472 475
@@ -488,6 +491,266 @@ HOSTNAME, USER and PORT are passed unchanged to
488 (should (auth-source-pass--have-message-matching 491 (should (auth-source-pass--have-message-matching
489 "found 2 entries matching \"gitlab.com\": (\"a/gitlab.com\" \"b/gitlab.com\")")))) 492 "found 2 entries matching \"gitlab.com\": (\"a/gitlab.com\" \"b/gitlab.com\")"))))
490 493
494
495;;;; Option `auth-source-pass-extra-query-keywords' (bug#58985)
496
497;; No entry has the requested port, but a result is still returned.
498
499(ert-deftest auth-source-pass-extra-query-keywords--wild-port-miss-netrc ()
500 (ert-with-temp-file netrc-file
501 :text "\
502machine x.com password a
503machine x.com port 42 password b
504"
505 (let* ((auth-sources (list netrc-file))
506 (auth-source-do-cache nil)
507 (results (auth-source-search :host "x.com" :port 22 :max 2)))
508 (dolist (result results)
509 (setf (plist-get result :secret) (auth-info-password result)))
510 (should (equal results '((:host "x.com" :secret "a")))))))
511
512(ert-deftest auth-source-pass-extra-query-keywords--wild-port-miss ()
513 (auth-source-pass--with-store '(("x.com" (secret . "a"))
514 ("x.com:42" (secret . "b")))
515 (auth-source-pass-enable)
516 (let* ((auth-source-pass-extra-query-keywords t)
517 (results (auth-source-search :host "x.com" :port 22 :max 2)))
518 (dolist (result results)
519 (setf (plist-get result :secret) (auth-info-password result)))
520 (should (equal results '((:host "x.com" :secret "a")))))))
521
522;; One of two entries has the requested port, both returned.
523
524(ert-deftest auth-source-pass-extra-query-keywords--wild-port-hit-netrc ()
525 (ert-with-temp-file netrc-file
526 :text "\
527machine x.com password a
528machine x.com port 42 password b
529"
530 (let* ((auth-sources (list netrc-file))
531 (auth-source-do-cache nil)
532 (results (auth-source-search :host "x.com" :port 42 :max 2)))
533 (dolist (result results)
534 (setf (plist-get result :secret) (auth-info-password result)))
535 (should (equal results '((:host "x.com" :secret "a")
536 (:host "x.com" :port "42" :secret "b")))))))
537
538(ert-deftest auth-source-pass-extra-query-keywords--wild-port-hit ()
539 (auth-source-pass--with-store '(("x.com" (secret . "a"))
540 ("x.com:42" (secret . "b")))
541 (auth-source-pass-enable)
542 (let* ((auth-source-pass-extra-query-keywords t)
543 (results (auth-source-search :host "x.com" :port 42 :max 2)))
544 (dolist (result results)
545 (setf (plist-get result :secret) (auth-info-password result)))
546 (should (equal results
547 '((:host "x.com" :secret "a")
548 (:host "x.com" :port 42 :secret "b")))))))
549
550;; No entry has the requested port, but :port is required, so search fails.
551
552(ert-deftest auth-source-pass-extra-query-keywords--wild-port-req-miss-netrc ()
553 (ert-with-temp-file netrc-file
554 :text "\
555machine x.com password a
556machine x.com port 42 password b
557"
558 (let* ((auth-sources (list netrc-file))
559 (auth-source-do-cache nil)
560 (results (auth-source-search
561 :host "x.com" :port 22 :require '(:port) :max 2)))
562 (should-not results))))
563
564(ert-deftest auth-source-pass-extra-query-keywords--wild-port-req-miss ()
565 (let ((auth-source-pass-extra-query-keywords t))
566 (auth-source-pass--with-store '(("x.com" (secret . "a"))
567 ("x.com:42" (secret . "b")))
568 (auth-source-pass-enable)
569 (should-not (auth-source-search
570 :host "x.com" :port 22 :require '(:port) :max 2)))))
571
572;; Specifying a :host without a :user finds a lone entry and does not
573;; include extra fields (i.e., :port nil) in the result.
574;; https://lists.gnu.org/archive/html/emacs-devel/2022-11/msg00130.html
575
576(ert-deftest auth-source-pass-extra-query-keywords--netrc-akib ()
577 (ert-with-temp-file netrc-file
578 :text "\
579machine x.com password a
580machine disroot.org user akib password b
581machine z.com password c
582"
583 (let* ((auth-sources (list netrc-file))
584 (auth-source-do-cache nil)
585 (results (auth-source-search :host "disroot.org" :max 2)))
586 (dolist (result results)
587 (setf (plist-get result :secret) (auth-info-password result)))
588 (should (equal results
589 '((:host "disroot.org" :user "akib" :secret "b")))))))
590
591(ert-deftest auth-source-pass-extra-query-keywords--akib ()
592 (auth-source-pass--with-store '(("x.com" (secret . "a"))
593 ("akib@disroot.org" (secret . "b"))
594 ("z.com" (secret . "c")))
595 (auth-source-pass-enable)
596 (let* ((auth-source-pass-extra-query-keywords t)
597 (results (auth-source-search :host "disroot.org" :max 2)))
598 (dolist (result results)
599 (setf (plist-get result :secret) (auth-info-password result)))
600 (should (equal results
601 '((:host "disroot.org" :user "akib" :secret "b")))))))
602
603;; Searches for :host are case-sensitive, and a returned host isn't
604;; normalized.
605
606(ert-deftest auth-source-pass-extra-query-keywords--netrc-host ()
607 (ert-with-temp-file netrc-file
608 :text "\
609machine libera.chat password a
610machine Libera.Chat password b
611"
612 (let* ((auth-sources (list netrc-file))
613 (auth-source-do-cache nil)
614 (results (auth-source-search :host "Libera.Chat" :max 2)))
615 (dolist (result results)
616 (setf (plist-get result :secret) (auth-info-password result)))
617 (should (equal results '((:host "Libera.Chat" :secret "b")))))))
618
619(ert-deftest auth-source-pass-extra-query-keywords--host ()
620 (auth-source-pass--with-store '(("libera.chat" (secret . "a"))
621 ("Libera.Chat" (secret . "b")))
622 (auth-source-pass-enable)
623 (let* ((auth-source-pass-extra-query-keywords t)
624 (results (auth-source-search :host "Libera.Chat" :max 2)))
625 (dolist (result results)
626 (setf (plist-get result :secret) (auth-info-password result)))
627 (should (equal results
628 '((:host "Libera.Chat" :secret "b")))))))
629
630
631;; A retrieved store entry mustn't be nil regardless of whether its
632;; path contains port or user components.
633
634(ert-deftest auth-source-pass-extra-query-keywords--baseline ()
635 (let ((auth-source-pass-extra-query-keywords t))
636 (auth-source-pass--with-store '(("x.com"))
637 (auth-source-pass-enable)
638 (should-not (auth-source-search :host "x.com")))))
639
640;; Output port type (int or string) matches that of input parameter.
641
642(ert-deftest auth-source-pass-extra-query-keywords--port-type ()
643 (let ((auth-source-pass-extra-query-keywords t)
644 (f (lambda (r) (setf (plist-get r :secret) (auth-info-password r)) r)))
645 (auth-source-pass--with-store '(("x.com:42" (secret . "a")))
646 (auth-source-pass-enable)
647 (should (equal (mapcar f (auth-source-search :host "x.com" :port 42))
648 '((:host "x.com" :port 42 :secret "a")))))
649 (auth-source-pass--with-store '(("x.com:42" (secret . "a")))
650 (auth-source-pass-enable)
651 (should (equal (mapcar f (auth-source-search :host "x.com" :port "42"))
652 '((:host "x.com" :port "42" :secret "a")))))))
653
654;; Match precision sometimes takes a back seat to the traversal
655;; ordering. Specifically, the :host (h1, ...) args hold greater sway
656;; over the output because they determine the first coordinate in the
657;; sequence of (host, user, port) combinations visited. (Taking a
658;; tree-wise view, these become the depth-1 nodes in a DFS.)
659
660;; Note that all trailing /user forms are demoted for the sake of
661;; predictability (see tests further below for details). This means
662;; that, in the following test, /bar is held in limbo, followed by
663;; /foo, but they both retain priority over "gnu.org", as noted above.
664
665(ert-deftest auth-source-pass-extra-query-keywords--hosts-first ()
666 (auth-source-pass--with-store '(("x.com:42/bar" (secret . "a"))
667 ("gnu.org" (secret . "b"))
668 ("x.com" (secret . "c"))
669 ("fake.com" (secret . "d"))
670 ("x.com/foo" (secret . "e")))
671 (auth-source-pass-enable)
672 (let* ((auth-source-pass-extra-query-keywords t)
673 (results (auth-source-search :host '("x.com" "gnu.org") :max 3)))
674 (dolist (result results)
675 (setf (plist-get result :secret) (auth-info-password result)))
676 (should (equal results
677 ;; Notice gnu.org is never considered ^
678 '((:host "x.com" :secret "c")
679 (:host "x.com" :user "bar" :port "42" :secret "a")
680 (:host "x.com" :user "foo" :secret "e")))))))
681
682;; This is another example given in the bug thread.
683
684(ert-deftest auth-source-pass-extra-query-keywords--ambiguous-user-host ()
685 (auth-source-pass--with-store '(("foo.com/bar.org" (secret . "a"))
686 ("foo.com" (secret . "b"))
687 ("bar.org" (secret . "c"))
688 ("fake.com" (secret . "d")))
689 (auth-source-pass-enable)
690 (let* ((auth-source-pass-extra-query-keywords t)
691 (results (auth-source-search :host "bar.org" :max 3)))
692 (dolist (result results)
693 (setf (plist-get result :secret) (auth-info-password result)))
694 (should (equal results '((:host "bar.org" :secret "c")))))))
695
696;; This conveys the same idea as `user-priorities', just below, but
697;; with slightly more realistic and less legible values.
698
699(ert-deftest auth-source-pass-extra-query-keywords--suffixed-user ()
700 (let ((store (sort (copy-sequence '(("x.com:42/bar" (secret . "a"))
701 ("bar@x.com" (secret . "b"))
702 ("x.com" (secret . "?"))
703 ("bar@y.org" (secret . "c"))
704 ("fake.com" (secret . "?"))
705 ("fake.com/bar" (secret . "d"))
706 ("y.org/bar" (secret . "?"))
707 ("bar@fake.com" (secret . "e"))))
708 (lambda (&rest _) (zerop (random 2))))))
709 (auth-source-pass--with-store store
710 (auth-source-pass-enable)
711 (let* ((auth-source-pass-extra-query-keywords t)
712 (results (auth-source-search :host '("x.com" "fake.com" "y.org")
713 :user "bar"
714 :require '(:user) :max 5)))
715 (dolist (result results)
716 (setf (plist-get result :secret) (auth-info-password result)))
717 (should (equal results
718 '((:host "x.com" :user "bar" :secret "b")
719 (:host "x.com" :user "bar" :port "42" :secret "a")
720 (:host "fake.com" :user "bar" :secret "e")
721 (:host "fake.com" :user "bar" :secret "d")
722 (:host "y.org" :user "bar" :secret "c"))))))))
723
724;; This is a more distilled version of `suffixed-user', above. It
725;; better illustrates that search order takes precedence over "/user"
726;; demotion because otherwise * and ** would be swapped, below. It
727;; follows that omitting the :port 2, gets you {u@h:1, u@h:2, h:1/u,
728;; h:2/u, u@g:1}.
729
730(ert-deftest auth-source-pass-extra-query-keywords--user-priorities ()
731 (let ((store (sort (copy-sequence '(("h:1/u" (secret . "/"))
732 ("h:2/u" (secret . "/"))
733 ("u@h:1" (secret . "@"))
734 ("u@h:2" (secret . "@"))
735 ("g:1/u" (secret . "/"))
736 ("g:2/u" (secret . "/"))
737 ("u@g:1" (secret . "@"))
738 ("u@g:2" (secret . "@"))))
739 (lambda (&rest _) (zerop (random 2))))))
740 (auth-source-pass--with-store store
741 (auth-source-pass-enable)
742 (let* ((auth-source-pass-extra-query-keywords t)
743 (results (auth-source-search :host '("h" "g")
744 :port 2
745 :max 5)))
746 (dolist (result results)
747 (setf (plist-get result :secret) (auth-info-password result)))
748 (should (equal results
749 '((:host "h" :user "u" :port 2 :secret "@")
750 (:host "h" :user "u" :port 2 :secret "/") ; *
751 (:host "g" :user "u" :port 2 :secret "@") ; **
752 (:host "g" :user "u" :port 2 :secret "/"))))))))
753
491(provide 'auth-source-pass-tests) 754(provide 'auth-source-pass-tests)
492 755
493;;; auth-source-pass-tests.el ends here 756;;; auth-source-pass-tests.el ends here