Complete among multiple auth-source-search choices when creating. Don't show the...
authorTed Zlatanov <tzz@lifelogs.com>
Thu, 17 Feb 2011 14:40:43 +0000 (08:40 -0600)
committerTed Zlatanov <tzz@lifelogs.com>
Thu, 17 Feb 2011 14:40:43 +0000 (08:40 -0600)
* auth-source.el (auth-source-search): Updated docs to talk about
multiple creation choices.
(auth-source-netrc-create): Accept a list as a value (from the search
parameters) and do completion on that list.  Keep a separate netrc line
with the password obscured for showing the user.

lisp/ChangeLog
lisp/auth-source.el
lisp/nnimap.el

index 9e05e74..16247e0 100644 (file)
@@ -1,5 +1,21 @@
 2011-02-17  Teodor Zlatanov  <tzz@lifelogs.com>
 
+       * nnimap.el (nnimap-credentials): Instead of picking the first port as
+       a creation default, pass the whole port list down.  It will be completed.
+
+       * auth-source.el (auth-source-search): Updated docs to talk about
+       multiple creation choices.
+       (auth-source-netrc-create): Accept a list as a value (from the search
+       parameters) and do completion on that list.  Keep a separate netrc line
+       with the password obscured for showing the user.
+
+       * nnimap.el (nnimap-open-connection-1): Make the `nnimap-address' the
+       first choice to `auth-source-search' so it will be used for entry
+       creation instead of the server's Gnus-specific name.
+       (nnimap-credentials): Rely on the auth-source library to select which
+       port is actually wanted in the new netrc entry, so don't override
+       `auth-source-creation-defaults'.
+
        * auth-source.el (auth-source-netrc-parse): Use :port instead of
        :protocol and accept a missing user, host, or port as a wildcard match.
        (auth-source-debug): Default to off.
index a5be129..8c34591 100644 (file)
@@ -463,8 +463,8 @@ which says:
  search to find only entries that have P set to 'pppp'.\"
 
 When multiple values are specified in the search parameter, the
-first one is used for creation.  So :host (X Y Z) would create a
-token for host X, for instance.
+user is prompted for which one.  So :host (X Y Z) would ask the
+user to choose between X, Y, and Z.
 
 This creation can fail if the search was not specific enough to
 create a new token (it's up to the backend to decide that).  You
@@ -861,6 +861,7 @@ See `auth-source-search' for details on SPEC."
          (required (append base-required create-extra))
          (file (oref backend source))
          (add "")
+         (show "")
          ;; `valist' is an alist
          valist
          ;; `artificial' will be returned if no creation is needed
@@ -868,12 +869,16 @@ See `auth-source-search' for details on SPEC."
 
     ;; only for base required elements (defined as function parameters):
     ;; fill in the valist with whatever data we may have from the search
-    ;; we take the first value if it's a list, the whole value otherwise
+    ;; we complete the first value if it's a list and use the value otherwise
     (dolist (br base-required)
       (when (symbol-value br)
-        (aput 'valist br (if (listp (symbol-value br))
-                             (nth 0 (symbol-value br))
-                           (symbol-value br)))))
+        (let ((br-choice (cond
+                          ;; all-accepting choice (predicate is t)
+                          ((eq t (symbol-value br)) nil)
+                          ;; just the value otherwise
+                          (t (symbol-value br)))))
+          (when br-choice
+            (aput 'valist br br-choice)))))
 
     ;; for extra required elements, see if the spec includes a value for them
     (dolist (er create-extra)
@@ -904,6 +909,8 @@ See `auth-source-search' for details on SPEC."
              (user-value (aget valist 'user))
              (host-value (aget valist 'host))
              (port-value (aget valist 'port))
+             ;; note this handles lists by just printing them
+             ;; later we allow the user to use completing-read to pick
              (info-so-far (concat (if user-value
                                       (format "%s@" user-value)
                                     "[USER?]")
@@ -931,6 +938,16 @@ See `auth-source-search' for details on SPEC."
                        (format "Enter %s for %s%s: "
                                r info-so-far default-string)
                        nil nil default))
+                     ((listp data)
+                      (completing-read
+                       (format "Enter %s for %s (TAB to see the choices): "
+                               r info-so-far)
+                       data
+                       nil              ; no predicate
+                       t                ; require a match
+                       ;; note the default is nil, but if the user
+                       ;; hits RET we'll get "", which is handled OK later
+                       nil))
                      (t data))))
 
         (when data
@@ -944,20 +961,25 @@ See `auth-source-search' for details on SPEC."
         ;; when r is not an empty string...
         (when (and (stringp data)
                    (< 0 (length data)))
-          ;; append the key (the symbol name of r) and the value in r
-          (setq add (concat add
-                            (format "%s%s %S"
-                                    ;; prepend a space
-                                    (if (zerop (length add)) "" " ")
-                                    ;; remap auth-source tokens to netrc
-                                    (case r
+          (let ((printer (lambda (hide)
+                           ;; append the key (the symbol name of r)
+                           ;; and the value in r
+                           (format "%s%s %S"
+                                   ;; prepend a space
+                                   (if (zerop (length add)) "" " ")
+                                   ;; remap auth-source tokens to netrc
+                                   (case r
                                      ('user "login")
                                      ('host "machine")
                                      ('secret "password")
                                      ('port "port") ; redundant but clearer
                                      (t (symbol-name r)))
-                                    ;; the value will be printed in %S format
-                                    data))))))
+                                   ;; the value will be printed in %S format
+                                   (if (and hide (eq r 'secret))
+                                       "HIDDEN_SECRET"
+                                     data)))))
+            (setq add (concat add (funcall printer nil)))
+            (setq show (concat show (funcall printer t)))))))
 
     (with-temp-buffer
       (when (file-exists-p file)
@@ -974,7 +996,7 @@ See `auth-source-search' for details on SPEC."
       (goto-char (point-max))
 
       ;; ask AFTER we've successfully opened the file
-      (if (y-or-n-p (format "Add to file %s: line [%s]" file add))
+      (if (y-or-n-p (format "Add to file %s: line [%s]" file show))
           (progn
             (unless (bolp)
               (insert "\n"))
index fc8873f..2412546 100644 (file)
@@ -277,8 +277,7 @@ textual parts.")
     (current-buffer)))
 
 (defun nnimap-credentials (address ports)
-  (let* ((auth-source-creation-defaults `((port . ,(nth 0 ports))))
-         (found (nth 0 (auth-source-search :max 1
+  (let* ((found (nth 0 (auth-source-search :max 1
                                            :host address
                                            :port ports
                                            :create t)))
@@ -386,8 +385,8 @@ textual parts.")
                                ;; the virtual server name and the address
                                (nnimap-credentials
                                 (list
-                                 (nnoo-current-server 'nnimap)
-                                 nnimap-address)
+                                 nnimap-address
+                                 (nnoo-current-server 'nnimap))
                                 ports))))
                  (setq nnimap-object nil)
                (let ((nnimap-inhibit-logging t))