# HG changeset patch # User Patrick Mezard # Date 1247967873 18000 # Node ID 3941d73c262ee115dd6b995c9a5fde10c1622b07 # Parent 9548b406a2d8165dc06a15b4c03798272c308761 svnwrappers: override svn+ssh credentials with supplied ones if any svn+ssh URLs are special because the authentication layer is not handled by svn, so they must contain the username to be resolved seamlessly. Until now, credentials supplied from the command line were ignored when rewriting those URLs. Fix that. diff --git a/hgsubversion/svnwrap/svn_swig_wrapper.py b/hgsubversion/svnwrap/svn_swig_wrapper.py --- a/hgsubversion/svnwrap/svn_swig_wrapper.py +++ b/hgsubversion/svnwrap/svn_swig_wrapper.py @@ -116,24 +116,22 @@ def _create_auth_baton(pool): return core.svn_auth_open(providers, pool) -def parse_url(url): +def parse_url(url, user=None, passwd=None): """Parse a URL and return a tuple (username, password, url) """ scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) - user, passwd = None, None if '@' in netloc: userpass, netloc = netloc.split('@') - if ':' in userpass: - user, passwd = userpass.split(':') - user, passwd = (urllib.unquote(user) or None, - urllib.unquote(passwd) or None, - ) - else: - user = urllib.unquote(userpass) or None - if user and scheme == 'svn+ssh': - netloc = '@'.join((user, netloc, )) + if not user and not passwd: + if ':' in userpass: + user, passwd = userpass.split(':') + else: + user, passwd = userpass, '' + user, passwd = urllib.unquote(user), urllib.unquote(passwd) + if user and scheme == 'svn+ssh': + netloc = '@'.join((user, netloc, )) url = urlparse.urlunparse((scheme, netloc, path, params, query, fragment)) - return (user, passwd, url) + return (user or None, passwd or None, url) class Revision(tuple): @@ -184,10 +182,10 @@ class SubversionRepo(object): It takes a required param, the URL. """ def __init__(self, url='', username='', password='', head=None): - parsed = parse_url(url) + parsed = parse_url(url, username, password) # --username and --password override URL credentials - self.username = username or parsed[0] - self.password = password or parsed[1] + self.username = parsed[0] + self.password = parsed[1] self.svn_url = parsed[2] self.auth_baton_pool = core.Pool() self.auth_baton = _create_auth_baton(self.auth_baton_pool) diff --git a/tests/test_urls.py b/tests/test_urls.py --- a/tests/test_urls.py +++ b/tests/test_urls.py @@ -8,24 +8,42 @@ class TestSubversionUrls(test_util.TestB parse_url('file:///var/svn/repo')) def test_user_url(self): - self.assertEqual(('joe', None, 'https://svn.testurl.com/repo'), - parse_url('https://joe@svn.testurl.com/repo')) + self.assertEqual( + ('joe', None, 'https://svn.testurl.com/repo'), + parse_url('https://joe@svn.testurl.com/repo')) + self.assertEqual( + ('bob', None, 'https://svn.testurl.com/repo'), + parse_url('https://joe@svn.testurl.com/repo', 'bob')) def test_password_url(self): - self.assertEqual((None, 't3stpw', 'svn+ssh://svn.testurl.com/repo'), - parse_url('svn+ssh://:t3stpw@svn.testurl.com/repo')) + self.assertEqual( + (None, 't3stpw', 'svn+ssh://svn.testurl.com/repo'), + parse_url('svn+ssh://:t3stpw@svn.testurl.com/repo')) + self.assertEqual( + (None, '123abc', 'svn+ssh://svn.testurl.com/repo'), + parse_url('svn+ssh://:t3stpw@svn.testurl.com/repo', None, '123abc')) def test_svnssh_preserve_user(self): self.assertEqual( ('user', 't3stpw', 'svn+ssh://user@svn.testurl.com/repo', ), parse_url('svn+ssh://user:t3stpw@svn.testurl.com/repo')) + self.assertEqual( + ('bob', '123abc', 'svn+ssh://bob@svn.testurl.com/repo', ), + parse_url('svn+ssh://user:t3stpw@svn.testurl.com/repo', 'bob', '123abc')) self.assertEqual( ('user2', None, 'svn+ssh://user2@svn.testurl.com/repo', ), parse_url('svn+ssh://user2@svn.testurl.com/repo')) + self.assertEqual( + ('bob', None, 'svn+ssh://bob@svn.testurl.com/repo', ), + parse_url('svn+ssh://user2@svn.testurl.com/repo', 'bob')) def test_user_password_url(self): - self.assertEqual(('joe', 't3stpw', 'https://svn.testurl.com/repo'), - parse_url('https://joe:t3stpw@svn.testurl.com/repo')) + self.assertEqual( + ('joe', 't3stpw', 'https://svn.testurl.com/repo'), + parse_url('https://joe:t3stpw@svn.testurl.com/repo')) + self.assertEqual( + ('bob', '123abc', 'https://svn.testurl.com/repo'), + parse_url('https://joe:t3stpw@svn.testurl.com/repo', 'bob', '123abc')) def suite():