[PATCH] Prompt user for HTTP authentication info

Eric Jaffe jaffe.eric at gmail.com
Sun May 14 16:26:13 CDT 2006


I was testing this out on my own server and I noticed that mercurial
did not ask me for a password when the server required authentication.
This is my first stab at a patch here, so obviously I can fix and
resend if I did anything wrong.

    Eric

--
# HG changeset patch
# User Eric Jaffe <jaffe.eric at gmail.com>
# Node ID 4837e0833b684ef5ddd611fb174fd982abd5a44d
# Parent  ba7afc7dd9013e2805098d19a6371f12d916fe25
Prompt user for HTTP authentication info

In interactive mode, mercurial now asks the user for the username and
password when the server requires it. The previous behavior was to fail
with an HTTP 401.

diff -r ba7afc7dd901 -r 4837e0833b68 mercurial/httprepo.py
--- a/mercurial/httprepo.py	Wed May 10 16:55:55 2006 -0500
+++ b/mercurial/httprepo.py	Sun May 14 17:16:27 2006 -0400
@@ -10,6 +10,29 @@ from i18n import gettext as _
 from i18n import gettext as _
 from demandload import *
 demandload(globals(), "hg os urllib urllib2 urlparse zlib util httplib")
+
+class UiPasswordMgr(urllib2.HTTPPasswordMgr):
+    def __init__(self, ui):
+        urllib2.HTTPPasswordMgr.__init__(self)
+        self.ui = ui
+
+    def find_user_password(self, realm, authuri):
+        def ui_prompt(msg):
+            self.ui.write(msg, ": ")
+            return self.ui.readline()
+
+        authinfo = urllib2.HTTPPasswordMgr.find_user_password(
+            self, realm, authuri)
+        if authinfo != (None, None):
+            return authinfo
+
+        self.ui.write(_("HTTP Authorization Required\n"))
+        self.ui.status("realm: %s\n" % realm)
+        user = ui_prompt("User")
+        passwd = ui_prompt("Password")
+
+        self.add_password(realm, authuri, user, passwd)
+        return (user, passwd)

 class httprepository(remoterepository):
     def __init__(self, ui, path):
@@ -53,13 +76,19 @@ class httprepository(remoterepository):
         if host and not no_proxy:
             proxy_handler = urllib2.ProxyHandler({"http" : "http://" + host})

-        authinfo = None
+        proxyauthinfo = None
         if user and passwd:
             passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
             passmgr.add_password(None, host, user, passwd)
-            authinfo = urllib2.ProxyBasicAuthHandler(passmgr)
+            proxyauthinfo = urllib2.ProxyBasicAuthHandler(passmgr)

-        opener = urllib2.build_opener(proxy_handler, authinfo)
+        httpauthinfo = ()
+        if ui.interactive:
+            passmgr = UiPasswordMgr(ui)
+            httpauthinfo = (urllib2.HTTPBasicAuthHandler(passmgr),
+                            urllib2.HTTPDigestAuthHandler(passmgr))
+
+        opener = urllib2.build_opener(proxy_handler, proxyauthinfo,
*httpauthinfo)
         # 1.0 here is the _protocol_ version
         opener.addheaders = [('User-agent', 'mercurial/proto-1.0')]
         urllib2.install_opener(opener)



More information about the Mercurial mailing list