Commit 51a112f1 by Colin Dean Committed by GitHub

Improves hash mismatch exception language (#4573)

* Improves wording of exception when calculated hash absent from lockfile and
extracts archive hashing and validation to a separate method

I think this could be further improved by representing the hashes as
a dataclass containing the hash type and the string digest. The types of
hashes would be more robust then instead of hardcoding sha256 here and
in `FileDependency.hash()`. It would also enable enumeration of
hash types of known hashes so that `FileDependency.hash()` could return
a list of hashes based on requested types.

Doing this might alleviate the md5/sha256 problems arising from changes
in poetry-core 1.0.6+ that affect Poetry 1.1.7+ users using Artifactory.

Co-authored-by: Arun Babu Neelicattu <arun.neelicattu@gmail.com>
parent d7982539
...@@ -17,6 +17,7 @@ from typing import Union ...@@ -17,6 +17,7 @@ from typing import Union
from cleo.io.null_io import NullIO from cleo.io.null_io import NullIO
from poetry.core.packages.file_dependency import FileDependency from poetry.core.packages.file_dependency import FileDependency
from poetry.core.packages.package import Package
from poetry.core.packages.utils.link import Link from poetry.core.packages.utils.link import Link
from poetry.core.pyproject.toml import PyProjectTOML from poetry.core.pyproject.toml import PyProjectTOML
from poetry.utils._compat import decode from poetry.utils._compat import decode
...@@ -38,7 +39,6 @@ if TYPE_CHECKING: ...@@ -38,7 +39,6 @@ if TYPE_CHECKING:
from cleo.io.io import IO # noqa from cleo.io.io import IO # noqa
from poetry.config.config import Config from poetry.config.config import Config
from poetry.core.packages.package import Package
from poetry.repositories import Pool from poetry.repositories import Pool
from poetry.utils.env import Env from poetry.utils.env import Env
...@@ -671,22 +671,28 @@ class Executor: ...@@ -671,22 +671,28 @@ class Executor:
archive = self._chef.prepare(archive) archive = self._chef.prepare(archive)
if package.files: if package.files:
archive_hash = ( archive_hash = self._validate_archive_hash(archive, package)
"sha256:"
+ FileDependency(
package.name,
Path(archive.path) if isinstance(archive, Link) else archive,
).hash()
)
if archive_hash not in {f["hash"] for f in package.files}:
raise RuntimeError(
f"Invalid hash for {package} using archive {archive.name}"
)
self._hashes[package.name] = archive_hash self._hashes[package.name] = archive_hash
return archive return archive
@staticmethod
def _validate_archive_hash(archive: Path, package: Package) -> str:
file_dep = FileDependency(
package.name,
Path(archive.path) if isinstance(archive, Link) else archive,
)
archive_hash = "sha256:" + file_dep.hash()
known_hashes = {f["hash"] for f in package.files}
if archive_hash not in known_hashes:
raise RuntimeError(
f"Hash for {package} from archive {archive.name} not found in known hashes (was: {archive_hash})"
)
return archive_hash
def _download_archive(self, operation: Union[Install, Update], link: Link) -> Path: def _download_archive(self, operation: Union[Install, Update], link: Link) -> Path:
response = self._authenticator.request( response = self._authenticator.request(
"get", link.url, stream=True, io=self._sections.get(id(operation), self._io) "get", link.url, stream=True, io=self._sections.get(id(operation), self._io)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment