[PATCH 2 of 3] http: pass user to readauthforuri() (fix 4a43e23b8c55)

Patrick Mezard pmezard at gmail.com
Fri Aug 5 14:24:58 CDT 2011


# HG changeset patch
# User Patrick Mezard <pmezard at gmail.com>
# Date 1312571141 -7200
# Branch stable
# Node ID 0a9f8def5e25da6450f9ab0554cfcc69d112d24a
# Parent  dc7963dc7bc2747aa063291004fdf9c3c86f3d9c
http: pass user to readauthforuri() (fix 4a43e23b8c55)

urllib2 never handles URIs with credentials, we have to extract them and store
them in the password manager before handing the stripped URI. Half of the
changes deducing the username from the URI in 4a43e23b8c55 were incorrect.
Instead, we retrieve the username from the password manager before passing to
readauthforuri().

test-hgweb-auth.py was passing because the test itself was flawed: it was
passing URIs with credentials to find_password(), which never happens.

diff --git a/mercurial/httpconnection.py b/mercurial/httpconnection.py
--- a/mercurial/httpconnection.py
+++ b/mercurial/httpconnection.py
@@ -58,7 +58,7 @@
         return self._len
 
 # moved here from url.py to avoid a cycle
-def readauthforuri(ui, uri):
+def readauthforuri(ui, uri, user):
     # Read configuration
     config = dict()
     for key, val in ui.configitems('auth'):
@@ -72,10 +72,6 @@
         gdict[setting] = val
 
     # Find the best match
-    uri = util.url(uri)
-    user = uri.user
-    uri.user = uri.password = None
-    uri = str(uri)
     scheme, hostpath = uri.split('://', 1)
     bestuser = None
     bestlen = 0
@@ -238,7 +234,11 @@
         return self.do_open(HTTPConnection, req, False)
 
     def https_open(self, req):
-        res = readauthforuri(self.ui, req.get_full_url())
+        # req.get_full_url() does not contain credentials and we may
+        # need them to match the certificates.
+        url = req.get_full_url()
+        user, password = self.pwmgr.find_stored_password(url)
+        res = readauthforuri(self.ui, url, user)
         if res:
             group, auth = res
             self.auth = auth
diff --git a/mercurial/url.py b/mercurial/url.py
--- a/mercurial/url.py
+++ b/mercurial/url.py
@@ -26,7 +26,7 @@
             return (user, passwd)
 
         if not user or not passwd:
-            res = httpconnectionmod.readauthforuri(self.ui, authuri)
+            res = httpconnectionmod.readauthforuri(self.ui, authuri, user)
             if res:
                 group, auth = res
                 user, passwd = auth.get('username'), auth.get('password')
@@ -53,6 +53,10 @@
         msg = _('http auth: user %s, password %s\n')
         self.ui.debug(msg % (user, passwd and '*' * len(passwd) or 'not set'))
 
+    def find_stored_password(self, authuri):
+        return urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password(
+            self, None, authuri)
+
 class proxyhandler(urllib2.ProxyHandler):
     def __init__(self, ui):
         proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy')
@@ -342,7 +346,11 @@
             return keepalive.KeepAliveHandler._start_transaction(self, h, req)
 
         def https_open(self, req):
-            res = httpconnectionmod.readauthforuri(self.ui, req.get_full_url())
+            # req.get_full_url() does not contain credentials and we may
+            # need them to match the certificates.
+            url = req.get_full_url()
+            user, password = self.pwmgr.find_stored_password(url)
+            res = httpconnectionmod.readauthforuri(self.ui, url, user)
             if res:
                 group, auth = res
                 self.auth = auth
diff --git a/tests/test-hgweb-auth.py b/tests/test-hgweb-auth.py
--- a/tests/test-hgweb-auth.py
+++ b/tests/test-hgweb-auth.py
@@ -37,10 +37,10 @@
         print 'URI:', uri
         try:
             pm = url.passwordmgr(ui)
-            authinfo = util.url(uri).authinfo()[1]
+            u, authinfo = util.url(uri).authinfo()
             if authinfo is not None:
                 pm.add_password(*authinfo)
-            print '    ', pm.find_user_password('test', uri)
+            print '    ', pm.find_user_password('test', u)
         except Abort, e:
             print 'abort'
 


More information about the Mercurial-devel mailing list