The default value "targets" makes sense because now the top-level
metadata can be accessed in a standard way:
root(), timestamp(), snapshot() and targets()
and likewise for the edit_X() functions
Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
These are equivalent to the edit_X() context managers but for cases
where user is not interested in creating a new version of the metadata.
Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
New names:
do_snapshot()
do_timestamp()
This is in preparation of using the old names for another purpose.
Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
The advantage here is that code within the context can take advantage
of the correct typing. This is already visible in the example code but
is even more useful in real applications.
Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
uploader API has two POST endpoints
/api/delegation/<ROLE>
Accepts new delegation keys for targetpath "<ROLE>/*" to role <ROLE>.
This data is not signed in any way: In a real service this action would
require some external authentication.
POST content:
{ <KEYID>: <TUF KEY> }
/api/role/<ROLE>
accepts uploads of new versions of <ROLE> metadata. The metadata
must be correctly signed by the keys assigned to this delegation.
POST content:
TUF targets metadata as json
Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
This tool works with the example repository: it can be used to
* Add a delegation (this is an unsafe API corresponding to e.g.
project creation in PyPI)
* Submit new delegated role version (this requires using signing keys
already submitted with the delegation)
Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
New Securesystemslib Keys can now be instantiated in two ways:
* deserialize via Key.from_dict() as before
* generate new keys via implementation specific methods
Fix all cases where we call Key() or Key.from_securesystemslib_key()
and use SSlibKey methods instead. Fix related tests.
Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
This is only needed for threshold signing and not even used in the
example: leave it to the implementations to handle for now.
Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
This no longer seems needed: if the metadata store does not contain
a single version of role, then open() can assume it is initializing.
Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
This is a collection of comment, documentation and logging fixes.
The noteworthy part is making it clear that repository is not stable
API yet: I think this is a good idea.
Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
This is not required for the demo but is more realistic: we keep
a cache of targets versions so that we can produce a new snapshot
whenever one is needed, without accessing all of the targets metadata
to do so.
Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
This does not make the examples simpler now, but it will when
there are multiple locations where snapshot/timestamp are called.
* This way the snapshot/timestamp input material is an internal detail
of Repository and the call sites will be simpler.
* Both methods now have a "force" argument that can be used to create a
new version regardless of meta info changes
* but implementations are now required to implement snapshot_info
and targets_infos properties that represent the current snapshot and
targets versions in the repository
Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
* Support any repository (that serves /targets/ and /metadata/)
with --url
* Support multiple repositories by aking the local cache
repository-specific
* Add "tofu" command to initialize with Trust-On-First-Use
* Update README so it uses the new repository application example
Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
This uses the repository module to create an app that
* generates everything from scratch
* serves metadata and targets from memory
* simulates a live repository by adding new targets every few seconds
Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
Generate keys for all roles in one place and rename to
better distinguish delegating targets key from bins key.
Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
If we have a goal of making metadata that can just be served to clients,
then these (and the parent metadata) should have versioned filenames.
Change the file names of the delegated files in the
hashed_bin_delegation.py to versioned.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
Add a basic example script showing all features of the succinct hash bin
delegations and the available API calls of SuccinctRoles.
The explanations are used to promote the usage of succinct hash bin
delegations by explaining it well enough so our users can understand
the API limitations and how to use them and at the same time I tried not
going into too many details of the SuccinctRoles math as its
implementation is inside tuf/api/metadata.py and there there are
explanations about that.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
We no longer need or use SPEC_VERSION variable defined in the
begging of the script.
Additionally, I decided to add a small addition to the "roles"
type annotation as that gives better context to the syntax highlighter
of VS code.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
Here is the list of all breaking API changes:
1) The "role" and "key" arguments in "Root.add_key()" are in reverse
order - "key" becomes first and "role" second.
2) "Root.remove_key()" has been renamed to "Root.revoke_key()".
3) The "role" and "keyid" arguments in "Root.revoke_key()" are in
reverse order - "keyid" becomes first and "role" second.
4) The "role" and "key" arguments in "Targets.add_key()" are in reverse
order - "key" becomes first and "role" second.
5) "Targets.remove_key()" has been renamed to "Targets.revoke_key()".
6) The "role" and "keyid" arguments in "Targets.revoke_key()" are in
reverse order - "keyid" becomes first and "role" second.
7) In both methods "Targets.add_key()" and "Targets.revoke_key()" the
"role" argument becomes an optional with a default value of None.
Those changes are made in an effort to make those methods logical
for both cases when standard roles and succinct_roles are used.
The "Root" API change was done in order to preserve naming and argument
order consistency with "Targets" API.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
This commit contains 2 API changes in "Delegations" class from
tuf/api/metadata.py:
1. roles argment is made optional
2. unrecognized_fields argument becomes the 4-th rather than the 3-rd
as it used to be
In this commit, I add support for succinct_roles roles inside
Delegations class. This change is related to TAP 15 proposal.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
Fetcher interface should only raise DownloadErrors,
regardless of the implementation.
* Make sure fetch() wraps non-DownloadError errors in a DownloadError
* Make the abstract function private _fetch()
* Try to be more consistent in doscstrings
This now makes the example client more sensible (when server does not
respond):
$ ./client_example.py download qwerty
...
Failed to download target qwerty: Failed to download url http://127.0.0.1:8000/metadata/2.root.json
(here the latter part of the error string comes from DownloadError
raised by FetcherInterface.fetch())
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
Rephrase deprecation info in repo_example modules doc headers
to reflect that the deprecation has happened.
Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
After we drop support for python3.6 we can relly that dictionaries
preserve the insertion order:
https://docs.python.org/3.7/whatsnew/3.7.html
This means we can replace the usage of OrderedDict with a standard
dictionaries.
Something we have to keep in mind is that even thought the insertion
order is preserved the equality comparison for normal dicts is
insensitive for normal dicts compared to OrderedDict
For example:
>>> OrderedDict([(1,1), (2,2)]) == OrderedDict([(2,2), (1,1)])
False
>>> dict([(1,1), (2,2)]) == dict([(2,2), (1,1)])
True
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
Add tuf/api/exceptions.py for exceptions in the new code.
I copied the exceptions from tuf/exceptions.py with a few important
decisions:
1. I only added the exceptions that are used in the new code
2. I removed the general "Error" class as we can directly inherit
Exceptions
3. I tried grouping the exceptions by relevance
4. I removed the second argument "UnsignedMetadataError" as it's only
kept for backward compatibility and is not used
5. I tried following the new code style guidelines and linted the file
with our linters.
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>