diff --git a/vcsserver/remote/git_remote.py b/vcsserver/remote/git_remote.py --- a/vcsserver/remote/git_remote.py +++ b/vcsserver/remote/git_remote.py @@ -41,7 +41,7 @@ from dulwich.server import update_server import rhodecode from vcsserver import exceptions, settings, subprocessio -from vcsserver.str_utils import safe_str, safe_int, safe_bytes, ascii_bytes +from vcsserver.str_utils import safe_str, safe_int, safe_bytes, ascii_bytes, convert_to_str from vcsserver.base import RepoFactory, obfuscate_qs, ArchiveNode, store_archive_in_cache, BytesEnvelope, BinaryEnvelope from vcsserver.hgcompat import ( hg_url as url_parser, httpbasicauthhandler, httpdigestauthhandler) @@ -461,18 +461,10 @@ class GitRemote(RemoteBase): url_obj = url_parser(safe_bytes(url)) authinfo = url_obj.authinfo()[1] - def _convert_to_strings(data): - if isinstance(data, bytes): - return safe_str(data) - elif isinstance(data, tuple): - return tuple(_convert_to_strings(item) for item in data) - else: - return data - if authinfo: # create a password manager passmgr = urllib.request.HTTPPasswordMgrWithDefaultRealm() - passmgr.add_password(*_convert_to_strings(authinfo)) + passmgr.add_password(*convert_to_str(authinfo)) handlers.extend((httpbasicauthhandler(passmgr), httpdigestauthhandler(passmgr))) diff --git a/vcsserver/remote/hg_remote.py b/vcsserver/remote/hg_remote.py --- a/vcsserver/remote/hg_remote.py +++ b/vcsserver/remote/hg_remote.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + import binascii import io import logging @@ -23,7 +24,7 @@ import urllib.request import urllib.parse import hashlib -from hgext import largefiles, rebase, purge +from hgext import largefiles, rebase from mercurial import commands from mercurial import unionrepo @@ -74,10 +75,9 @@ from vcsserver.hgcompat import ( RequirementError, alwaysmatcher, patternmatcher, - hgutil, hgext_strip, ) -from vcsserver.str_utils import ascii_bytes, ascii_str, safe_str, safe_bytes +from vcsserver.str_utils import ascii_bytes, ascii_str, safe_str, safe_bytes, convert_to_str from vcsserver.vcs_base import RemoteBase from vcsserver.config import hooks as hooks_config from vcsserver.lib.exc_tracking import format_exc @@ -488,7 +488,7 @@ class HgRemote(RemoteBase): if authinfo: # create a password manager passmgr = urllib.request.HTTPPasswordMgrWithDefaultRealm() - passmgr.add_password(*authinfo) + passmgr.add_password(*convert_to_str(authinfo)) handlers.extend((httpbasicauthhandler(passmgr), httpdigestauthhandler(passmgr))) diff --git a/vcsserver/str_utils.py b/vcsserver/str_utils.py --- a/vcsserver/str_utils.py +++ b/vcsserver/str_utils.py @@ -131,3 +131,14 @@ def ascii_str(str_) -> str: if not isinstance(str_, bytes): raise ValueError(f'ascii_str cannot convert other types than bytes: got: {type(str_)}') return str_.decode('ascii') + + +def convert_to_str(data): + if isinstance(data, bytes): + return safe_str(data) + elif isinstance(data, tuple): + return tuple(convert_to_str(item) for item in data) + elif isinstance(data, list): + return list(convert_to_str(item) for item in data) + else: + return data diff --git a/vcsserver/tests/test_utils.py b/vcsserver/tests/test_utils.py --- a/vcsserver/tests/test_utils.py +++ b/vcsserver/tests/test_utils.py @@ -16,7 +16,7 @@ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import pytest -from vcsserver.str_utils import ascii_bytes, ascii_str +from vcsserver.str_utils import ascii_bytes, ascii_str, convert_to_str @pytest.mark.parametrize('given, expected', [ @@ -51,3 +51,19 @@ def test_ascii_str(given, expected): def test_ascii_str_raises(given): with pytest.raises(ValueError): ascii_str(given) + + +@pytest.mark.parametrize('given, expected', [ + ('a', 'a'), + (b'a', 'a'), + # tuple + (('a', b'b', b'c'), ('a', 'b', 'c')), + # nested tuple + (('a', b'b', (b'd', b'e')), ('a', 'b', ('d', 'e'))), + # list + (['a', b'b', b'c'], ['a', 'b', 'c']), + # mixed + (['a', b'b', b'c', (b'b1', b'b2')], ['a', 'b', 'c', ('b1', 'b2')]) +]) +def test_convert_to_str(given, expected): + assert convert_to_str(given) == expected