Skip to content

Commit

Permalink
Merge pull request #1456 from jku/tighten-comments
Browse files Browse the repository at this point in the history
Metadata API: Rewrite comments
  • Loading branch information
Jussi Kukkonen authored Jun 23, 2021
2 parents 7108ea2 + 79f4f41 commit f458e92
Showing 1 changed file with 61 additions and 116 deletions.
177 changes: 61 additions & 116 deletions tuf/api/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,7 @@
SignedSerializer,
)

# Disable the "C0302: Too many lines in module" warning which warns for modules
# with more 1000 lines, because all of the code here is logically connected
# and currently, we are above 1000 lines by a small margin.
# pylint: disable=C0302
# pylint: disable=too-many-lines

# We aim to support SPECIFICATION_VERSION and require the input metadata
# files to have the same major version (the first number) as ours.
Expand All @@ -66,7 +63,6 @@ class Metadata:
Attributes:
signed: A subclass of Signed, which has the actual metadata payload,
i.e. one of Targets, Snapshot, Timestamp or Root.
signatures: An ordered dictionary of keyids to Signature objects, each
signing the canonical serialized representation of 'signed'.
"""
Expand All @@ -93,8 +89,8 @@ def from_dict(cls, metadata: Dict[str, Any]) -> "Metadata":
Returns:
A TUF Metadata object.
"""

# Dispatch to contained metadata class on metadata _type field.
_type = metadata["signed"]["_type"]

Expand Down Expand Up @@ -149,8 +145,8 @@ def from_file(
Returns:
A TUF Metadata object.
"""

if storage_backend is None:
storage_backend = FilesystemBackend()

Expand Down Expand Up @@ -203,20 +199,18 @@ def to_file(
Arguments:
filename: The path to write the file to.
serializer: A MetadataSerializer subclass instance that implements
the desired wireline format serialization. Per default a
JSONSerializer is used.
storage_backend: An object that implements
securesystemslib.storage.StorageBackendInterface. Per default
a (local) FilesystemBackend is used.
serializer: A MetadataSerializer instance that implements the
desired serialization format. Default is JSONSerializer.
storage_backend: A StorageBackendInterface implementation. Default
is FilesystemBackend (i.e. a local file).
Raises:
tuf.api.serialization.SerializationError:
The metadata object cannot be serialized.
securesystemslib.exceptions.StorageError:
The file cannot be written.
"""

if serializer is None:
# Use local scope import to avoid circular import errors
# pylint: disable=import-outside-toplevel
Expand All @@ -238,14 +232,12 @@ def sign(
"""Creates signature over 'signed' and assigns it to 'signatures'.
Arguments:
signer: An object implementing the securesystemslib.signer.Signer
interface.
signer: A securesystemslib.signer.Signer implementation.
append: A boolean indicating if the signature should be appended to
the list of signatures or replace any existing signatures. The
default behavior is to replace signatures.
signed_serializer: A SignedSerializer subclass instance that
implements the desired canonicalization format. Per default a
CanonicalJSONSerializer is used.
signed_serializer: A SignedSerializer that implements the desired
serialization format. Default is CanonicalJSONSerializer.
Raises:
tuf.api.serialization.SerializationError:
Expand All @@ -256,8 +248,8 @@ def sign(
Returns:
A securesystemslib-style signature object.
"""

if signed_serializer is None:
# Use local scope import to avoid circular import errors
# pylint: disable=import-outside-toplevel
Expand Down Expand Up @@ -408,8 +400,9 @@ def bump_version(self) -> None:

class Key:
"""A container class representing the public portion of a Key.
Please note that "Key" instances are not semanticly validated during
initialization. We consider this as responsibility of securesystemslib.
initialization: this only happens at signature verification time.
Attributes:
keyid: An identifier string that must uniquely identify a key within
Expand All @@ -421,7 +414,6 @@ class Key:
"rsassa-pss-sha256", "ed25519", and "ecdsa-sha2-nistp256".
keyval: A dictionary containing the public portion of the key.
unrecognized_fields: Dictionary of all unrecognized fields.
"""

def __init__(
Expand Down Expand Up @@ -521,15 +513,15 @@ def verify_signature(


class Role:
"""A container class containing the set of keyids and threshold associated
with a particular role.
"""Container that defines which keys are required to sign roles metadata.
Role defines how many keys are required to successfully sign the roles
metadata, and which keys are accepted.
Attributes:
keyids: A set of strings each of which represents a given key.
threshold: An integer representing the required number of keys for that
particular role.
keyids: A set of strings representing signing keys for this role.
threshold: Number of keys required to sign this role's metadata.
unrecognized_fields: Dictionary of all unrecognized fields.
"""

def __init__(
Expand Down Expand Up @@ -573,29 +565,14 @@ class Root(Signed):
Attributes:
consistent_snapshot: An optional boolean indicating whether the
repository supports consistent snapshots.
keys: A dictionary that contains a public key store used to verify
top level roles metadata signatures::
{
'<KEYID>': <Key instance>,
...
},
roles: A dictionary that contains a list of signing keyids and
a signature threshold for each top level role::
{
'<ROLE>': <Role istance>,
...
}
keys: Dictionary of keyids to Keys. Defines the keys used in 'roles'.
roles: Dictionary of role names to Roles. Defines which keys are
required to sign the metadata for a specific role.
"""

_signed_type = "root"

# TODO: determine an appropriate value for max-args and fix places where
# we violate that. This __init__ function takes 7 arguments, whereas the
# default max-args value for pylint is 5
# TODO: determine an appropriate value for max-args
# pylint: disable=too-many-arguments
def __init__(
self,
Expand Down Expand Up @@ -739,18 +716,8 @@ class MetaFile(BaseFile):
Attributes:
version: An integer indicating the version of the metadata file.
length: An optional integer indicating the length of the metadata file.
hashes: An optional dictionary mapping hash algorithms to the
hashes resulting from applying them over the metadata file
contents.::
'hashes': {
'<HASH ALGO 1>': '<METADATA FILE HASH 1>',
'<HASH ALGO 2>': '<METADATA FILE HASH 2>',
...
}
hashes: An optional dictionary of hash algorithm names to hash values.
unrecognized_fields: Dictionary of all unrecognized fields.
"""

def __init__(
Expand Down Expand Up @@ -799,10 +766,11 @@ def to_dict(self) -> Dict[str, Any]:
return res_dict

def verify_length_and_hashes(self, data: Union[bytes, BinaryIO]):
"""Verifies that the length and hashes of "data" match expected
values.
"""Verifies that the length and hashes of "data" match expected values.
Args:
data: File object or its content in bytes.
Raises:
LengthOrHashMismatchError: Calculated length or hashes do not
match expected values or hash algorithm is not supported.
Expand All @@ -817,13 +785,11 @@ def verify_length_and_hashes(self, data: Union[bytes, BinaryIO]):
class Timestamp(Signed):
"""A container for the signed part of timestamp metadata.
Attributes:
meta: A dictionary that contains information about snapshot metadata::
{
'snapshot.json': <MetaFile INSTANCE>
}
Timestamp contains information about the snapshot Metadata file.
Attributes:
meta: A dictionary of filenames to MetaFiles. The only valid key value
is the snapshot filename, as defined by the specification.
"""

_signed_type = "timestamp"
Expand Down Expand Up @@ -865,15 +831,10 @@ def update(self, snapshot_meta: MetaFile) -> None:
class Snapshot(Signed):
"""A container for the signed part of snapshot metadata.
Attributes:
meta: A dictionary that contains information about targets metadata::
{
'targets.json': <MetaFile INSTANCE>,
'<DELEGATED TARGETS ROLE 1>.json': <MetaFile INSTANCE>,
'<DELEGATED TARGETS ROLE 2>.json': <MetaFile INSTANCE>,
}
Snapshot contains information about all target Metadata files.
Attributes:
meta: A dictionary of target metadata filenames to MetaFile objects.
"""

_signed_type = "snapshot"
Expand Down Expand Up @@ -918,22 +879,22 @@ def update(self, rolename: str, role_info: MetaFile) -> None:


class DelegatedRole(Role):
"""A container with information about particular delegated role.
"""A container with information about a delegated role.
A delegation can happen in three ways:
- paths is None and path_hash_prefixes is None: delegates all targets
- paths is set: delegates targets matching any path pattern in paths
- path_hash_prefixes is set: delegates targets whose target path hash
starts with any of the prefixes in path_hash_prefixes
paths and path_hash_prefixes are mutually exclusive: both cannot be set.
Attributes:
name: A string giving the name of the delegated role.
keyids: A set of strings each of which represents a given key.
threshold: An integer representing the required number of keys for that
particular role.
terminating: A boolean indicating whether subsequent delegations
should be considered.
paths: An optional list of strings, where each string describes
a path that the role is trusted to provide.
path_hash_prefixes: An optional list of HEX_DIGESTs used to succinctly
describe a set of target paths. Only one of the attributes "paths"
and "path_hash_prefixes" is allowed to be set.
should be considered during a target lookup.
paths: An optional list of path pattern strings. See note above.
path_hash_prefixes: An optional list of hash prefixes. See note above.
unrecognized_fields: Dictionary of all unrecognized fields.
"""

def __init__(
Expand Down Expand Up @@ -996,12 +957,11 @@ class Delegations:
"""A container object storing information about all delegations.
Attributes:
keys: A dictionary of keyids and key objects containing information
about the corresponding key.
roles: A list of DelegatedRole instances containing information about
all delegated roles.
keys: Dictionary of keyids to Keys. Defines the keys used in 'roles'.
roles: List of DelegatedRoles that define which keys are required to
sign the metadata for a specific role. The roles order also
defines the order that role delegations are considered in.
unrecognized_fields: Dictionary of all unrecognized fields.
"""

def __init__(
Expand Down Expand Up @@ -1045,17 +1005,8 @@ class TargetFile(BaseFile):
Attributes:
length: An integer indicating the length of the target file.
hashes: A dictionary mapping hash algorithms to the
hashes resulting from applying them over the metadata file
contents::
'hashes': {
'<HASH ALGO 1>': '<TARGET FILE HASH 1>',
'<HASH ALGO 2>': '<TARGET FILE HASH 2>',
...
}
hashes: A dictionary of hash algorithm names to hash values.
unrecognized_fields: Dictionary of all unrecognized fields.
"""

def __init__(
Expand Down Expand Up @@ -1096,10 +1047,11 @@ def to_dict(self) -> Dict[str, Any]:
}

def verify_length_and_hashes(self, data: Union[bytes, BinaryIO]):
"""Verifies that the length and hashes of "data" match expected
values.
"""Verifies that length and hashes of "data" match expected values.
Args:
data: File object or its content in bytes.
Raises:
LengthOrHashMismatchError: Calculated length or hashes do not
match expected values or hash algorithm is not supported.
Expand All @@ -1111,25 +1063,18 @@ def verify_length_and_hashes(self, data: Union[bytes, BinaryIO]):
class Targets(Signed):
"""A container for the signed part of targets metadata.
Attributes:
targets: A dictionary that contains information about target files::
{
'<TARGET FILE NAME>': <TargetFile INSTANCE>,
...
}
delegations: An optional object containing a list of delegated target
roles and public key store used to verify their metadata
signatures.
Targets contains verifying information about target files and also
delegates responsibility to other Targets roles.
Attributes:
targets: A dictionary of target filenames to TargetFiles
delegations: An optional Delegations that defines how this Targets
further delegates responsibility to other Targets Metadata files.
"""

_signed_type = "targets"

# TODO: determine an appropriate value for max-args and fix places where
# we violate that. This __init__ function takes 7 arguments, whereas the
# default max-args value for pylint is 5
# TODO: determine an appropriate value for max-args
# pylint: disable=too-many-arguments
def __init__(
self,
Expand Down

0 comments on commit f458e92

Please sign in to comment.