15
15
available in the class model.
16
16
17
17
"""
18
+ import abc
18
19
import tempfile
19
20
from datetime import datetime , timedelta
20
- from typing import Any , Dict , List , Mapping , Optional
21
+ from typing import Any , ClassVar , Dict , List , Mapping , Optional , Tuple , Type
21
22
22
23
from securesystemslib .keys import verify_signature
23
24
from securesystemslib .signer import Signature , Signer
@@ -78,7 +79,7 @@ def from_dict(cls, metadata: Dict[str, Any]) -> "Metadata":
78
79
_type = metadata ["signed" ]["_type" ]
79
80
80
81
if _type == "targets" :
81
- inner_cls = Targets
82
+ inner_cls : Type [ Signed ] = Targets
82
83
elif _type == "snapshot" :
83
84
inner_cls = Snapshot
84
85
elif _type == "timestamp" :
@@ -304,7 +305,7 @@ def verify(
304
305
)
305
306
306
307
307
- class Signed :
308
+ class Signed ( metaclass = abc . ABCMeta ) :
308
309
"""A base class for the signed part of TUF metadata.
309
310
310
311
Objects with base class Signed are usually included in a Metadata object
@@ -321,7 +322,7 @@ class Signed:
321
322
"""
322
323
323
324
# Signed implementations are expected to override this
324
- _signed_type = None
325
+ _signed_type : ClassVar [ str ] = "signed"
325
326
326
327
# _type and type are identical: 1st replicates file format, 2nd passes lint
327
328
@property
@@ -351,8 +352,21 @@ def __init__(
351
352
self .version = version
352
353
self .unrecognized_fields : Mapping [str , Any ] = unrecognized_fields or {}
353
354
355
+ @abc .abstractmethod
356
+ def to_dict (self ) -> Dict [str , Any ]:
357
+ """Serialization helper that returns dict representation of self"""
358
+ raise NotImplementedError
359
+
360
+ @classmethod
361
+ @abc .abstractmethod
362
+ def from_dict (cls , signed_dict : Dict [str , Any ]) -> "Signed" :
363
+ """Deserialization helper, creates object from dict representation"""
364
+ raise NotImplementedError
365
+
354
366
@classmethod
355
- def _common_fields_from_dict (cls , signed_dict : Dict [str , Any ]) -> List [Any ]:
367
+ def _common_fields_from_dict (
368
+ cls , signed_dict : Dict [str , Any ]
369
+ ) -> Tuple [int , str , datetime ]:
356
370
"""Returns common fields of 'Signed' instances from the passed dict
357
371
representation, and returns an ordered list to be passed as leading
358
372
positional arguments to a subclass constructor.
@@ -371,7 +385,7 @@ def _common_fields_from_dict(cls, signed_dict: Dict[str, Any]) -> List[Any]:
371
385
# what the constructor expects and what we store. The inverse operation
372
386
# is implemented in '_common_fields_to_dict'.
373
387
expires = formats .expiry_string_to_datetime (expires_str )
374
- return [ version , spec_version , expires ]
388
+ return version , spec_version , expires
375
389
376
390
def _common_fields_to_dict (self ) -> Dict [str , Any ]:
377
391
"""Returns dict representation of common fields of 'Signed' instances.
@@ -550,20 +564,20 @@ def __init__(
550
564
self .roles = roles
551
565
552
566
@classmethod
553
- def from_dict (cls , root_dict : Dict [str , Any ]) -> "Root" :
567
+ def from_dict (cls , signed_dict : Dict [str , Any ]) -> "Root" :
554
568
"""Creates Root object from its dict representation."""
555
- common_args = cls ._common_fields_from_dict (root_dict )
556
- consistent_snapshot = root_dict .pop ("consistent_snapshot" , None )
557
- keys = root_dict .pop ("keys" )
558
- roles = root_dict .pop ("roles" )
569
+ common_args = cls ._common_fields_from_dict (signed_dict )
570
+ consistent_snapshot = signed_dict .pop ("consistent_snapshot" , None )
571
+ keys = signed_dict .pop ("keys" )
572
+ roles = signed_dict .pop ("roles" )
559
573
560
574
for keyid , key_dict in keys .items ():
561
575
keys [keyid ] = Key .from_dict (key_dict )
562
576
for role_name , role_dict in roles .items ():
563
577
roles [role_name ] = Role .from_dict (role_dict )
564
578
565
- # All fields left in the root_dict are unrecognized.
566
- return cls (* common_args , keys , roles , consistent_snapshot , root_dict )
579
+ # All fields left in the signed_dict are unrecognized.
580
+ return cls (* common_args , keys , roles , consistent_snapshot , signed_dict )
567
581
568
582
def to_dict (self ) -> Dict [str , Any ]:
569
583
"""Returns the dict representation of self."""
@@ -646,7 +660,10 @@ def from_dict(cls, meta_dict: Dict[str, Any]) -> "MetaFile":
646
660
647
661
def to_dict (self ) -> Dict [str , Any ]:
648
662
"""Returns the dictionary representation of self."""
649
- res_dict = {"version" : self .version , ** self .unrecognized_fields }
663
+ res_dict : Dict [str , Any ] = {
664
+ "version" : self .version ,
665
+ ** self .unrecognized_fields ,
666
+ }
650
667
651
668
if self .length is not None :
652
669
res_dict ["length" ] = self .length
@@ -683,13 +700,13 @@ def __init__(
683
700
self .meta = meta
684
701
685
702
@classmethod
686
- def from_dict (cls , timestamp_dict : Dict [str , Any ]) -> "Timestamp" :
703
+ def from_dict (cls , signed_dict : Dict [str , Any ]) -> "Timestamp" :
687
704
"""Creates Timestamp object from its dict representation."""
688
- common_args = cls ._common_fields_from_dict (timestamp_dict )
689
- meta_dict = timestamp_dict .pop ("meta" )
705
+ common_args = cls ._common_fields_from_dict (signed_dict )
706
+ meta_dict = signed_dict .pop ("meta" )
690
707
meta = {"snapshot.json" : MetaFile .from_dict (meta_dict ["snapshot.json" ])}
691
708
# All fields left in the timestamp_dict are unrecognized.
692
- return cls (* common_args , meta , timestamp_dict )
709
+ return cls (* common_args , meta , signed_dict )
693
710
694
711
def to_dict (self ) -> Dict [str , Any ]:
695
712
"""Returns the dict representation of self."""
@@ -733,15 +750,15 @@ def __init__(
733
750
self .meta = meta
734
751
735
752
@classmethod
736
- def from_dict (cls , snapshot_dict : Dict [str , Any ]) -> "Snapshot" :
753
+ def from_dict (cls , signed_dict : Dict [str , Any ]) -> "Snapshot" :
737
754
"""Creates Snapshot object from its dict representation."""
738
- common_args = cls ._common_fields_from_dict (snapshot_dict )
739
- meta_dicts = snapshot_dict .pop ("meta" )
755
+ common_args = cls ._common_fields_from_dict (signed_dict )
756
+ meta_dicts = signed_dict .pop ("meta" )
740
757
meta = {}
741
758
for meta_path , meta_dict in meta_dicts .items ():
742
759
meta [meta_path ] = MetaFile .from_dict (meta_dict )
743
760
# All fields left in the snapshot_dict are unrecognized.
744
- return cls (* common_args , meta , snapshot_dict )
761
+ return cls (* common_args , meta , signed_dict )
745
762
746
763
def to_dict (self ) -> Dict [str , Any ]:
747
764
"""Returns the dict representation of self."""
@@ -801,7 +818,7 @@ def __init__(
801
818
self .path_hash_prefixes = path_hash_prefixes
802
819
803
820
@classmethod
804
- def from_dict (cls , role_dict : Mapping [str , Any ]) -> "Role " :
821
+ def from_dict (cls , role_dict : Dict [str , Any ]) -> "DelegatedRole " :
805
822
"""Creates DelegatedRole object from its dict representation."""
806
823
name = role_dict .pop ("name" )
807
824
keyids = role_dict .pop ("keyids" )
@@ -971,12 +988,12 @@ def __init__(
971
988
self .delegations = delegations
972
989
973
990
@classmethod
974
- def from_dict (cls , targets_dict : Dict [str , Any ]) -> "Targets" :
991
+ def from_dict (cls , signed_dict : Dict [str , Any ]) -> "Targets" :
975
992
"""Creates Targets object from its dict representation."""
976
- common_args = cls ._common_fields_from_dict (targets_dict )
977
- targets = targets_dict .pop ("targets" )
993
+ common_args = cls ._common_fields_from_dict (signed_dict )
994
+ targets = signed_dict .pop ("targets" )
978
995
try :
979
- delegations_dict = targets_dict .pop ("delegations" )
996
+ delegations_dict = signed_dict .pop ("delegations" )
980
997
except KeyError :
981
998
delegations = None
982
999
else :
@@ -985,7 +1002,7 @@ def from_dict(cls, targets_dict: Dict[str, Any]) -> "Targets":
985
1002
for target_path , target_info in targets .items ():
986
1003
res_targets [target_path ] = TargetFile .from_dict (target_info )
987
1004
# All fields left in the targets_dict are unrecognized.
988
- return cls (* common_args , res_targets , delegations , targets_dict )
1005
+ return cls (* common_args , res_targets , delegations , signed_dict )
989
1006
990
1007
def to_dict (self ) -> Dict [str , Any ]:
991
1008
"""Returns the dict representation of self."""
0 commit comments