Просмотр исходного кода

#475: Unquoting credentials before passing them over to urllib2

Volodymyr Holovko 8 лет назад
Родитель
Сommit
3e5ec543ca
2 измененных файлов с 37 добавлено и 0 удалено
  1. 6 0
      dulwich/client.py
  2. 31 0
      dulwich/tests/test_client.py

+ 6 - 0
dulwich/client.py

@@ -50,8 +50,10 @@ import sys
 
 try:
     from urllib import quote as urlquote
+    from urllib import unquote as urlunquote
 except ImportError:
     from urllib.parse import quote as urlquote
+    from urllib.parse import unquote as urlunquote
 
 try:
     import urllib2
@@ -1064,7 +1066,11 @@ class HttpGitClient(GitClient):
     def from_parsedurl(cls, parsedurl, **kwargs):
         auth, host = urllib2.splituser(parsedurl.netloc)
         password = parsedurl.password
+        if password is not None:
+            password = urlunquote(password)
         username = parsedurl.username
+        if username is not None:
+            username = urlunquote(username)
         # TODO(jelmer): This also strips the username
         parsedurl = parsedurl._replace(netloc=host)
         return cls(urlparse.urlunparse(parsedurl),

+ 31 - 0
dulwich/tests/test_client.py

@@ -23,6 +23,15 @@ import sys
 import shutil
 import tempfile
 
+try:
+    from urllib import quote as urlquote
+except ImportError:
+    from urllib.parse import quote as urlquote
+
+try:
+    import urlparse
+except ImportError:
+    import urllib.parse as urlparse
 
 import dulwich
 from dulwich import (
@@ -819,6 +828,28 @@ class HttpGitClientTests(TestCase):
             h for h in c.opener.handlers if getattr(h, 'passwd', None) is not None]
         self.assertEqual(0, len(pw_handler))
 
+    def test_from_parsedurl_on_url_with_quoted_credentials(self):
+        original_username = 'john|the|first'
+        quoted_username = urlquote(original_username)
+
+        original_password = 'Ya#1$2%3'
+        quoted_password = urlquote(original_password)
+
+        url = 'https://{username}:{password}@github.com/jelmer/dulwich'.format(
+            username=quoted_username,
+            password=quoted_password
+        )
+
+        c = HttpGitClient.from_parsedurl(urlparse.urlparse(url))
+        self.assertEqual(original_username, c._username)
+        self.assertEqual(original_password, c._password)
+        [pw_handler] = [
+            h for h in c.opener.handlers if getattr(h, 'passwd', None) is not None]
+        self.assertEqual(
+            (original_username, original_password),
+            pw_handler.passwd.find_user_password(
+                None, 'https://github.com/jelmer/dulwich'))
+
 
 class TCPGitClientTests(TestCase):