Skip to content

Commit f778d36

Browse files
author
Ivana Atanasova
committed
Update ngclient to return loaded metadata
This changes `TrustedMetadataSet` to return new trusted Metadata on successful calls of the `update_<role>` functions and also changes `Updater._load_targets` to return loaded metadata as well Signed-off-by: Ivana Atanasova <[email protected]>
1 parent fa7990c commit f778d36

File tree

3 files changed

+54
-18
lines changed

3 files changed

+54
-18
lines changed

tests/test_trusted_metadata_set.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,21 @@ def test_update(self):
129129

130130
self.assertTrue(count, 6)
131131

132+
def test_update_metadata_output(self):
133+
timestamp = self.trusted_set.update_timestamp(self.metadata["timestamp"])
134+
snapshot = self.trusted_set.update_snapshot(self.metadata["snapshot"])
135+
self.trusted_set.update_targets(self.metadata["targets"])
136+
delegeted_targets_1 = self.trusted_set.update_delegated_targets(
137+
self.metadata["role1"], "role1", "targets"
138+
)
139+
delegeted_targets_2 = self.trusted_set.update_delegated_targets(
140+
self.metadata["role2"], "role2", "role1"
141+
)
142+
self.assertIsInstance(timestamp, Metadata)
143+
self.assertIsInstance(snapshot, Metadata)
144+
self.assertIsInstance(delegeted_targets_1, Metadata)
145+
self.assertIsInstance(delegeted_targets_2, Metadata)
146+
132147
def test_out_of_order_ops(self):
133148
# Update snapshot before timestamp
134149
with self.assertRaises(RuntimeError):

tuf/ngclient/_internal/trusted_metadata_set.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def targets(self) -> Optional[Metadata[Targets]]:
141141
return self._trusted_set.get("targets")
142142

143143
# Methods for updating metadata
144-
def update_root(self, data: bytes) -> None:
144+
def update_root(self, data: bytes) -> Metadata:
145145
"""Verifies and loads 'data' as new root metadata.
146146
147147
Note that an expired intermediate root is considered valid: expiry is
@@ -182,7 +182,9 @@ def update_root(self, data: bytes) -> None:
182182
self._trusted_set["root"] = new_root
183183
logger.info("Updated root v%d", new_root.signed.version)
184184

185-
def update_timestamp(self, data: bytes) -> None:
185+
return new_root
186+
187+
def update_timestamp(self, data: bytes) -> Metadata:
186188
"""Verifies and loads 'data' as new timestamp metadata.
187189
188190
Note that an intermediate timestamp is allowed to be expired:
@@ -251,6 +253,8 @@ def update_timestamp(self, data: bytes) -> None:
251253
# timestamp is loaded: raise if it is not valid _final_ timestamp
252254
self._check_final_timestamp()
253255

256+
return new_timestamp
257+
254258
def _check_final_timestamp(self) -> None:
255259
"""Raise if timestamp is expired"""
256260

@@ -260,7 +264,7 @@ def _check_final_timestamp(self) -> None:
260264

261265
def update_snapshot(
262266
self, data: bytes, trusted: Optional[bool] = False
263-
) -> None:
267+
) -> Metadata:
264268
"""Verifies and loads 'data' as new snapshot metadata.
265269
266270
Note that an intermediate snapshot is allowed to be expired and version
@@ -347,6 +351,8 @@ def update_snapshot(
347351
# snapshot is loaded, but we raise if it's not valid _final_ snapshot
348352
self._check_final_snapshot()
349353

354+
return new_snapshot
355+
350356
def _check_final_snapshot(self) -> None:
351357
"""Raise if snapshot is expired or meta version does not match"""
352358

@@ -375,7 +381,7 @@ def update_targets(self, data: bytes) -> None:
375381

376382
def update_delegated_targets(
377383
self, data: bytes, role_name: str, delegator_name: str
378-
) -> None:
384+
) -> Metadata:
379385
"""Verifies and loads 'data' as new metadata for target 'role_name'.
380386
381387
Args:
@@ -438,6 +444,8 @@ def update_delegated_targets(
438444
self._trusted_set[role_name] = new_delegate
439445
logger.info("Updated %s v%d", role_name, version)
440446

447+
return new_delegate
448+
441449
def _load_trusted_root(self, data: bytes) -> None:
442450
"""Verifies and loads 'data' as trusted root metadata.
443451

tuf/ngclient/updater.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
from securesystemslib import util as sslib_util
7373

7474
from tuf import exceptions
75-
from tuf.api.metadata import TargetFile, Targets
75+
from tuf.api.metadata import Metadata, TargetFile
7676
from tuf.ngclient._internal import requests_fetcher, trusted_metadata_set
7777
from tuf.ngclient.config import UpdaterConfig
7878
from tuf.ngclient.fetcher import FetcherInterface
@@ -331,7 +331,7 @@ def _load_root(self) -> None:
331331
# 404/403 means current root is newest available
332332
break
333333

334-
def _load_timestamp(self) -> None:
334+
def _load_timestamp(self) -> Metadata:
335335
"""Load local and remote timestamp metadata"""
336336
try:
337337
data = self._load_local_metadata("timestamp")
@@ -344,15 +344,18 @@ def _load_timestamp(self) -> None:
344344
data = self._download_metadata(
345345
"timestamp", self.config.timestamp_max_length
346346
)
347-
self._trusted_set.update_timestamp(data)
347+
timestamp = self._trusted_set.update_timestamp(data)
348348
self._persist_metadata("timestamp", data)
349349

350-
def _load_snapshot(self) -> None:
350+
return timestamp
351+
352+
def _load_snapshot(self) -> Metadata:
351353
"""Load local (and if needed remote) snapshot metadata"""
352354
try:
353355
data = self._load_local_metadata("snapshot")
354-
self._trusted_set.update_snapshot(data, trusted=True)
356+
snapshot = self._trusted_set.update_snapshot(data, trusted=True)
355357
logger.debug("Local snapshot is valid: not downloading new one")
358+
return snapshot
356359
except (OSError, exceptions.RepositoryError) as e:
357360
# Local snapshot does not exist or is invalid: update from remote
358361
logger.debug("Local snapshot not valid as final: %s", e)
@@ -365,15 +368,20 @@ def _load_snapshot(self) -> None:
365368
version = snapshot_meta.version
366369

367370
data = self._download_metadata("snapshot", length, version)
368-
self._trusted_set.update_snapshot(data)
371+
snapshot = self._trusted_set.update_snapshot(data)
369372
self._persist_metadata("snapshot", data)
370373

371-
def _load_targets(self, role: str, parent_role: str) -> None:
374+
return snapshot
375+
376+
def _load_targets(self, role: str, parent_role: str) -> Metadata:
372377
"""Load local (and if needed remote) metadata for 'role'."""
373378
try:
374379
data = self._load_local_metadata(role)
375-
self._trusted_set.update_delegated_targets(data, role, parent_role)
380+
delegated_targets = self._trusted_set.update_delegated_targets(
381+
data, role, parent_role
382+
)
376383
logger.debug("Local %s is valid: not downloading new one", role)
384+
return delegated_targets
377385
except (OSError, exceptions.RepositoryError) as e:
378386
# Local 'role' does not exist or is invalid: update from remote
379387
logger.debug("Failed to load local %s: %s", role, e)
@@ -386,9 +394,13 @@ def _load_targets(self, role: str, parent_role: str) -> None:
386394
version = metainfo.version
387395

388396
data = self._download_metadata(role, length, version)
389-
self._trusted_set.update_delegated_targets(data, role, parent_role)
397+
delegated_targets = self._trusted_set.update_delegated_targets(
398+
data, role, parent_role
399+
)
390400
self._persist_metadata(role, data)
391401

402+
return delegated_targets
403+
392404
def _preorder_depth_first_walk(
393405
self, target_filepath: str
394406
) -> Optional[TargetFile]:
@@ -417,10 +429,9 @@ def _preorder_depth_first_walk(
417429

418430
# The metadata for 'role_name' must be downloaded/updated before
419431
# its targets, delegations, and child roles can be inspected.
420-
self._load_targets(role_name, parent_role)
432+
role_metadata = self._load_targets(role_name, parent_role)
421433

422-
role_metadata: Targets = self._trusted_set[role_name].signed
423-
target = role_metadata.targets.get(target_filepath)
434+
target = role_metadata.signed.targets.get(target_filepath)
424435

425436
if target is not None:
426437
logger.debug("Found target in current role %s", role_name)
@@ -432,11 +443,13 @@ def _preorder_depth_first_walk(
432443
# And also decrement number of visited roles.
433444
number_of_delegations -= 1
434445

435-
if role_metadata.delegations is not None:
446+
if role_metadata.signed.delegations is not None:
436447
child_roles_to_visit = []
437448
# NOTE: This may be a slow operation if there are many
438449
# delegated roles.
439-
for child_role in role_metadata.delegations.roles.values():
450+
for (
451+
child_role
452+
) in role_metadata.signed.delegations.roles.values():
440453
if child_role.is_delegated_path(target_filepath):
441454
logger.debug("Adding child role %s", child_role.name)
442455

0 commit comments

Comments
 (0)