changeset 467:3941d73c262e

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.
author Patrick Mezard <pmezard@gmail.com>
date Sat, 18 Jul 2009 20:44:33 -0500
parents 9548b406a2d8
children 037bba1c6736
files hgsubversion/svnwrap/svn_swig_wrapper.py tests/test_urls.py
diffstat 2 files changed, 37 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- 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)
--- 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():