diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 865039d..bea275d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,11 +20,11 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.7, 3.8, 3.9, "3.10", "3.11"] + python-version: [3.7, 3.8, 3.9, "3.10", "3.11", 3.12] os: [ubuntu-latest, macOS-latest, windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up PDM uses: pdm-project/setup-pdm@v3 with: diff --git a/noxfile.py b/noxfile.py index 414ba84..67ea5ea 100644 --- a/noxfile.py +++ b/noxfile.py @@ -5,13 +5,13 @@ os.environ.update(PDM_IGNORE_SAVED_PYTHON="1", PDM_USE_VENV="1") -@nox.session(python=("3.7", "3.8", "3.9", "3.10", "3.11")) +@nox.session(python=("3.7", "3.8", "3.9", "3.10", "3.11", "3.12")) def test(session): session.run("pdm", "install", "-Gtest", external=True) session.run("pytest", "tests/") -@nox.session(python="3.9") +@nox.session(python="3.11") def docs(session): session.install("-r", "docs/requirements.txt") @@ -19,7 +19,7 @@ def docs(session): session.run("sphinx-build", "-n", "-W", "-b", "html", "docs/", "build/docs") -@nox.session(name="docs-live", python="3.10") +@nox.session(name="docs-live", python="3.11") def docs_live(session): session.install("-r", "docs/requirements.txt") session.install("-e", ".") diff --git a/src/unearth/auth.py b/src/unearth/auth.py index d78a04b..b056b46 100644 --- a/src/unearth/auth.py +++ b/src/unearth/auth.py @@ -176,7 +176,7 @@ def _get_new_credentials( self, original_url: str, *, - allow_netrc: bool = False, + allow_netrc: bool = True, allow_keyring: bool = False, ) -> tuple[str | None, str | None]: """Find and return credentials for the specified URL.""" @@ -236,7 +236,9 @@ def _get_url_and_credentials( _, url = split_auth_from_url(original_url) netloc = urlparse(url).netloc # Try to get credentials from original url - username, password = self._get_new_credentials(original_url) + username, password = self._get_new_credentials( + original_url, allow_netrc=True, allow_keyring=False + ) # If credentials not found, use any stored credentials for this netloc. # Do this if either the username or the password is missing. @@ -263,8 +265,8 @@ def __call__(self, req: PreparedRequest) -> PreparedRequest: if username is not None and password is not None: req = HTTPBasicAuth(username, password)(req) - # Attach a hook to handle 400 responses - req.register_hook("response", self.handle_400s) + # Attach a hook to handle 401 responses + req.register_hook("response", self.handle_401) return req @@ -285,10 +287,10 @@ def _should_save_password_to_keyring(self) -> bool: return False return input("Save credentials to keyring [y/N]: ") == "y" - def handle_400s(self, resp: Response, **kwargs: Any) -> Response: - # We only care about 401, 403, 404 responses, anything else we want to just + def handle_401(self, resp: Response, **kwargs: Any) -> Response: + # We only care about 401 response, anything else we want to just # pass through the actual response - if resp.status_code not in [401, 403, 404]: + if resp.status_code != 401: return resp parsed = urlparse(cast(str, resp.url)) @@ -296,7 +298,7 @@ def handle_400s(self, resp: Response, **kwargs: Any) -> Response: # Query the keyring for credentials: username, password = self._get_new_credentials( resp.url, - allow_netrc=True, + allow_netrc=False, allow_keyring=True, ) @@ -304,8 +306,7 @@ def handle_400s(self, resp: Response, **kwargs: Any) -> Response: save = False if not username and not password: # We are not able to prompt the user so simply return the response - # Also, do not prompt on 404 - if not self.prompting or resp.status_code == 404: + if not self.prompting: return resp username, password, save = self._prompt_for_password(parsed.netloc) @@ -328,7 +329,7 @@ def handle_400s(self, resp: Response, **kwargs: Any) -> Response: req = HTTPBasicAuth(username or "", password or "")(resp.request) # We add new hooks on the fly, since the req is the same as resp.request # The hook will be picked up by the next iteration of `dispatch_hooks()` - req.register_hook("response", self.warn_on_401_403_404) + req.register_hook("response", self.warn_on_401) # On successful request, save the credentials that were used to # keyring. (Note that if the user responded "no" above, this member @@ -342,9 +343,9 @@ def handle_400s(self, resp: Response, **kwargs: Any) -> Response: return new_resp - def warn_on_401_403_404(self, resp: Response, **kwargs: Any) -> None: + def warn_on_401(self, resp: Response, **kwargs: Any) -> None: """Response callback to warn about incorrect credentials.""" - if resp.status_code in [401, 403, 404]: + if resp.status_code == 401: logger.warning( "%s Error, Credentials not correct for %s", resp.status_code,