changeset 15025:0593e8f81c71 stable

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.
author Patrick Mezard <pmezard@gmail.com>
date Fri, 05 Aug 2011 21:05:41 +0200
parents 0f1311e829c9
children f32a2989ff58
files mercurial/httpconnection.py mercurial/url.py tests/test-hgweb-auth.py
diffstat 3 files changed, 18 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/httpconnection.py	Fri Aug 05 21:05:40 2011 +0200
+++ b/mercurial/httpconnection.py	Fri Aug 05 21:05:41 2011 +0200
@@ -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
--- a/mercurial/url.py	Fri Aug 05 21:05:40 2011 +0200
+++ b/mercurial/url.py	Fri Aug 05 21:05:41 2011 +0200
@@ -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
--- a/tests/test-hgweb-auth.py	Fri Aug 05 21:05:40 2011 +0200
+++ b/tests/test-hgweb-auth.py	Fri Aug 05 21:05:41 2011 +0200
@@ -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'