Skip to content

Commit f458e92

Browse files
author
Jussi Kukkonen
authored
Merge pull request #1456 from jku/tighten-comments
Metadata API: Rewrite comments
2 parents 7108ea2 + 79f4f41 commit f458e92

File tree

1 file changed

+61
-116
lines changed

1 file changed

+61
-116
lines changed

tuf/api/metadata.py

+61-116
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,7 @@
4747
SignedSerializer,
4848
)
4949

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

5552
# We aim to support SPECIFICATION_VERSION and require the input metadata
5653
# files to have the same major version (the first number) as ours.
@@ -66,7 +63,6 @@ class Metadata:
6663
Attributes:
6764
signed: A subclass of Signed, which has the actual metadata payload,
6865
i.e. one of Targets, Snapshot, Timestamp or Root.
69-
7066
signatures: An ordered dictionary of keyids to Signature objects, each
7167
signing the canonical serialized representation of 'signed'.
7268
"""
@@ -93,8 +89,8 @@ def from_dict(cls, metadata: Dict[str, Any]) -> "Metadata":
9389
9490
Returns:
9591
A TUF Metadata object.
96-
9792
"""
93+
9894
# Dispatch to contained metadata class on metadata _type field.
9995
_type = metadata["signed"]["_type"]
10096

@@ -149,8 +145,8 @@ def from_file(
149145
150146
Returns:
151147
A TUF Metadata object.
152-
153148
"""
149+
154150
if storage_backend is None:
155151
storage_backend = FilesystemBackend()
156152

@@ -203,20 +199,18 @@ def to_file(
203199
204200
Arguments:
205201
filename: The path to write the file to.
206-
serializer: A MetadataSerializer subclass instance that implements
207-
the desired wireline format serialization. Per default a
208-
JSONSerializer is used.
209-
storage_backend: An object that implements
210-
securesystemslib.storage.StorageBackendInterface. Per default
211-
a (local) FilesystemBackend is used.
202+
serializer: A MetadataSerializer instance that implements the
203+
desired serialization format. Default is JSONSerializer.
204+
storage_backend: A StorageBackendInterface implementation. Default
205+
is FilesystemBackend (i.e. a local file).
212206
213207
Raises:
214208
tuf.api.serialization.SerializationError:
215209
The metadata object cannot be serialized.
216210
securesystemslib.exceptions.StorageError:
217211
The file cannot be written.
218-
219212
"""
213+
220214
if serializer is None:
221215
# Use local scope import to avoid circular import errors
222216
# pylint: disable=import-outside-toplevel
@@ -238,14 +232,12 @@ def sign(
238232
"""Creates signature over 'signed' and assigns it to 'signatures'.
239233
240234
Arguments:
241-
signer: An object implementing the securesystemslib.signer.Signer
242-
interface.
235+
signer: A securesystemslib.signer.Signer implementation.
243236
append: A boolean indicating if the signature should be appended to
244237
the list of signatures or replace any existing signatures. The
245238
default behavior is to replace signatures.
246-
signed_serializer: A SignedSerializer subclass instance that
247-
implements the desired canonicalization format. Per default a
248-
CanonicalJSONSerializer is used.
239+
signed_serializer: A SignedSerializer that implements the desired
240+
serialization format. Default is CanonicalJSONSerializer.
249241
250242
Raises:
251243
tuf.api.serialization.SerializationError:
@@ -256,8 +248,8 @@ def sign(
256248
257249
Returns:
258250
A securesystemslib-style signature object.
259-
260251
"""
252+
261253
if signed_serializer is None:
262254
# Use local scope import to avoid circular import errors
263255
# pylint: disable=import-outside-toplevel
@@ -408,8 +400,9 @@ def bump_version(self) -> None:
408400

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

427419
def __init__(
@@ -521,15 +513,15 @@ def verify_signature(
521513

522514

523515
class Role:
524-
"""A container class containing the set of keyids and threshold associated
525-
with a particular role.
516+
"""Container that defines which keys are required to sign roles metadata.
517+
518+
Role defines how many keys are required to successfully sign the roles
519+
metadata, and which keys are accepted.
526520
527521
Attributes:
528-
keyids: A set of strings each of which represents a given key.
529-
threshold: An integer representing the required number of keys for that
530-
particular role.
522+
keyids: A set of strings representing signing keys for this role.
523+
threshold: Number of keys required to sign this role's metadata.
531524
unrecognized_fields: Dictionary of all unrecognized fields.
532-
533525
"""
534526

535527
def __init__(
@@ -573,29 +565,14 @@ class Root(Signed):
573565
Attributes:
574566
consistent_snapshot: An optional boolean indicating whether the
575567
repository supports consistent snapshots.
576-
keys: A dictionary that contains a public key store used to verify
577-
top level roles metadata signatures::
578-
579-
{
580-
'<KEYID>': <Key instance>,
581-
...
582-
},
583-
584-
roles: A dictionary that contains a list of signing keyids and
585-
a signature threshold for each top level role::
586-
587-
{
588-
'<ROLE>': <Role istance>,
589-
...
590-
}
591-
568+
keys: Dictionary of keyids to Keys. Defines the keys used in 'roles'.
569+
roles: Dictionary of role names to Roles. Defines which keys are
570+
required to sign the metadata for a specific role.
592571
"""
593572

594573
_signed_type = "root"
595574

596-
# TODO: determine an appropriate value for max-args and fix places where
597-
# we violate that. This __init__ function takes 7 arguments, whereas the
598-
# default max-args value for pylint is 5
575+
# TODO: determine an appropriate value for max-args
599576
# pylint: disable=too-many-arguments
600577
def __init__(
601578
self,
@@ -739,18 +716,8 @@ class MetaFile(BaseFile):
739716
Attributes:
740717
version: An integer indicating the version of the metadata file.
741718
length: An optional integer indicating the length of the metadata file.
742-
hashes: An optional dictionary mapping hash algorithms to the
743-
hashes resulting from applying them over the metadata file
744-
contents.::
745-
746-
'hashes': {
747-
'<HASH ALGO 1>': '<METADATA FILE HASH 1>',
748-
'<HASH ALGO 2>': '<METADATA FILE HASH 2>',
749-
...
750-
}
751-
719+
hashes: An optional dictionary of hash algorithm names to hash values.
752720
unrecognized_fields: Dictionary of all unrecognized fields.
753-
754721
"""
755722

756723
def __init__(
@@ -799,10 +766,11 @@ def to_dict(self) -> Dict[str, Any]:
799766
return res_dict
800767

801768
def verify_length_and_hashes(self, data: Union[bytes, BinaryIO]):
802-
"""Verifies that the length and hashes of "data" match expected
803-
values.
769+
"""Verifies that the length and hashes of "data" match expected values.
770+
804771
Args:
805772
data: File object or its content in bytes.
773+
806774
Raises:
807775
LengthOrHashMismatchError: Calculated length or hashes do not
808776
match expected values or hash algorithm is not supported.
@@ -817,13 +785,11 @@ def verify_length_and_hashes(self, data: Union[bytes, BinaryIO]):
817785
class Timestamp(Signed):
818786
"""A container for the signed part of timestamp metadata.
819787
820-
Attributes:
821-
meta: A dictionary that contains information about snapshot metadata::
822-
823-
{
824-
'snapshot.json': <MetaFile INSTANCE>
825-
}
788+
Timestamp contains information about the snapshot Metadata file.
826789
790+
Attributes:
791+
meta: A dictionary of filenames to MetaFiles. The only valid key value
792+
is the snapshot filename, as defined by the specification.
827793
"""
828794

829795
_signed_type = "timestamp"
@@ -865,15 +831,10 @@ def update(self, snapshot_meta: MetaFile) -> None:
865831
class Snapshot(Signed):
866832
"""A container for the signed part of snapshot metadata.
867833
868-
Attributes:
869-
meta: A dictionary that contains information about targets metadata::
870-
871-
{
872-
'targets.json': <MetaFile INSTANCE>,
873-
'<DELEGATED TARGETS ROLE 1>.json': <MetaFile INSTANCE>,
874-
'<DELEGATED TARGETS ROLE 2>.json': <MetaFile INSTANCE>,
875-
}
834+
Snapshot contains information about all target Metadata files.
876835
836+
Attributes:
837+
meta: A dictionary of target metadata filenames to MetaFile objects.
877838
"""
878839

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

919880

920881
class DelegatedRole(Role):
921-
"""A container with information about particular delegated role.
882+
"""A container with information about a delegated role.
883+
884+
A delegation can happen in three ways:
885+
- paths is None and path_hash_prefixes is None: delegates all targets
886+
- paths is set: delegates targets matching any path pattern in paths
887+
- path_hash_prefixes is set: delegates targets whose target path hash
888+
starts with any of the prefixes in path_hash_prefixes
889+
paths and path_hash_prefixes are mutually exclusive: both cannot be set.
922890
923891
Attributes:
924892
name: A string giving the name of the delegated role.
925-
keyids: A set of strings each of which represents a given key.
926-
threshold: An integer representing the required number of keys for that
927-
particular role.
928893
terminating: A boolean indicating whether subsequent delegations
929-
should be considered.
930-
paths: An optional list of strings, where each string describes
931-
a path that the role is trusted to provide.
932-
path_hash_prefixes: An optional list of HEX_DIGESTs used to succinctly
933-
describe a set of target paths. Only one of the attributes "paths"
934-
and "path_hash_prefixes" is allowed to be set.
894+
should be considered during a target lookup.
895+
paths: An optional list of path pattern strings. See note above.
896+
path_hash_prefixes: An optional list of hash prefixes. See note above.
935897
unrecognized_fields: Dictionary of all unrecognized fields.
936-
937898
"""
938899

939900
def __init__(
@@ -996,12 +957,11 @@ class Delegations:
996957
"""A container object storing information about all delegations.
997958
998959
Attributes:
999-
keys: A dictionary of keyids and key objects containing information
1000-
about the corresponding key.
1001-
roles: A list of DelegatedRole instances containing information about
1002-
all delegated roles.
960+
keys: Dictionary of keyids to Keys. Defines the keys used in 'roles'.
961+
roles: List of DelegatedRoles that define which keys are required to
962+
sign the metadata for a specific role. The roles order also
963+
defines the order that role delegations are considered in.
1003964
unrecognized_fields: Dictionary of all unrecognized fields.
1004-
1005965
"""
1006966

1007967
def __init__(
@@ -1045,17 +1005,8 @@ class TargetFile(BaseFile):
10451005
10461006
Attributes:
10471007
length: An integer indicating the length of the target file.
1048-
hashes: A dictionary mapping hash algorithms to the
1049-
hashes resulting from applying them over the metadata file
1050-
contents::
1051-
1052-
'hashes': {
1053-
'<HASH ALGO 1>': '<TARGET FILE HASH 1>',
1054-
'<HASH ALGO 2>': '<TARGET FILE HASH 2>',
1055-
...
1056-
}
1008+
hashes: A dictionary of hash algorithm names to hash values.
10571009
unrecognized_fields: Dictionary of all unrecognized fields.
1058-
10591010
"""
10601011

10611012
def __init__(
@@ -1096,10 +1047,11 @@ def to_dict(self) -> Dict[str, Any]:
10961047
}
10971048

10981049
def verify_length_and_hashes(self, data: Union[bytes, BinaryIO]):
1099-
"""Verifies that the length and hashes of "data" match expected
1100-
values.
1050+
"""Verifies that length and hashes of "data" match expected values.
1051+
11011052
Args:
11021053
data: File object or its content in bytes.
1054+
11031055
Raises:
11041056
LengthOrHashMismatchError: Calculated length or hashes do not
11051057
match expected values or hash algorithm is not supported.
@@ -1111,25 +1063,18 @@ def verify_length_and_hashes(self, data: Union[bytes, BinaryIO]):
11111063
class Targets(Signed):
11121064
"""A container for the signed part of targets metadata.
11131065
1114-
Attributes:
1115-
targets: A dictionary that contains information about target files::
1116-
1117-
{
1118-
'<TARGET FILE NAME>': <TargetFile INSTANCE>,
1119-
...
1120-
}
1121-
1122-
delegations: An optional object containing a list of delegated target
1123-
roles and public key store used to verify their metadata
1124-
signatures.
1066+
Targets contains verifying information about target files and also
1067+
delegates responsibility to other Targets roles.
11251068
1069+
Attributes:
1070+
targets: A dictionary of target filenames to TargetFiles
1071+
delegations: An optional Delegations that defines how this Targets
1072+
further delegates responsibility to other Targets Metadata files.
11261073
"""
11271074

11281075
_signed_type = "targets"
11291076

1130-
# TODO: determine an appropriate value for max-args and fix places where
1131-
# we violate that. This __init__ function takes 7 arguments, whereas the
1132-
# default max-args value for pylint is 5
1077+
# TODO: determine an appropriate value for max-args
11331078
# pylint: disable=too-many-arguments
11341079
def __init__(
11351080
self,

0 commit comments

Comments
 (0)