On Fri, 27 May 2011 20:39:28 +0200 Rémi Vanicat <[email protected]> wrote: 

RV> I've recently pushed to master a modification to this part of the
RV> code. Could you integrate with it?

Attached.

RV> Note also that when one is reading "foo's password:" it is actually ssh
RV> asking for a password when there is no ssh-key. When it's git that do the 
asking, it
RV> just ask for "Password:" (hence the bug for the original poster of this
RV> thread).

OK, I didn't get that.  See my TODO comments regarding more things we
can do there, especially the origin.url if we can get it.

I changed things a bit so please let me know if any of the code is wrong
or broken.  When this iteration is acceptable I'll add the backwards
compatibility calls to `auth-source-user-or-password' as well.

Also my original message asked about askpass; that's much more reliable
than parsing CLI output and works in Unix and Windows (with msysgit at
least).  Could Magit support that?

It may be productive to give me commit access to the Github repo as I
have some other Magit things in my queue.  It's not a big deal, just
don't make me do the Github-specific fork+pull request procedure :)

Ted

diff --git a/magit.el b/magit.el
index 5b25259..86cb202 100644
--- a/magit.el
+++ b/magit.el
@@ -83,6 +83,8 @@
 (require 'easymenu)
 (require 'diff-mode)
 
+(require 'auth-source nil t)
+
 ;; Silences byte-compiler warnings
 (eval-when-compile  (require 'view))
 (declare-function view-mode 'view)
@@ -1968,14 +1970,44 @@ function can be enriched by magit extension like magit-topgit and magit-svn"
 
 (defun magit-password (proc string)
   "Checks if git/ssh asks for a password and ask the user for it."
-  (let (ask)
+  (let ((origin-url-host "unknown") ; this should come from origin.url
+        mode host prompt found)
     (cond ((or (string-match "^Enter passphrase for key '\\\(.*\\\)': $" string)
                (string-match "^\\\(.*\\\)'s password:" string))
-           (setq ask (format "Password for '%s': " (match-string 1 string))))
+           (setq mode 'ssh-key
+                 ;; this can be a key or user@host; TODO: parse host+user out
+                 host (match-string 1 string)
+                 prompt (format "SSH password for '%s': " host)))
           ((string-match "^[pP]assword:" string)
-           (setq ask "Password:")))
-    (when ask
-     (process-send-string proc (concat (read-passwd ask nil) "\n")))))
+           (setq mode 'password
+                 host origin-url-host
+                 prompt (format "Password for %s:" host)))
+          ((string-match "^[Uu]sername:" string)
+           (setq mode 'username
+                 host origin-url-host
+                 prompt (format "Username for %s:" host))))
+
+    (setq found (and host
+                     mode
+                     (fboundp 'auth-source-search)
+                     ;; TODO: use `auth-source-user-or-password'
+                     ;; if `auth-source-search' is missing
+                     (nth 0 (auth-source-search :max 1
+                                                :host host
+                                                :port (symbol-name mode)
+                                                ; :user user ; TODO, see above
+                                                :require '(:user :secret)
+                                                :create nil))))
+    (when prompt
+     (process-send-string
+      proc
+      (concat (or
+               (and found (let ((secret (plist-get found :secret)))
+                            (if (functionp secret)
+                                (funcall secret)
+                              secret)))
+               (read-passwd prompt nil)
+              "\n"))))))
 
 (defun magit-process-filter (proc string)
   (save-current-buffer

Reply via email to