# HG changeset patch # User Thomas De Schampheleire # Date 1598122423 -7200 # Node ID 3e9d079fcf914ef42c5e109bf389e02abea100ba # Parent 1dbe842f32c43f9ca9ebc8b7d9331bed8c750382# Parent eca0cb56a822690c58e6237e9787cd8cfa77fddc merge stable diff -r 1dbe842f32c4 -r 3e9d079fcf91 kallithea/bin/base.py --- a/kallithea/bin/base.py Sat Jul 25 18:44:59 2020 +0200 +++ b/kallithea/bin/base.py Sat Aug 22 20:53:43 2020 +0200 @@ -130,7 +130,7 @@ update = True with open(self._conf_name, 'wb') as f: ext_json.dump(config, f, indent=4) - f.write('\n') + f.write(b'\n') if update: sys.stdout.write('Updated config in %s\n' % self._conf_name) diff -r 1dbe842f32c4 -r 3e9d079fcf91 kallithea/lib/vcs/backends/git/repository.py --- a/kallithea/lib/vcs/backends/git/repository.py Sat Jul 25 18:44:59 2020 +0200 +++ b/kallithea/lib/vcs/backends/git/repository.py Sat Aug 22 20:53:43 2020 +0200 @@ -19,7 +19,6 @@ import urllib.request from collections import OrderedDict -import mercurial.url # import httpbasicauthhandler, httpdigestauthhandler import mercurial.util # import url as hg_url from dulwich.config import ConfigFile from dulwich.objects import Tag @@ -31,6 +30,7 @@ from kallithea.lib.vcs.exceptions import (BranchDoesNotExistError, ChangesetDoesNotExistError, EmptyRepositoryError, RepositoryError, TagAlreadyExistError, TagDoesNotExistError) from kallithea.lib.vcs.utils import ascii_str, date_fromtimestamp, makedate, safe_bytes, safe_str +from kallithea.lib.vcs.utils.helpers import get_urllib_request_handlers from kallithea.lib.vcs.utils.lazy import LazyProperty from kallithea.lib.vcs.utils.paths import abspath, get_user_home @@ -168,23 +168,14 @@ if '+' in url[:url.find('://')]: url = url[url.find('+') + 1:] - handlers = [] url_obj = mercurial.util.url(safe_bytes(url)) - test_uri, authinfo = url_obj.authinfo() + test_uri, handlers = get_urllib_request_handlers(url_obj) if not test_uri.endswith(b'info/refs'): test_uri = test_uri.rstrip(b'/') + b'/info/refs' url_obj.passwd = b'*****' cleaned_uri = str(url_obj) - if authinfo: - # create a password manager - passmgr = urllib.request.HTTPPasswordMgrWithDefaultRealm() - passmgr.add_password(*authinfo) - - handlers.extend((mercurial.url.httpbasicauthhandler(passmgr), - mercurial.url.httpdigestauthhandler(passmgr))) - o = urllib.request.build_opener(*handlers) o.addheaders = [('User-Agent', 'git/1.7.8.0')] # fake some git diff -r 1dbe842f32c4 -r 3e9d079fcf91 kallithea/lib/vcs/backends/hg/repository.py --- a/kallithea/lib/vcs/backends/hg/repository.py Sat Jul 25 18:44:59 2020 +0200 +++ b/kallithea/lib/vcs/backends/hg/repository.py Sat Aug 22 20:53:43 2020 +0200 @@ -33,13 +33,13 @@ import mercurial.sshpeer import mercurial.tags import mercurial.ui -import mercurial.url import mercurial.util from kallithea.lib.vcs.backends.base import BaseRepository, CollectionGenerator from kallithea.lib.vcs.exceptions import (BranchDoesNotExistError, ChangesetDoesNotExistError, EmptyRepositoryError, RepositoryError, TagAlreadyExistError, TagDoesNotExistError, VCSError) from kallithea.lib.vcs.utils import ascii_str, author_email, author_name, date_fromtimestamp, makedate, safe_bytes, safe_str +from kallithea.lib.vcs.utils.helpers import get_urllib_request_handlers from kallithea.lib.vcs.utils.lazy import LazyProperty from kallithea.lib.vcs.utils.paths import abspath @@ -308,27 +308,19 @@ if b'+' in url[:url.find(b'://')]: url_prefix, url = url.split(b'+', 1) - handlers = [] url_obj = mercurial.util.url(url) - test_uri, authinfo = url_obj.authinfo() + test_uri, handlers = get_urllib_request_handlers(url_obj) + url_obj.passwd = b'*****' cleaned_uri = str(url_obj) - if authinfo: - # create a password manager - passmgr = urllib.request.HTTPPasswordMgrWithDefaultRealm() - passmgr.add_password(*authinfo) - - handlers.extend((mercurial.url.httpbasicauthhandler(passmgr), - mercurial.url.httpdigestauthhandler(passmgr))) - o = urllib.request.build_opener(*handlers) o.addheaders = [('Content-Type', 'application/mercurial-0.1'), ('Accept', 'application/mercurial-0.1')] req = urllib.request.Request( "%s?%s" % ( - test_uri, + safe_str(test_uri), urllib.parse.urlencode({ 'cmd': 'between', 'pairs': "%s-%s" % ('0' * 40, '0' * 40), diff -r 1dbe842f32c4 -r 3e9d079fcf91 kallithea/lib/vcs/utils/helpers.py --- a/kallithea/lib/vcs/utils/helpers.py Sat Jul 25 18:44:59 2020 +0200 +++ b/kallithea/lib/vcs/utils/helpers.py Sat Aug 22 20:53:43 2020 +0200 @@ -6,8 +6,12 @@ import os import re import time +import urllib.request + +import mercurial.url from kallithea.lib.vcs.exceptions import RepositoryError, VCSError +from kallithea.lib.vcs.utils import safe_str from kallithea.lib.vcs.utils.paths import abspath @@ -217,3 +221,29 @@ for attr in attrs: data[attr] = getattr(obj, attr) return data + +def get_urllib_request_handlers(url_obj): + handlers = [] + test_uri, authinfo = url_obj.authinfo() + + if authinfo: + # authinfo is a tuple (realm, uris, user, password) where 'uris' itself + # is a tuple of URIs. + # If url_obj is obtained via mercurial.util.url, the obtained authinfo + # values will be bytes, e.g. + # (None, (b'http://127.0.0.1/repo', b'127.0.0.1'), b'user', b'pass') + # However, urllib expects strings, not bytes, so we must convert them. + + # create a password manager + passmgr = urllib.request.HTTPPasswordMgrWithDefaultRealm() + passmgr.add_password( + safe_str(authinfo[0]) if authinfo[0] else None, # realm + tuple(safe_str(x) for x in authinfo[1]), # uris + safe_str(authinfo[2]), # user + safe_str(authinfo[3]), # password + ) + + handlers.extend((mercurial.url.httpbasicauthhandler(passmgr), + mercurial.url.httpdigestauthhandler(passmgr))) + + return test_uri, handlers diff -r 1dbe842f32c4 -r 3e9d079fcf91 kallithea/tests/functional/test_admin_repos.py --- a/kallithea/tests/functional/test_admin_repos.py Sat Jul 25 18:44:59 2020 +0200 +++ b/kallithea/tests/functional/test_admin_repos.py Sat Aug 22 20:53:43 2020 +0200 @@ -344,6 +344,19 @@ _session_csrf_secret_token=self.session_csrf_secret_token())) response.mustcontain('Invalid repository URL') + def test_create_remote_repo_wrong_clone_uri_http_auth(self): + self.log_user() + repo_name = self.NEW_REPO + description = 'description for newly created repo' + response = self.app.post(base.url('repos'), + fixture._get_repo_create_params(repo_private=False, + repo_name=repo_name, + repo_type=self.REPO_TYPE, + repo_description=description, + clone_uri='http://user:pass@127.0.0.1/repo', + _session_csrf_secret_token=self.session_csrf_secret_token())) + response.mustcontain('Invalid repository URL') + def test_delete(self): self.log_user() repo_name = 'vcs_test_new_to_delete_%s' % self.REPO_TYPE