diff --git a/tests/test_api.py b/tests/test_api.py index fde1617f5a..14ae12c973 100755 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -725,6 +725,34 @@ def test_targetfile_from_data(self) -> None: targetfile_from_data = TargetFile.from_data(target_file_path, data) targetfile_from_data.verify_length_and_hashes(data) + def test_targetfile_get_prefixed_paths(self) -> None: + target = TargetFile(100, {"sha256": "abc", "md5": "def"}, "a/b/f.ext") + self.assertEqual( + target.get_prefixed_paths(), ["a/b/abc.f.ext", "a/b/def.f.ext"] + ) + + target = TargetFile(100, {"sha256": "abc", "md5": "def"}, "") + self.assertEqual(target.get_prefixed_paths(), ["abc.", "def."]) + + target = TargetFile(100, {"sha256": "abc", "md5": "def"}, "a/b/") + self.assertEqual(target.get_prefixed_paths(), ["a/b/abc.", "a/b/def."]) + + target = TargetFile(100, {"sha256": "abc", "md5": "def"}, "f.ext") + self.assertEqual( + target.get_prefixed_paths(), ["abc.f.ext", "def.f.ext"] + ) + + target = TargetFile(100, {"sha256": "abc", "md5": "def"}, "a/b/.ext") + self.assertEqual( + target.get_prefixed_paths(), ["a/b/abc..ext", "a/b/def..ext"] + ) + + target = TargetFile(100, {"sha256": "abc"}, "/root/file.ext") + self.assertEqual(target.get_prefixed_paths(), ["/root/abc.file.ext"]) + + target = TargetFile(100, {"sha256": "abc"}, "/") + self.assertEqual(target.get_prefixed_paths(), ["/abc."]) + def test_is_delegated_role(self) -> None: # test path matches # see more extensive tests in test_is_target_in_pathpattern() diff --git a/tuf/api/metadata.py b/tuf/api/metadata.py index c21fc3eb31..cf739892eb 100644 --- a/tuf/api/metadata.py +++ b/tuf/api/metadata.py @@ -1737,6 +1737,17 @@ def verify_length_and_hashes(self, data: Union[bytes, IO[bytes]]) -> None: self._verify_length(data, self.length) self._verify_hashes(data, self.hashes) + def get_prefixed_paths(self) -> List[str]: + """ + Return hash-prefixed URL path fragments for the target file path. + """ + paths = [] + parent, sep, name = self.path.rpartition("/") + for hash_value in self.hashes.values(): + paths.append(f"{parent}{sep}{hash_value}.{name}") + + return paths + class Targets(Signed): """A container for the signed part of targets metadata.