-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding support for HTTP Basic Auth when installing and searching from legacy repo (#233) #306
Conversation
@sdispater @cauebs This is ready for review anytime you have time! Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for taking the time to put this PR together!
I added some feedback and requested some changes. Nothing major and it should be pretty straightforward.
Tell me what you think.
if not url_parts.username: | ||
username, password = get_http_basic_auth(self.name) | ||
if username and password: | ||
netloc = "{}:{}@{}".format(username, password, url_parts.netloc) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of recreating the url by hand we can just pass the auth information to the session created in __init__()
. That way the _url
attribute is left untouched while still providing the auth information to each request made to the remote url.
self._session.auth = get_http_basic_auth(self.name)
For this to work we have to make a small change to get_http_basic_auth()
so that it returns None
when no authentication information could be found. This makes the code much simpler since we don't have to chech each time if username/password exist.
poetry/utils/helpers.py
Outdated
repo_auth = config.setting("http-basic.{}".format(repository_name)) | ||
if repo_auth: | ||
return repo_auth["username"], repo_auth["password"] | ||
return "", "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should return None
for the reasons specified above.
pyproject.toml
Outdated
@@ -55,6 +55,7 @@ pygments-github-lexers = "^0.0.5" | |||
black = { version = "^18.3-alpha.0", python = "^3.6" } | |||
pre-commit = "^1.10" | |||
tox = "^3.0" | |||
mock = "^2.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not necessary since we already have pytest-mock
which provides a more convenient way to mock objects and functions.
@@ -43,3 +44,11 @@ def test_page_absolute_links_path_are_correct(): | |||
for link in page.links: | |||
assert link.netloc == "files.pythonhosted.org" | |||
assert link.path.startswith("/packages/") | |||
|
|||
|
|||
@mock.patch("poetry.repositories.legacy_repository.get_http_basic_auth") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shoud use the mocker
fixture provided by pytest-mock
|
||
|
||
@mock.patch("poetry.repositories.legacy_repository.get_http_basic_auth") | ||
def test_http_basic_auth_repo(mock_get_auth): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing this will be more complex with the changes I requested since we will need to check the url that will be called in _get()
.
poetry/installation/pip_installer.py
Outdated
@@ -25,9 +25,14 @@ def install(self, package, update=False): | |||
if package.source_type == "legacy" and package.source_url: | |||
parsed = urlparse.urlparse(package.source_url) | |||
if parsed.scheme == "http": | |||
if not parsed.username: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the changes requested below. The authentication part of the url will not appear here, so this check is not necessary.
However, this will be an issue since pip
won't be aware of the credentials. So this is where we should modify the url to include the credentials, I think.
Thanks for the feedback, it's your project so we'll do it your way :P For the session, setting the I've actually been using my fork since last week and it's working great at least. |
@MarcDufresne It's weird that the downloads timeout by using the session. Could this be caused by the fact that we encapsulate the sessions in a |
I just checked and I can't reproduce the timeouts. Everything works on my end by using the session in the |
@sdispater Thanks for trying it on your end, can you share a snippet? IIRC I had to make Oh and I should be fixing the comments shortly! |
@MarcDufresne I just overrode |
Ok cool, I'll do it like that then, I didn't want to change too much code at first, but if you're okay with it, I'll do it like that. |
@sdispater Can you take a look at |
@MarcDufresne At the moment there is no easy way to retrieve the name of the repository from the lock file. I think we can store it in the See here: https://github.com/sdispater/poetry/blob/master/poetry/repositories/legacy_repository.py#L239 |
Thanks a lot for this! |
Well thanks for your feedback and accepting this! Glad to see poetry becoming even more useful :D |
@sdispater could you please release new version of poetry with this fix? |
… legacy repo (#233) (#306) * Adding support for HTTP Basic Auth when pulling from legacy repo * added docs * Adding unit test for http auth * Adding mock to dev deps * moved config reading logic to helper function, adapted test * corrections * rework pip_installer * use source_reference as repo name when writing lock file and installing
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Pull Request Check List
Hi! I really like
poetry
and would love to be able to use it at work, sadly it doesn't support HTTP Basic Auth when pulling from private repositories so that has kept us from using it. See #233That is why I have come up with this PR. It basically adds support for pulling from private repos using the auth values stored in
http-basic.<repo-name>
by inserting them in the repo URL dynamically. I've also made sure that the username and password are never output to the shell.While doing this I tried to have the most minimal impact on existing user. For example, anyone that already defines username and password directly in the URL of the
pyproject.toml
file won't suddenly have issues since I check for existing credentials and skip my code if anything is found (But I suggest those who do this now use thehttp-basic
configuration). Additionally, I make sure that if no credentials are found for this specific repo the URL won't be altered at all.I did not write tests yet because I wanted my design validated first and because I am not sure how to approach tests for this feature.I wrote a unit test that mocks reading
http-basic
from the config and uses the returned values to create a new URL and then validates that the URL was properly constructed.I have also tested the functionality locally using a devpi-server behind a HTTP Basic Auth protected web server, with the config below
pyproject.toml
: