Skip to content

Commit

Permalink
Metadata API: Use OrderedDict for signatures
Browse files Browse the repository at this point in the history
Dict ordering is part of regular Dict from Python 3.7: Use OrderedDict
for signatures to make sure signatures are serialized in a reproducible
order even on 3.6.

The added benefit is that reader will immediately understand that the
order has some significance.

The actual type annotations are a bit convoluted because:
* typing does not include OrderedDict before 3.7 so can't use that
* Annotating inner types does not work for collections.OrderedDict
  in older pythons (so have to use the "stringified annotations")

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
  • Loading branch information
Jussi Kukkonen committed Jun 9, 2021
1 parent e3190fc commit 1ce36d0
Showing 1 changed file with 8 additions and 5 deletions.
13 changes: 8 additions & 5 deletions tuf/api/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"""
import abc
import tempfile
from collections import OrderedDict
from datetime import datetime, timedelta
from typing import Any, ClassVar, Dict, List, Mapping, Optional, Tuple, Type

Expand Down Expand Up @@ -48,11 +49,13 @@ class Metadata:
signed: A subclass of Signed, which has the actual metadata payload,
i.e. one of Targets, Snapshot, Timestamp or Root.
signatures: A dict of keyids to Securesystemslib Signature objects,
each signing the canonical serialized representation of 'signed'.
signatures: An ordered dictionary of keyids to Signature objects, each
signing the canonical serialized representation of 'signed'.
"""

def __init__(self, signed: "Signed", signatures: Dict[str, Signature]):
def __init__(
self, signed: "Signed", signatures: "OrderedDict[str, Signature]"
):
self.signed = signed
self.signatures = signatures

Expand Down Expand Up @@ -89,7 +92,7 @@ def from_dict(cls, metadata: Dict[str, Any]) -> "Metadata":
raise ValueError(f'unrecognized metadata type "{_type}"')

# Make sure signatures are unique
signatures: Dict[str, Signature] = {}
signatures: "OrderedDict[str, Signature]" = OrderedDict()
for sig_dict in metadata.pop("signatures"):
sig = Signature.from_dict(sig_dict)
if sig.keyid in signatures:
Expand Down Expand Up @@ -249,7 +252,7 @@ def sign(
if append:
self.signatures[signature.keyid] = signature
else:
self.signatures = {signature.keyid: signature}
self.signatures = OrderedDict({signature.keyid: signature})

return signature

Expand Down

0 comments on commit 1ce36d0

Please sign in to comment.