mirror of
https://github.com/theupdateframework/python-tuf
synced 2026-05-24 10:08:28 +00:00
Update, test, and complete Issue #100 target methods.
Improve targets_of_role(rolename) behavior. It now updates the minimum metadata needed for 'rolename'. Ensure all_targets() adds targets in the expected order, where parent role targets come before children. Minor updates to comments and docstrings.
This commit is contained in:
parent
a2db039cf0
commit
c39abf9e6c
2 changed files with 33 additions and 13 deletions
|
|
@ -1892,7 +1892,9 @@ def all_targets(self):
|
|||
<Purpose>
|
||||
Get a list of the target information for all the trusted targets
|
||||
on the repository. This list also includes all the targets of
|
||||
delegated roles. The list conforms to 'tuf.formats.TARGETFILES_SCHEMA'
|
||||
delegated roles. Targets of the list returned are ordered according
|
||||
the trusted order of the delegated roles, where parent roles come before
|
||||
children. The list conforms to 'tuf.formats.TARGETFILES_SCHEMA'
|
||||
and has the form:
|
||||
|
||||
[{'filepath': 'a/b/c.txt',
|
||||
|
|
@ -1923,11 +1925,12 @@ def all_targets(self):
|
|||
self._refresh_targets_metadata(include_delegations=True)
|
||||
|
||||
all_targets = []
|
||||
|
||||
# Fetch the targets for the 'targets' role.
|
||||
all_targets = self._targets_of_role('targets', skip_refresh=True)
|
||||
|
||||
# Fetch the targets for the delegated roles.
|
||||
for delegated_role in tuf.roledb.get_delegated_rolenames('targets'):
|
||||
# Fetch the targets of the delegated roles.
|
||||
for delegated_role in sorted(tuf.roledb.get_delegated_rolenames('targets')):
|
||||
all_targets = self._targets_of_role(delegated_role, all_targets,
|
||||
skip_refresh=True)
|
||||
|
||||
|
|
@ -2061,7 +2064,7 @@ def refresh_targets_metadata_chain(self, rolename):
|
|||
if it has expired.
|
||||
|
||||
<Returns>
|
||||
None.
|
||||
A list of the roles that have been updated, loaded, and are valid.
|
||||
"""
|
||||
|
||||
# Do the arguments have the correct format?
|
||||
|
|
@ -2093,7 +2096,7 @@ def refresh_targets_metadata_chain(self, rolename):
|
|||
parent_roles.append(roles_added+'/'+next_role)
|
||||
roles_added = roles_added+'/'+next_role
|
||||
|
||||
message = 'Minimum metadata to download to set the chain of trust: '+\
|
||||
message = 'Minimum metadata to download and set the chain of trust: '+\
|
||||
repr(parent_roles)+'.'
|
||||
logger.info(message)
|
||||
|
||||
|
|
@ -2127,7 +2130,8 @@ def refresh_targets_metadata_chain(self, rolename):
|
|||
logger.debug('Roles to update: '+repr(parent_roles)+'.')
|
||||
|
||||
# Iterate 'parent_roles', load each role's metadata file from disk, and
|
||||
# update it if it has changed.
|
||||
# update it if it has changed.
|
||||
refreshed_chain = []
|
||||
for rolename in parent_roles:
|
||||
self._load_metadata_from_file('previous', rolename)
|
||||
self._load_metadata_from_file('current', rolename)
|
||||
|
|
@ -2137,9 +2141,12 @@ def refresh_targets_metadata_chain(self, rolename):
|
|||
# Remove the role if it has expired.
|
||||
try:
|
||||
self._ensure_not_expired(rolename)
|
||||
refreshed_chain.append(rolename)
|
||||
except tuf.ExpiredMetadataError:
|
||||
tuf.roledb.remove_role(rolename)
|
||||
|
||||
return refreshed_chain
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -2150,6 +2157,7 @@ def _targets_of_role(self, rolename, targets=None, skip_refresh=False):
|
|||
Return the target information for all the targets of 'rolename'.
|
||||
The returned information is a list conformant to
|
||||
'tuf.formats.TARGETFILES_SCHEMA' and has the form:
|
||||
|
||||
[{'filepath': 'a/b/c.txt',
|
||||
'fileinfo': {'length': 13323,
|
||||
'hashes': {'sha256': dbfac345..}}
|
||||
|
|
@ -2195,7 +2203,7 @@ def _targets_of_role(self, rolename, targets=None, skip_refresh=False):
|
|||
|
||||
# Do we have metadata for 'rolename'?
|
||||
if rolename not in self.metadata['current']:
|
||||
message = 'No metadata for '+rolename+'. Unable to determine targets.'
|
||||
message = 'No metadata for '+repr(rolename)+'. Unable to determine targets.'
|
||||
logger.debug(message)
|
||||
return targets
|
||||
|
||||
|
|
@ -2219,13 +2227,11 @@ def targets_of_role(self, rolename='targets'):
|
|||
Return a list of trusted targets directly specified by 'rolename'.
|
||||
The returned information is a list conformant to
|
||||
tuf.formats.TARGETFILES_SCHEMA and has the form:
|
||||
|
||||
[{'filepath': 'a/b/c.txt',
|
||||
'fileinfo': {'length': 13323,
|
||||
'hashes': {'sha256': dbfac345..}}
|
||||
...]
|
||||
|
||||
This may be a very slow operation if there is a large number of
|
||||
delegations and many metadata files aren't already downloaded.
|
||||
|
||||
<Arguments>
|
||||
rolename:
|
||||
|
|
@ -2253,8 +2259,9 @@ def targets_of_role(self, rolename='targets'):
|
|||
# Raise 'tuf.FormatError' if there is a mismatch.
|
||||
tuf.formats.RELPATH_SCHEMA.check_match(rolename)
|
||||
|
||||
self.refresh_targets_metadata_chain(rolename)
|
||||
self._refresh_targets_metadata(rolename)
|
||||
|
||||
|
||||
return self._targets_of_role(rolename, skip_refresh=True)
|
||||
|
||||
|
||||
|
|
@ -2641,6 +2648,7 @@ def updated_targets(self, targets, destination_directory):
|
|||
|
||||
The returned information is a list conformant to
|
||||
'tuf.formats.TARGETFILES_SCHEMA' and has the form:
|
||||
|
||||
[{'filepath': 'a/b/c.txt',
|
||||
'fileinfo': {'length': 13323,
|
||||
'hashes': {'sha256': dbfac345..}}
|
||||
|
|
@ -2648,7 +2656,8 @@ def updated_targets(self, targets, destination_directory):
|
|||
|
||||
<Arguments>
|
||||
targets:
|
||||
A list of target files.
|
||||
A list of target files. Targets that come earlier in the list are
|
||||
chosen over duplicates that may occur later.
|
||||
|
||||
destination_directory:
|
||||
The directory containing the target files.
|
||||
|
|
@ -2669,13 +2678,20 @@ def updated_targets(self, targets, destination_directory):
|
|||
tuf.formats.TARGETFILES_SCHEMA.check_match(targets)
|
||||
tuf.formats.PATH_SCHEMA.check_match(destination_directory)
|
||||
|
||||
# Keep track of the target objects and filepaths of updated targets.
|
||||
# Return 'updated_targets' and use 'updated_targetpaths' to avoid
|
||||
# duplicates.
|
||||
updated_targets = []
|
||||
updated_targetpaths = []
|
||||
|
||||
for target in targets:
|
||||
# Get the target's filepath located in 'destination_directory'.
|
||||
# We will compare targets against this file.
|
||||
target_filepath = os.path.join(destination_directory, target['filepath'])
|
||||
|
||||
if target_filepath in updated_targetpaths:
|
||||
continue
|
||||
|
||||
# Try one of the algorithm/digest combos for a mismatch. We break
|
||||
# as soon as we find a mismatch.
|
||||
for algorithm, digest in target['fileinfo']['hashes'].items():
|
||||
|
|
@ -2683,13 +2699,17 @@ def updated_targets(self, targets, destination_directory):
|
|||
try:
|
||||
digest_object = tuf.hash.digest_filename(target_filepath,
|
||||
algorithm=algorithm)
|
||||
|
||||
# This exception would occur if the target does not exist locally.
|
||||
except IOError:
|
||||
updated_targets.append(target)
|
||||
updated_targetpaths.append(target_filepath)
|
||||
break
|
||||
|
||||
# The file does exist locally, check if its hash differs.
|
||||
if digest_object.hexdigest() != digest:
|
||||
updated_targets.append(target)
|
||||
updated_targetpaths.append(target_filepath)
|
||||
break
|
||||
|
||||
return updated_targets
|
||||
|
|
|
|||
|
|
@ -2658,7 +2658,7 @@ def load_repository(repository_directory):
|
|||
targets_objects[tuf.roledb.get_parent_rolename(metadata_name)]
|
||||
targets_objects[metadata_name] = new_targets_object
|
||||
|
||||
self._delegated_roles[(os.path.basename(metadata_name))] = \
|
||||
targets_object._delegated_roles[(os.path.basename(metadata_name))] = \
|
||||
new_targets_object
|
||||
|
||||
# Add the keys specified in the delegations field of the Targets role.
|
||||
|
|
|
|||
Loading…
Reference in a new issue