aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Zlatanov2017-02-03 16:06:12 -0500
committerTed Zlatanov2017-04-27 17:37:58 -0400
commitbd60ee2ffc37b64a898d81184089b82afd55cae0 (patch)
tree7a9158a656ccd2ed62c58f1780996f7d71783ea5
parent79c5ea9911a9aba7db0ba0e367e06507cee2fc02 (diff)
downloademacs-bd60ee2ffc37b64a898d81184089b82afd55cae0.tar.gz
emacs-bd60ee2ffc37b64a898d81184089b82afd55cae0.zip
auth-source: factor out parsers and add tests
* lisp/auth-source.el: Factor out the source parsers. Clean up comments. * test/lisp/auth-source-tests.el: Add tests.
-rw-r--r--lisp/auth-source.el349
-rw-r--r--test/lisp/auth-source-tests.el45
2 files changed, 165 insertions, 229 deletions
diff --git a/lisp/auth-source.el b/lisp/auth-source.el
index 7402ab21d74..5ad42772f94 100644
--- a/lisp/auth-source.el
+++ b/lisp/auth-source.el
@@ -317,25 +317,6 @@ If the value is not a list, symmetric encryption will be used."
317 (repeat :tag "Recipient public keys" 317 (repeat :tag "Recipient public keys"
318 (string :tag "Recipient public key")))) 318 (string :tag "Recipient public key"))))
319 319
320;; temp for debugging
321;; (unintern 'auth-source-protocols)
322;; (unintern 'auth-sources)
323;; (customize-variable 'auth-sources)
324;; (setq auth-sources nil)
325;; (format "%S" auth-sources)
326;; (customize-variable 'auth-source-protocols)
327;; (setq auth-source-protocols nil)
328;; (format "%S" auth-source-protocols)
329;; (auth-source-pick nil :host "a" :port 'imap)
330;; (auth-source-user-or-password "login" "imap.myhost.com" 'imap)
331;; (auth-source-user-or-password "password" "imap.myhost.com" 'imap)
332;; (auth-source-user-or-password-imap "login" "imap.myhost.com")
333;; (auth-source-user-or-password-imap "password" "imap.myhost.com")
334;; (auth-source-protocol-defaults 'imap)
335
336;; (let ((auth-source-debug 'debug)) (auth-source-do-debug "hello"))
337;; (let ((auth-source-debug t)) (auth-source-do-debug "hello"))
338;; (let ((auth-source-debug nil)) (auth-source-do-debug "hello"))
339(defun auth-source-do-debug (&rest msg) 320(defun auth-source-do-debug (&rest msg)
340 (when auth-source-debug 321 (when auth-source-debug
341 (apply #'auth-source-do-warn msg))) 322 (apply #'auth-source-do-warn msg)))
@@ -354,8 +335,6 @@ If the value is not a list, symmetric encryption will be used."
354 'message) 335 'message)
355 msg)) 336 msg))
356 337
357
358;; (auth-source-read-char-choice "enter choice? " '(?a ?b ?q))
359(defun auth-source-read-char-choice (prompt choices) 338(defun auth-source-read-char-choice (prompt choices)
360 "Read one of CHOICES by `read-char-choice', or `read-char'. 339 "Read one of CHOICES by `read-char-choice', or `read-char'.
361`dropdown-list' support is disabled because it doesn't work reliably. 340`dropdown-list' support is disabled because it doesn't work reliably.
@@ -373,152 +352,147 @@ with \"[a/b/c] \" if CHOICES is \(?a ?b ?c)."
373 (setq k (read-char-choice full-prompt choices))) 352 (setq k (read-char-choice full-prompt choices)))
374 k))) 353 k)))
375 354
376;; (auth-source-pick nil :host "any" :port 'imap :user "joe") 355(defvar auth-source-backend-parser-functions nil
377;; (auth-source-pick t :host "any" :port 'imap :user "joe") 356 "List of auth-source parser functions
378;; (setq auth-sources '((:source (:secrets default) :host t :port t :user "joe") 357These functions return backends from an entry in `auth-sources'.
379;; (:source (:secrets "session") :host t :port t :user "joe") 358Add your backends to this list with `add-hook'.")
380;; (:source (:secrets "Login") :host t :port t)
381;; (:source "~/.authinfo.gpg" :host t :port t)))
382
383;; (setq auth-sources '((:source (:secrets default) :host t :port t :user "joe")
384;; (:source (:secrets "session") :host t :port t :user "joe")
385;; (:source (:secrets "Login") :host t :port t)
386;; ))
387
388;; (setq auth-sources '((:source "~/.authinfo.gpg" :host t :port t)))
389
390;; (auth-source-backend-parse "myfile.gpg")
391;; (auth-source-backend-parse 'default)
392;; (auth-source-backend-parse "secrets:Login")
393;; (auth-source-backend-parse 'macos-keychain-internet)
394;; (auth-source-backend-parse 'macos-keychain-generic)
395;; (auth-source-backend-parse "macos-keychain-internet:/path/here.keychain")
396;; (auth-source-backend-parse "macos-keychain-generic:/path/here.keychain")
397 359
398(defun auth-source-backend-parse (entry) 360(defun auth-source-backend-parse (entry)
399 "Creates an auth-source-backend from an ENTRY in `auth-sources'." 361 "Creates an auth-source-backend from an ENTRY in `auth-sources'."
400 (auth-source-backend-parse-parameters 362
401 entry 363 (let (backend)
402 (cond 364 (dolist (f auth-source-backend-parser-functions)
403 ;; take 'default and recurse to get it as a Secrets API default collection 365 (when (setq backend (funcall f entry))
404 ;; matching any user, host, and protocol 366 (return)))
405 ((eq entry 'default) 367
406 (auth-source-backend-parse '(:source (:secrets default)))) 368 (unless backend
407 ;; take secrets:XYZ and recurse to get it as Secrets API collection "XYZ" 369 ;; none of the parsers worked
408 ;; matching any user, host, and protocol 370 (auth-source-do-warn
409 ((and (stringp entry) (string-match "^secrets:\\(.+\\)" entry)) 371 "auth-source-backend-parse: invalid backend spec: %S" entry)
410 (auth-source-backend-parse `(:source (:secrets ,(match-string 1 entry))))) 372 (setq backend (make-instance 'auth-source-backend
411 373 :source ""
412 ;; take 'macos-keychain-internet and recurse to get it as a Mac OS 374 :type 'ignore)))
413 ;; Keychain collection matching any user, host, and protocol 375 (auth-source-backend-parse-parameters entry backend)))
414 ((eq entry 'macos-keychain-internet) 376
415 (auth-source-backend-parse '(:source (:macos-keychain-internet default)))) 377(defun auth-source-backends-parser-file (entry)
416 ;; take 'macos-keychain-generic and recurse to get it as a Mac OS 378 ;; take just a file name use it as a netrc/plist file
417 ;; Keychain collection matching any user, host, and protocol 379 ;; matching any user, host, and protocol
418 ((eq entry 'macos-keychain-generic) 380 (when (stringp entry)
419 (auth-source-backend-parse '(:source (:macos-keychain-generic default)))) 381 (setq entry `(:source ,entry)))
420 ;; take macos-keychain-internet:XYZ and recurse to get it as macOS 382 (cond
421 ;; Keychain "XYZ" matching any user, host, and protocol 383 ;; a file name with parameters
422 ((and (stringp entry) (string-match "^macos-keychain-internet:\\(.+\\)" 384 ((stringp (plist-get entry :source))
423 entry)) 385 (if (equal (file-name-extension (plist-get entry :source)) "plist")
424 (auth-source-backend-parse `(:source (:macos-keychain-internet 386 (auth-source-backend
425 ,(match-string 1 entry))))) 387 (plist-get entry :source)
426 ;; take macos-keychain-generic:XYZ and recurse to get it as macOS 388 :source (plist-get entry :source)
427 ;; Keychain "XYZ" matching any user, host, and protocol 389 :type 'plstore
428 ((and (stringp entry) (string-match "^macos-keychain-generic:\\(.+\\)" 390 :search-function #'auth-source-plstore-search
429 entry)) 391 :create-function #'auth-source-plstore-create
430 (auth-source-backend-parse `(:source (:macos-keychain-generic 392 :data (plstore-open (plist-get entry :source)))
431 ,(match-string 1 entry))))) 393 (auth-source-backend
432 394 (plist-get entry :source)
433 ;; take just a file name and recurse to get it as a netrc file 395 :source (plist-get entry :source)
434 ;; matching any user, host, and protocol 396 :type 'netrc
435 ((stringp entry) 397 :search-function #'auth-source-netrc-search
436 (auth-source-backend-parse `(:source ,entry))) 398 :create-function #'auth-source-netrc-create)))))
437 399
438 ;; a file name with parameters 400;; Note this function should be last in the parser functions, so we add it first
439 ((stringp (plist-get entry :source)) 401(add-hook 'auth-source-backend-parser-functions 'auth-source-backends-parser-file)
440 (if (equal (file-name-extension (plist-get entry :source)) "plist") 402
441 (auth-source-backend 403(defun auth-source-backends-parser-macos-keychain (entry)
442 (plist-get entry :source) 404 ;; take macos-keychain-{internet,generic}:XYZ and use it as macOS
443 :source (plist-get entry :source) 405 ;; Keychain "XYZ" matching any user, host, and protocol
444 :type 'plstore 406 (when (and (stringp entry) (string-match "^macos-keychain-internet:\\(.+\\)"
445 :search-function #'auth-source-plstore-search 407 entry))
446 :create-function #'auth-source-plstore-create 408 (setq entry `(:source (:macos-keychain-internet
447 :data (plstore-open (plist-get entry :source))) 409 ,(match-string 1 entry)))))
448 (auth-source-backend 410 (when (and (stringp entry) (string-match "^macos-keychain-generic:\\(.+\\)"
449 (plist-get entry :source) 411 entry))
450 :source (plist-get entry :source) 412 (setq entry `(:source (:macos-keychain-generic
451 :type 'netrc 413 ,(match-string 1 entry)))))
452 :search-function #'auth-source-netrc-search 414 ;; take 'macos-keychain-internet or generic and use it as a Mac OS
453 :create-function #'auth-source-netrc-create))) 415 ;; Keychain collection matching any user, host, and protocol
454 416 (when (eq entry 'macos-keychain-internet)
455 ;; the macOS Keychain 417 (setq entry '(:source (:macos-keychain-internet default))))
456 ((and 418 (when (eq entry 'macos-keychain-generic)
457 (not (null (plist-get entry :source))) ; the source must not be nil 419 (setq entry '(:source (:macos-keychain-generic default))))
458 (listp (plist-get entry :source)) ; and it must be a list 420 (cond
459 (or 421 ;; the macOS Keychain
460 (plist-get (plist-get entry :source) :macos-keychain-generic) 422 ((and
461 (plist-get (plist-get entry :source) :macos-keychain-internet))) 423 (not (null (plist-get entry :source))) ; the source must not be nil
462 424 (listp (plist-get entry :source)) ; and it must be a list
463 (let* ((source-spec (plist-get entry :source)) 425 (or
464 (keychain-generic (plist-get source-spec :macos-keychain-generic)) 426 (plist-get (plist-get entry :source) :macos-keychain-generic)
465 (keychain-type (if keychain-generic 427 (plist-get (plist-get entry :source) :macos-keychain-internet)))
466 'macos-keychain-generic 428
467 'macos-keychain-internet)) 429 (let* ((source-spec (plist-get entry :source))
468 (source (plist-get source-spec (if keychain-generic 430 (keychain-generic (plist-get source-spec :macos-keychain-generic))
469 :macos-keychain-generic 431 (keychain-type (if keychain-generic
470 :macos-keychain-internet)))) 432 'macos-keychain-generic
471 433 'macos-keychain-internet))
472 (when (symbolp source) 434 (source (plist-get source-spec (if keychain-generic
473 (setq source (symbol-name source))) 435 :macos-keychain-generic
474 436 :macos-keychain-internet))))
475 (auth-source-backend 437
476 (format "Mac OS Keychain (%s)" source) 438 (when (symbolp source)
477 :source source 439 (setq source (symbol-name source)))
478 :type keychain-type 440
479 :search-function #'auth-source-macos-keychain-search 441 (auth-source-backend
480 :create-function #'auth-source-macos-keychain-create))) 442 (format "Mac OS Keychain (%s)" source)
481 443 :source source
482 ;; the Secrets API. We require the package, in order to have a 444 :type keychain-type
483 ;; defined value for `secrets-enabled'. 445 :search-function #'auth-source-macos-keychain-search
484 ((and 446 :create-function #'auth-source-macos-keychain-create)))))
485 (not (null (plist-get entry :source))) ; the source must not be nil 447
486 (listp (plist-get entry :source)) ; and it must be a list 448(add-hook 'auth-source-backend-parser-functions 'auth-source-backends-parser-macos-keychain)
487 (require 'secrets nil t) ; and we must load the Secrets API 449
488 secrets-enabled) ; and that API must be enabled 450(defun auth-source-backends-parser-secrets (entry)
489 451 ;; take secrets:XYZ and use it as Secrets API collection "XYZ"
490 ;; the source is either the :secrets key in ENTRY or 452 ;; matching any user, host, and protocol
491 ;; if that's missing or nil, it's "session" 453 (when (and (stringp entry) (string-match "^secrets:\\(.+\\)" entry))
492 (let ((source (or (plist-get (plist-get entry :source) :secrets) 454 (setq entry `(:source (:secrets ,(match-string 1 entry)))))
493 "session"))) 455 ;; take 'default and use it as a Secrets API default collection
494 456 ;; matching any user, host, and protocol
495 ;; if the source is a symbol, we look for the alias named so, 457 (when (eq entry 'default)
496 ;; and if that alias is missing, we use "Login" 458 (setq entry '(:source (:secrets default))))
497 (when (symbolp source) 459 (cond
498 (setq source (or (secrets-get-alias (symbol-name source)) 460 ;; the Secrets API. We require the package, in order to have a
499 "Login"))) 461 ;; defined value for `secrets-enabled'.
500 462 ((and
501 (if (featurep 'secrets) 463 (not (null (plist-get entry :source))) ; the source must not be nil
502 (auth-source-backend 464 (listp (plist-get entry :source)) ; and it must be a list
503 (format "Secrets API (%s)" source) 465 (not (null (plist-get
504 :source source 466 (plist-get entry :source)
505 :type 'secrets 467 :secrets))) ; the source must have :secrets
506 :search-function #'auth-source-secrets-search 468 (require 'secrets nil t) ; and we must load the Secrets API
507 :create-function #'auth-source-secrets-create) 469 secrets-enabled) ; and that API must be enabled
508 (auth-source-do-warn 470
509 "auth-source-backend-parse: no Secrets API, ignoring spec: %S" entry) 471 ;; the source is either the :secrets key in ENTRY or
510 (auth-source-backend 472 ;; if that's missing or nil, it's "session"
511 (format "Ignored Secrets API (%s)" source) 473 (let ((source (plist-get (plist-get entry :source) :secrets)))
512 :source "" 474
513 :type 'ignore)))) 475 ;; if the source is a symbol, we look for the alias named so,
514 476 ;; and if that alias is missing, we use "Login"
515 ;; none of them 477 (when (symbolp source)
516 (t 478 (setq source (or (secrets-get-alias (symbol-name source))
517 (auth-source-do-warn 479 "Login")))
518 "auth-source-backend-parse: invalid backend spec: %S" entry) 480
519 (make-instance 'auth-source-backend 481 (if (featurep 'secrets)
520 :source "" 482 (auth-source-backend
521 :type 'ignore))))) 483 (format "Secrets API (%s)" source)
484 :source source
485 :type 'secrets
486 :search-function #'auth-source-secrets-search
487 :create-function #'auth-source-secrets-create)
488 (auth-source-do-warn
489 "auth-source-backend-parse: no Secrets API, ignoring spec: %S" entry)
490 (auth-source-backend
491 (format "Ignored Secrets API (%s)" source)
492 :source ""
493 :type 'ignore))))))
494
495(add-hook 'auth-source-backend-parser-functions 'auth-source-backends-parser-secrets)
522 496
523(defun auth-source-backend-parse-parameters (entry backend) 497(defun auth-source-backend-parse-parameters (entry backend)
524 "Fills in the extra auth-source-backend parameters of ENTRY. 498 "Fills in the extra auth-source-backend parameters of ENTRY.
@@ -781,12 +755,6 @@ must call it to obtain the actual value."
781 (setq matches (append matches bmatches)))))) 755 (setq matches (append matches bmatches))))))
782 matches)) 756 matches))
783 757
784;; (auth-source-search :max 0)
785;; (auth-source-search :max 1)
786;; (funcall (plist-get (nth 0 (auth-source-search :max 1)) :secret))
787;; (auth-source-search :host "nonesuch" :type 'netrc :K 1)
788;; (auth-source-search :host "nonesuch" :type 'secrets)
789
790(defun auth-source-delete (&rest spec) 758(defun auth-source-delete (&rest spec)
791 "Delete entries from the authentication backends according to SPEC. 759 "Delete entries from the authentication backends according to SPEC.
792Calls `auth-source-search' with the :delete property in SPEC set to t. 760Calls `auth-source-search' with the :delete property in SPEC set to t.
@@ -844,17 +812,6 @@ This is the same SPEC you passed to `auth-source-search'.
844Returns t or nil for forgotten or not found." 812Returns t or nil for forgotten or not found."
845 (password-cache-remove (auth-source-format-cache-entry spec))) 813 (password-cache-remove (auth-source-format-cache-entry spec)))
846 814
847;; (loop for sym being the symbols of password-data when (string-match (concat "^" auth-source-magic) (symbol-name sym)) collect (symbol-name sym))
848
849;; (auth-source-remember '(:host "wedd") '(4 5 6))
850;; (auth-source-remembered-p '(:host "wedd"))
851;; (auth-source-remember '(:host "xedd") '(1 2 3))
852;; (auth-source-remembered-p '(:host "xedd"))
853;; (auth-source-remembered-p '(:host "zedd"))
854;; (auth-source-recall '(:host "xedd"))
855;; (auth-source-recall '(:host t))
856;; (auth-source-forget+ :host t)
857
858(defun auth-source-forget+ (&rest spec) 815(defun auth-source-forget+ (&rest spec)
859 "Forget any cached data matching SPEC. Returns forgotten count. 816 "Forget any cached data matching SPEC. Returns forgotten count.
860 817
@@ -886,8 +843,6 @@ while \(:host t) would find all host entries."
886 (cl-return 'no))) 843 (cl-return 'no)))
887 'no)))) 844 'no))))
888 845
889;; (auth-source-pick-first-password :host "z.lifelogs.com")
890;; (auth-source-pick-first-password :port "imap")
891(defun auth-source-pick-first-password (&rest spec) 846(defun auth-source-pick-first-password (&rest spec)
892 "Pick the first secret found from applying SPEC to `auth-source-search'." 847 "Pick the first secret found from applying SPEC to `auth-source-search'."
893 (let* ((result (nth 0 (apply #'auth-source-search (plist-put spec :max 1)))) 848 (let* ((result (nth 0 (apply #'auth-source-search (plist-put spec :max 1))))
@@ -897,7 +852,6 @@ while \(:host t) would find all host entries."
897 (funcall secret) 852 (funcall secret)
898 secret))) 853 secret)))
899 854
900;; (auth-source-format-prompt "test %u %h %p" '((?u "user") (?h "host")))
901(defun auth-source-format-prompt (prompt alist) 855(defun auth-source-format-prompt (prompt alist)
902 "Format PROMPT using %x (for any character x) specifiers in ALIST." 856 "Format PROMPT using %x (for any character x) specifiers in ALIST."
903 (dolist (cell alist) 857 (dolist (cell alist)
@@ -1119,7 +1073,6 @@ Note that the MAX parameter is used so we can exit the parse early."
1119 (lambda () p))) 1073 (lambda () p)))
1120 passphrase)))) 1074 passphrase))))
1121 1075
1122;; (auth-source-epa-extract-gpg-token "gpg:LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tClZlcnNpb246IEdudVBHIHYxLjQuMTEgKEdOVS9MaW51eCkKCmpBMEVBd01DT25qMjB1ak9rZnRneVI3K21iNm9aZWhuLzRad3cySkdlbnVaKzRpeEswWDY5di9icDI1U1dsQT0KPS9yc2wKLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQo=" "~/.netrc")
1123(defun auth-source-epa-extract-gpg-token (secret file) 1076(defun auth-source-epa-extract-gpg-token (secret file)
1124 "Pass either the decoded SECRET or the gpg:BASE64DATA version. 1077 "Pass either the decoded SECRET or the gpg:BASE64DATA version.
1125FILE is the file from which we obtained this token." 1078FILE is the file from which we obtained this token."
@@ -1134,7 +1087,6 @@ FILE is the file from which we obtained this token."
1134 1087
1135(defvar pp-escape-newlines) 1088(defvar pp-escape-newlines)
1136 1089
1137;; (insert (auth-source-epa-make-gpg-token "mysecret" "~/.netrc"))
1138(defun auth-source-epa-make-gpg-token (secret file) 1090(defun auth-source-epa-make-gpg-token (secret file)
1139 (let ((context (epg-make-context 'OpenPGP)) 1091 (let ((context (epg-make-context 'OpenPGP))
1140 (pp-escape-newlines nil) 1092 (pp-escape-newlines nil)
@@ -1193,9 +1145,6 @@ FILE is the file from which we obtained this token."
1193 ret)) 1145 ret))
1194 alist)) 1146 alist))
1195 1147
1196;; (setq secret (plist-get (nth 0 (auth-source-search :host t :type 'netrc :K 1 :max 1)) :secret))
1197;; (funcall secret)
1198
1199(cl-defun auth-source-netrc-search (&rest spec 1148(cl-defun auth-source-netrc-search (&rest spec
1200 &key backend require create 1149 &key backend require create
1201 type max host user port 1150 type max host user port
@@ -1415,7 +1364,6 @@ See `auth-source-search' for details on SPEC."
1415 1364
1416 (list artificial))) 1365 (list artificial)))
1417 1366
1418;;(funcall (plist-get (nth 0 (auth-source-search :host '("nonesuch2") :user "tzz" :port "imap" :create t :max 1)) :save-function))
1419(defun auth-source-netrc-saver (file add) 1367(defun auth-source-netrc-saver (file add)
1420 "Save a line ADD in FILE, prompting along the way. 1368 "Save a line ADD in FILE, prompting along the way.
1421Respects `auth-source-save-behavior'. Uses 1369Respects `auth-source-save-behavior'. Uses
@@ -1496,13 +1444,6 @@ Respects `auth-source-save-behavior'. Uses
1496 1444
1497;;; Backend specific parsing: Secrets API backend 1445;;; Backend specific parsing: Secrets API backend
1498 1446
1499;; (let ((auth-sources '(default))) (auth-source-search :max 1 :create t))
1500;; (let ((auth-sources '(default))) (auth-source-search :max 1 :delete t))
1501;; (let ((auth-sources '(default))) (auth-source-search :max 1))
1502;; (let ((auth-sources '(default))) (auth-source-search))
1503;; (let ((auth-sources '("secrets:Login"))) (auth-source-search :max 1))
1504;; (let ((auth-sources '("secrets:Login"))) (auth-source-search :max 1 :signon_realm "https://git.gnus.org/Git"))
1505
1506(defun auth-source-secrets-listify-pattern (pattern) 1447(defun auth-source-secrets-listify-pattern (pattern)
1507 "Convert a pattern with lists to a list of string patterns. 1448 "Convert a pattern with lists to a list of string patterns.
1508 1449
@@ -1630,20 +1571,6 @@ authentication tokens:
1630 1571
1631;;; Backend specific parsing: Mac OS Keychain (using /usr/bin/security) backend 1572;;; Backend specific parsing: Mac OS Keychain (using /usr/bin/security) backend
1632 1573
1633;; (let ((auth-sources '(macos-keychain-internet))) (auth-source-search :max 1 :create t))
1634;; (let ((auth-sources '(macos-keychain-internet))) (auth-source-search :max 1 :delete t))
1635;; (let ((auth-sources '(macos-keychain-internet))) (auth-source-search :max 1))
1636;; (let ((auth-sources '(macos-keychain-internet))) (auth-source-search))
1637
1638;; (let ((auth-sources '(macos-keychain-generic))) (auth-source-search :max 1 :create t))
1639;; (let ((auth-sources '(macos-keychain-generic))) (auth-source-search :max 1 :delete t))
1640;; (let ((auth-sources '(macos-keychain-generic))) (auth-source-search :max 1))
1641;; (let ((auth-sources '(macos-keychain-generic))) (auth-source-search))
1642
1643;; (let ((auth-sources '("macos-keychain-internet:/Users/tzz/Library/Keychains/login.keychain"))) (auth-source-search :max 1))
1644;; (let ((auth-sources '("macos-keychain-generic:Login"))) (auth-source-search :max 1 :host "git.gnus.org"))
1645;; (let ((auth-sources '("macos-keychain-generic:Login"))) (auth-source-search :max 1))
1646
1647(cl-defun auth-source-macos-keychain-search (&rest spec 1574(cl-defun auth-source-macos-keychain-search (&rest spec
1648 &key backend create delete type max 1575 &key backend create delete type max
1649 &allow-other-keys) 1576 &allow-other-keys)
diff --git a/test/lisp/auth-source-tests.el b/test/lisp/auth-source-tests.el
index e73f55e2bfa..2634777c7db 100644
--- a/test/lisp/auth-source-tests.el
+++ b/test/lisp/auth-source-tests.el
@@ -32,6 +32,10 @@
32(defvar secrets-enabled t 32(defvar secrets-enabled t
33 "Enable the secrets backend to test its features.") 33 "Enable the secrets backend to test its features.")
34 34
35(defun auth-source-ensure-ignored-backend (source)
36 (auth-source-validate-backend source '((:source . "")
37 (:type . ignore))))
38
35(defun auth-source-validate-backend (source validation-alist) 39(defun auth-source-validate-backend (source validation-alist)
36 (let ((backend (auth-source-backend-parse source))) 40 (let ((backend (auth-source-backend-parse source)))
37 (should (auth-source-backend-p backend)) 41 (should (auth-source-backend-p backend))
@@ -119,15 +123,6 @@
119 (:search-function . auth-source-secrets-search) 123 (:search-function . auth-source-secrets-search)
120 (:create-function . auth-source-secrets-create))))) 124 (:create-function . auth-source-secrets-create)))))
121 125
122(ert-deftest auth-source-backend-parse-secrets-nil-source ()
123 (provide 'secrets) ; simulates the presence of the `secrets' package
124 (let ((secrets-enabled t))
125 (auth-source-validate-backend '(:source (:secrets nil))
126 '((:source . "session")
127 (:type . secrets)
128 (:search-function . auth-source-secrets-search)
129 (:create-function . auth-source-secrets-create)))))
130
131(ert-deftest auth-source-backend-parse-secrets-alias () 126(ert-deftest auth-source-backend-parse-secrets-alias ()
132 (provide 'secrets) ; simulates the presence of the `secrets' package 127 (provide 'secrets) ; simulates the presence of the `secrets' package
133 (let ((secrets-enabled t)) 128 (let ((secrets-enabled t))
@@ -162,17 +157,12 @@
162 (:search-function . auth-source-secrets-search) 157 (:search-function . auth-source-secrets-search)
163 (:create-function . auth-source-secrets-create)))))) 158 (:create-function . auth-source-secrets-create))))))
164 159
165;; TODO This test shows suspicious behavior of auth-source: the 160(ert-deftest auth-source-backend-parse-invalid-or-nil-source ()
166;; "secrets" source is used even though nothing in the input indicates
167;; that is what we want
168(ert-deftest auth-source-backend-parse-secrets-no-source ()
169 (provide 'secrets) ; simulates the presence of the `secrets' package 161 (provide 'secrets) ; simulates the presence of the `secrets' package
170 (let ((secrets-enabled t)) 162 (let ((secrets-enabled t))
171 (auth-source-validate-backend '(:source '(foo)) 163 (auth-source-ensure-ignored-backend nil)
172 '((:source . "session") 164 (auth-source-ensure-ignored-backend '(:source '(foo)))
173 (:type . secrets) 165 (auth-source-ensure-ignored-backend '(:source nil))))
174 (:search-function . auth-source-secrets-search)
175 (:create-function . auth-source-secrets-create)))))
176 166
177(defun auth-source--test-netrc-parse-entry (entry host user port) 167(defun auth-source--test-netrc-parse-entry (entry host user port)
178 "Parse a netrc entry from buffer." 168 "Parse a netrc entry from buffer."
@@ -219,5 +209,24 @@
219 ("login" . "user1") 209 ("login" . "user1")
220 ("machine" . "mymachine1")))))) 210 ("machine" . "mymachine1"))))))
221 211
212(ert-deftest auth-source-test-format-prompt ()
213 (should (equal (auth-source-format-prompt "test %u %h %p" '((?u "user") (?h "host")))
214 "test user host %p")))
215
216(ert-deftest auth-source-test-remembrances-of-things-past ()
217 (let ((password-cache t)
218 (password-data (make-vector 7 0)))
219 (auth-source-remember '(:host "wedd") '(4 5 6))
220 (should (auth-source-remembered-p '(:host "wedd")))
221 (should-not (auth-source-remembered-p '(:host "xedd")))
222 (auth-source-remember '(:host "xedd") '(1 2 3))
223 (should (auth-source-remembered-p '(:host "xedd")))
224 (should-not (auth-source-remembered-p '(:host "zedd")))
225 (should (auth-source-recall '(:host "xedd")))
226 (should-not (auth-source-recall nil))
227 (auth-source-forget+ :host t)
228 (should-not (auth-source-remembered-p '(:host "xedd")))
229 (should-not (auth-source-remembered-p '(:host t)))))
230
222(provide 'auth-source-tests) 231(provide 'auth-source-tests)
223;;; auth-source-tests.el ends here 232;;; auth-source-tests.el ends here