After the implementation of a Key class representing
the public portion of a key, the method add_key() should
take an argument of type Key, instead of a dictionary.
Test cases are updated accordingly.
Signed-off-by: Teodora Sechkova <tsechkova@vmware.com>
Stop using Mapping where we actually mean Dict:
Mapping means "we only need a read-only dict" and most of the time
this is not really the case.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
In the top level metadata classes, there are complex attributes such as
"meta" in Targets and Snapshot, "key" and "roles" in Root etc.
We want to represent those complex attributes with a class to allow
easier verification and support for metadata with unrecognized fields.
For more context read ADR 0004 and ADR 0008 in the docs/adr folder.
DelegatedRole shares a couple of fields with the Role class and that's
why it inherits it.
I decided to use a separate Delegations class because I thought it will
make it easier to read, verify and add additional helper functions.
Also, I tried to make sure that I test each level of the delegations
representation for support of storing unrecognized fields.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
This is suggested by the Google style guide: the old style logging
(%-format) allows the log strings to be lazily formatted so there's less
need to think about performance when forming debug messages.
No actual code changes are needed because the metadata API does not yet
log anything.
Fixes#1334
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
* Define missing argument type hints
* Stop using Mapping where we actually mean Dict:
Mapping means "we only need a read-only dict" and most of the
time this is not really the case.
* Use List, not list (latter only works from Python 3.9)
* Update Metadata.signatures documentation
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
We should not do multiple lookups through data structures if one is
enough (here we have extra lookups on both roles and keyids).
Also in this case raising on missing key seems like the preferable
alternative so even a try-except is not needed.
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
As per the specification (v1.0.1) length and hashes fields
in timestamp and snapshot metadata are optional.
We have implement this in the older API
(see https://github.com/theupdateframework/tuf/pull/1031) and we should
implement it in the new API.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
Using Metadata APIs '_type' attribute (from outside metadata.py) currently
results in linter errors.
Add a duplicate 'type': this way the API users can avoid linter errors
but '_type' is still available in case the strict file format
compatibility is needed.
Fixes#1375
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Also remove _type from Signed constructor arguments: the value is in a
class atttribute. This way _type never needs to be validated (except
in the dispatcher in Metadata). There is a double-check in
_common_fields_from_dict() just to be sure.
This makes the API easier to use correctly as the public property is
immutable.
This is an API break as all Signed constructors change -- this could be
avoided but seems like the correct choice.
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Verify that adding an already existing key to keyid for a particular
role in Root won't create duplicate key.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
From the specification:
"Clients MUST ensure that for any KEYID represented in this key list
and in other files, only one unique key has that KEYID."
The “only one unique key has that KEYID” is a requirement which can’t
be achieved if two keyids are the same.
So, in order to mandate that requirement it makes sense to use a set
which will guarantee us the keyid’s uniqueness.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
In the top level metadata classes, there are complex attributes such as
"meta" in Targets and Snapshot, "key" and "roles" in Root etc.
We want to represent those complex attributes with a class to allow
easier verification and support for metadata with unrecognized fields.
For more context read ADR 0004 and ADR 0008 in the docs/adr folder.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
In the top level metadata classes, there are complex attributes such as
"meta" in Targets and Snapshot, "key" and "roles" in Root etc.
We want to represent those complex attributes with a class to allow
easier verification and support for metadata with unrecognized fields.
For more context read ADR 0004 and ADR 0008 in the docs/adr folder.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
Black was updated from 20.8b1 to 21.4b0 requiring that one-line
docstring don't add additional space before the closing quotes.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
In order to support ADR 0008 we would want to accept unrecognized
fields in all metadata classes.
Input that contains unknown fields in the 'signed' dictionary should
successfully deserialize into a Metadata object, and that object should
successfully serialize with the unknown fields intact.
Also, we should test that we support unrecognized fields when adding
new classes or modifying existing ones to make sure we support
ADR 0008.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
This is essentially short-hand for
JSONDeserializer().deserialize(data)
but seems much easier for the API user so may be worth it.
Metadata.from_file() now uses Metadata.from_bytes() internally.
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Checks metadata expiration against a reference time (a naive datetime in UTC).
If not provided, checks against the current UTC date and time.
Returns True if expiration time is less than the reference time.
Signed-off-by: Velichka Atanasova <avelichka@vmware.com>
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Black standardizes single to double quotes where feasible.
However, it doesn't seem to change double to single quotes nor adds
escape characters, as a consequence it skips standardization on
strings with mixed quotes.
Unfortunately, pylint's quote consistency check also doesn't detect
this, so the onus will remain on the reviewer in these cases.
**Unrelated changes**:
The commit still enables pylint's "check-quote-consistency" just in
case it can detect something the black doesn't.
The commit also fixes a syntax inconsistency in pylintrc.
Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
The updated pylintrc is based on the Google Python Style Guide
pylint configuration at
https://google.github.io/styleguide/pylintrc with the following
differences:
- We don't list defaults which are applied anyway.
- We don't configure checks that seem unrelated to the code style
guide.
- We don't disable any checks that are not in conflict with the
current code or code style guide.
This has the advantage of a minimal configuration file which should
be easy to maintain and extend as required, e.g. if conflicting
code is added, or linting time becomes too long, due to unnecessary
checks.
Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
In the securesystemslib pr https://github.com/secure-systems-lab/securesystemslib/pull/319
I added a new Signer interface with the purpose of supporting multiple
signing implementations.
Additionally, I added the SSlibSigner implementation of that interface
which implements the signing operation for rsa, ed25519 and ecdsa
schemes.
With this commit, I integrate the SSlibSigner into the new API in tuf.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
Call an instance method and a static method that are only defined
in a parent class from child instances using self (instance) and
cls (static) instead of super().
While this doesn't make a practical difference, the new syntax is
probably less confusing to the reader.
Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
- Make class docstrings wording consistent.
- Emphasize that we use the OLPC Canonical JSON specification.
Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
tuf.api is not designed for Python 2 compatibility. This commit
removes the following stray compatibility constructs in its
serialization subpackage:
- '__metaclass__ = abc.ABCMeta'
- six.raise_from
Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
Prior to this commit the (abstract) 'Signed' base class implemented
from/to_dict methods, to be used by any subclass in addition to
or instead of a custom from/to_dict method. The design led to some
confusion, especially in 'Signed.from_dict' factories, which
instantiated subclass objects when called on a subclass, which
didn't implement its own 'from_dict' method.
This commit demystifies the design, by implementing from/to_dict
on all 'Signed' subclasses, and moving common from/to_dict tasks
to helper functions in the 'Signed' class.
The newly gained clarity and explicitness comes at the cost of
slightly more lines of code.
Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
Clarify that the TUF metadata class model is not bound to a JSON
wireline format by:
- re-wording module, class and method docstrings and code comments
to add details about custom and default serialization and the
purpose of from/to_dict methods, and
- removing the 'JsonDict' type annotation -- instead we use
generic Mapping[str, Any] for method arguments and strict
Dict[str, Any] as return value as suggested in
https://docs.python.org/3/library/typing.html#typing.Dict
Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
- Rename _dict to json_dict to avoid wrong semantics of leading
underscore. (leading underscore was initially chosen to avoid name
shadowing)
- Rename 'serializer' argument of type 'SignedSerializer' to
'signed_serializer', to distinguish from 'serializer' argument of
type 'MetadataSerializer'.
Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
Revert an earlier commit that moved to/from_dict metadata class
model methods to a util module of the serialization sub-package.
We keep to/from_dict methods on the metadata classes because:
- It seems **idiomatic** (see e.g. 3rd-party libaries such as attrs,
pydantic, marshmallow, or built-ins that provide default or
customizable dict representation for higher-level objects).
The idiomatic choice should make usage more intuitive.
- It feels better **structured** when each method is encapsulated
within the corresponding class, which in turn should make
maintaining/modifying/extending the class model easier.
- It allows us to remove function-scope imports (see subsequent
commit).
Caveat:
Now that "the meat" of the sub-packaged JSON serializer is
implemented on the class, it might make it harder to create a
non-dict based serializer by copy-paste-amending the JSON
serializer.
However, the benefits from above seem to outweigh the disadvantage.
See option 5 of ADR0006 for further details (#1270).
Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>