Skip to content
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

git: allow http auth via dulwich #5567

Merged
merged 1 commit into from
May 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ jobs:
run: poetry run mypy

- name: Run pytest (integration suite)
env:
POETRY_TEST_INTEGRATION_GIT_USERNAME: ${GITHUB_ACTOR}
POETRY_TEST_INTEGRATION_GIT_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
run: poetry run python -m pytest -p no:sugar -q --integration tests/integration

- name: Get Plugin Version (poetry-plugin-export)
Expand Down
4 changes: 2 additions & 2 deletions src/poetry/repositories/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from poetry.core.packages.utils.link import Link
from poetry.core.version.markers import parse_marker

from poetry.config.config import Config
from poetry.repositories.cached import CachedRepository
from poetry.repositories.exceptions import PackageNotFound
from poetry.repositories.exceptions import RepositoryError
Expand All @@ -29,6 +28,7 @@


if TYPE_CHECKING:
from poetry.config.config import Config
from poetry.inspection.info import PackageInfo


Expand All @@ -43,7 +43,7 @@ def __init__(
super().__init__(name, disable_cache)
self._url = url
self._authenticator = Authenticator(
config=config or Config(use_environment=True),
config=config,
abn marked this conversation as resolved.
Show resolved Hide resolved
cache_id=name,
disable_cache=disable_cache,
)
Expand Down
19 changes: 15 additions & 4 deletions src/poetry/utils/authenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from cachecontrol import CacheControl
from cachecontrol.caches import FileCache

from poetry.config.config import Config
from poetry.exceptions import PoetryException
from poetry.locations import REPOSITORY_CACHE_DIR
from poetry.utils.helpers import get_cert
Expand All @@ -31,8 +32,6 @@

from cleo.io.io import IO

from poetry.config.config import Config


logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -84,12 +83,12 @@ def get_http_credentials(
class Authenticator:
def __init__(
self,
config: Config,
config: Config | None = None,
io: IO | None = None,
cache_id: str | None = None,
disable_cache: bool = False,
) -> None:
self._config = config
self._config = config or Config(use_environment=True)
self._io = io
self._sessions_for_netloc: dict[str, requests.Session] = {}
self._credentials: dict[str, HTTPAuthCredential] = {}
Expand Down Expand Up @@ -371,3 +370,15 @@ def _get_certs_for_url(self, url: str) -> dict[str, Path | None]:
if selected:
return selected.certs(config=self._config)
return {"cert": None, "verify": None}


_authenticator: Authenticator | None = None


def get_default_authenticator() -> Authenticator:
global _authenticator

if _authenticator is None:
_authenticator = Authenticator()

return _authenticator
7 changes: 6 additions & 1 deletion src/poetry/vcs/git/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from dulwich.repo import Repo

from poetry.console.exceptions import PoetrySimpleConsoleException
from poetry.utils.authenticator import get_default_authenticator
from poetry.utils.helpers import remove_directory


Expand Down Expand Up @@ -181,7 +182,11 @@ def _fetch_remote_refs(cls, url: str, local: Repo) -> FetchPackResult:
"""
client: GitClient
path: str
client, path = get_transport_and_path(url)

credentials = get_default_authenticator().get_credentials_for_url(url=url)
client, path = get_transport_and_path(
url, username=credentials.username, password=credentials.password
)

with local:
return client.fetch(
Expand Down
49 changes: 49 additions & 0 deletions tests/integration/test_utils_vcs_git.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import os
import uuid

from copy import deepcopy
Expand All @@ -15,6 +16,7 @@
from poetry.core.pyproject.toml import PyProjectTOML

from poetry.console.exceptions import PoetrySimpleConsoleException
from poetry.utils.authenticator import Authenticator
from poetry.vcs.git import Git
from poetry.vcs.git.backend import GitRefSpec

Expand Down Expand Up @@ -249,6 +251,53 @@ def test_system_git_fallback_on_http_401(
spy.assert_called_once()


GIT_USERNAME = os.environ.get("POETRY_TEST_INTEGRATION_GIT_USERNAME")
GIT_PASSWORD = os.environ.get("POETRY_TEST_INTEGRATION_GIT_PASSWORD")
HTTP_AUTH_CREDENTIALS_AVAILABLE = not (GIT_USERNAME and GIT_PASSWORD)


@pytest.mark.skipif(
HTTP_AUTH_CREDENTIALS_AVAILABLE,
reason="HTTP authentication credentials not available",
)
def test_configured_repository_http_auth(
mocker: MockerFixture, source_url: str, config: Config
) -> None:
from poetry.vcs.git import backend

spy_clone_legacy = mocker.spy(Git, "_clone_legacy")
spy_get_transport_and_path = mocker.spy(backend, "get_transport_and_path")

config.merge(
{
"repositories": {"git-repo": {"url": source_url}},
"http-basic": {
"git-repo": {
"username": GIT_USERNAME,
"password": GIT_PASSWORD,
}
},
}
)

mocker.patch(
"poetry.vcs.git.backend.get_default_authenticator",
return_value=Authenticator(config=config),
)

with Git.clone(url=source_url, branch="0.1") as repo:
assert_version(repo, BRANCH_TO_REVISION_MAP["0.1"])

spy_clone_legacy.assert_not_called()

spy_get_transport_and_path.assert_called_with(
location=source_url,
username=GIT_USERNAME,
password=GIT_PASSWORD,
)
spy_get_transport_and_path.assert_called_once()


def test_system_git_called_when_configured(
mocker: MockerFixture, source_url: str, use_system_git_client: None
) -> None:
Expand Down