Mercurial > hg
changeset 15027:1e45b92f4fb2
merge with stable
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Fri, 05 Aug 2011 16:07:51 -0500 |
parents | 157a294444b2 (current diff) f32a2989ff58 (diff) |
children | eb97a3e38656 |
files | mercurial/dispatch.py mercurial/url.py mercurial/util.py |
diffstat | 8 files changed, 110 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/dispatch.py Thu Aug 04 16:12:58 2011 -0500 +++ b/mercurial/dispatch.py Fri Aug 05 16:07:51 2011 -0500 @@ -357,6 +357,15 @@ # but only if they have been defined prior to the current definition. for alias, definition in ui.configitems('alias'): aliasdef = cmdalias(alias, definition, cmdtable) + + try: + olddef = cmdtable[aliasdef.cmd][0] + if olddef.definition == aliasdef.definition: + continue + except (KeyError, AttributeError): + # definition might not exist or it might not be a cmdalias + pass + cmdtable[aliasdef.cmd] = (aliasdef, aliasdef.opts, aliasdef.help) if aliasdef.norepo: commands.norepo += ' %s' % alias
--- a/mercurial/httpconnection.py Thu Aug 04 16:12:58 2011 -0500 +++ b/mercurial/httpconnection.py Fri Aug 05 16:07:51 2011 -0500 @@ -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 Thu Aug 04 16:12:58 2011 -0500 +++ b/mercurial/url.py Fri Aug 05 16:07:51 2011 -0500 @@ -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/mercurial/util.py Thu Aug 04 16:12:58 2011 -0500 +++ b/mercurial/util.py Fri Aug 05 16:07:51 2011 -0500 @@ -1468,6 +1468,8 @@ path = None if not self.host: self.host = None + # path of file:///d is /d + # path of file:///d:/ is d:/, not /d:/ if path and not hasdriveletter(path): path = '/' + path @@ -1587,7 +1589,9 @@ self.user, self.passwd = user, passwd if not self.user: return (s, None) - return (s, (None, (str(self), self.host), + # authinfo[1] is passed to urllib2 password manager, and its URIs + # must not contain credentials. + return (s, (None, (s, self.host), self.user, self.passwd or '')) def isabs(self): @@ -1610,11 +1614,6 @@ path = self._hostport + '/' + self.path elif self.host is not None and self.path: path = '/' + path - # We also need to handle the case of file:///C:/, which - # should return C:/, not /C:/. - elif hasdriveletter(path): - # Strip leading slash from paths with drive names - return path[1:] return path return self._origpath
--- a/tests/test-hgweb-auth.py Thu Aug 04 16:12:58 2011 -0500 +++ b/tests/test-hgweb-auth.py Fri Aug 05 16:07:51 2011 -0500 @@ -1,4 +1,5 @@ from mercurial import demandimport; demandimport.enable() +import urllib2 from mercurial import ui, util from mercurial import url from mercurial.error import Abort @@ -36,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' @@ -95,3 +96,12 @@ 'y.username': 'y', 'y.password': 'ypassword'}, urls=['http://y@example.org/foo/bar']) + +def testauthinfo(fullurl, authurl): + print 'URIs:', fullurl, authurl + pm = urllib2.HTTPPasswordMgrWithDefaultRealm() + pm.add_password(*util.url(fullurl).authinfo()[1]) + print pm.find_user_password('test', authurl) + +print '\n*** Test urllib2 and util.url\n' +testauthinfo('http://user@example.com:8080/foo', 'http://example.com:8080/foo')
--- a/tests/test-hgweb-auth.py.out Thu Aug 04 16:12:58 2011 -0500 +++ b/tests/test-hgweb-auth.py.out Fri Aug 05 16:07:51 2011 -0500 @@ -189,3 +189,8 @@ CFG: {x.password: xpassword, x.prefix: http://example.org/foo/bar, x.username: None, y.password: ypassword, y.prefix: http://example.org/foo, y.username: y} URI: http://y@example.org/foo/bar ('y', 'xpassword') + +*** Test urllib2 and util.url + +URIs: http://user@example.com:8080/foo http://example.com:8080/foo +('user', '')
--- a/tests/test-http.t Thu Aug 04 16:12:58 2011 -0500 +++ b/tests/test-http.t Fri Aug 05 16:07:51 2011 -0500 @@ -110,6 +110,55 @@ abort: HTTP Error 404: Not Found [255] +test http authentication + + $ cd test + $ cat << EOT > userpass.py + > import base64 + > from mercurial.hgweb import common + > def perform_authentication(hgweb, req, op): + > auth = req.env.get('HTTP_AUTHORIZATION') + > if not auth: + > raise common.ErrorResponse(common.HTTP_UNAUTHORIZED, 'who', + > [('WWW-Authenticate', 'Basic Realm="mercurial"')]) + > if base64.b64decode(auth.split()[1]).split(':', 1) != ['user', 'pass']: + > raise common.ErrorResponse(common.HTTP_FORBIDDEN, 'no') + > def extsetup(): + > common.permhooks.insert(0, perform_authentication) + > EOT + $ hg --config extensions.x=userpass.py serve -p $HGPORT2 -d --pid-file=pid + $ cat pid >> $DAEMON_PIDS + + $ hg id http://localhost:$HGPORT2/ + abort: http authorization required + [255] + $ hg id http://user@localhost:$HGPORT2/ + abort: http authorization required + [255] + $ hg id http://user:pass@localhost:$HGPORT2/ + 5fed3813f7f5 + $ echo '[auth]' >> .hg/hgrc + $ echo 'l.schemes=http' >> .hg/hgrc + $ echo 'l.prefix=lo' >> .hg/hgrc + $ echo 'l.username=user' >> .hg/hgrc + $ echo 'l.password=pass' >> .hg/hgrc + $ hg id http://localhost:$HGPORT2/ + 5fed3813f7f5 + $ hg id http://localhost:$HGPORT2/ + 5fed3813f7f5 + $ hg id http://user@localhost:$HGPORT2/ + 5fed3813f7f5 + $ hg id http://user:pass@localhost:$HGPORT2/ + 5fed3813f7f5 + $ hg id http://user2@localhost:$HGPORT2/ + abort: http authorization required + [255] + $ hg id http://user:pass2@localhost:$HGPORT2/ + abort: HTTP Error 403: no + [255] + + $ cd .. + check error log $ cat error.log
--- a/tests/test-url.py Thu Aug 04 16:12:58 2011 -0500 +++ b/tests/test-url.py Fri Aug 05 16:07:51 2011 -0500 @@ -204,18 +204,32 @@ <url scheme: 'file', path: '/foo/bar/baz'> >>> str(u) 'file:///foo/bar/baz' + >>> u.localpath() + '/foo/bar/baz' >>> u = url('file:///foo/bar/baz') >>> u <url scheme: 'file', path: '/foo/bar/baz'> >>> str(u) 'file:///foo/bar/baz' + >>> u.localpath() + '/foo/bar/baz' + + >>> u = url('file:///f:oo/bar/baz') + >>> u + <url scheme: 'file', path: 'f:oo/bar/baz'> + >>> str(u) + 'file:f%3Aoo/bar/baz' + >>> u.localpath() + 'f:oo/bar/baz' >>> u = url('file:foo/bar/baz') >>> u <url scheme: 'file', path: 'foo/bar/baz'> >>> str(u) 'file:foo/bar/baz' + >>> u.localpath() + 'foo/bar/baz' """ doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE)