6767 MetaFile ,
6868 Root ,
6969 Snapshot ,
70+ SuccinctRoles ,
7071 TargetFile ,
7172 Targets ,
7273 Timestamp ,
@@ -169,7 +170,7 @@ def rotate_keys(self, role: str) -> None:
169170 self .signers [role ].clear ()
170171 for _ in range (0 , self .root .roles [role ].threshold ):
171172 key , signer = self .create_key ()
172- self .root .add_key (role , key )
173+ self .root .add_key (key , role )
173174 self .add_signer (role , signer )
174175
175176 def _initialize (self ) -> None :
@@ -182,7 +183,7 @@ def _initialize(self) -> None:
182183
183184 for role in TOP_LEVEL_ROLE_NAMES :
184185 key , signer = self .create_key ()
185- self .md_root .signed .add_key (role , key )
186+ self .md_root .signed .add_key (key , role )
186187 self .add_signer (role , signer )
187188
188189 self .publish_root ()
@@ -334,12 +335,16 @@ def update_snapshot(self) -> None:
334335 self .snapshot .version += 1
335336 self .update_timestamp ()
336337
338+ def _get_delegator (self , delegator_name : str ) -> Targets :
339+ """Given a delegator name return, its corresponding Targets object."""
340+ if delegator_name == Targets .type :
341+ return self .targets
342+
343+ return self .md_delegates [delegator_name ].signed
344+
337345 def add_target (self , role : str , data : bytes , path : str ) -> None :
338346 """Create a target from data and add it to the target_files."""
339- if role == Targets .type :
340- targets = self .targets
341- else :
342- targets = self .md_delegates [role ].signed
347+ targets = self ._get_delegator (role )
343348
344349 target = TargetFile .from_data (path , data , ["sha256" ])
345350 targets .targets [path ] = target
@@ -349,26 +354,63 @@ def add_delegation(
349354 self , delegator_name : str , role : DelegatedRole , targets : Targets
350355 ) -> None :
351356 """Add delegated target role to the repository."""
352- if delegator_name == Targets .type :
353- delegator = self .targets
354- else :
355- delegator = self .md_delegates [delegator_name ].signed
357+ delegator = self ._get_delegator (delegator_name )
358+
359+ if (
360+ delegator .delegations is not None
361+ and delegator .delegations .succinct_roles is not None
362+ ):
363+ raise ValueError ("Can't add a role when succinct_roles is used" )
356364
357365 # Create delegation
358366 if delegator .delegations is None :
359- delegator .delegations = Delegations ({}, {})
367+ delegator .delegations = Delegations ({}, roles = {})
368+
369+ assert delegator .delegations .roles is not None
360370 # put delegation last by default
361371 delegator .delegations .roles [role .name ] = role
362372
363373 # By default add one new key for the role
364374 key , signer = self .create_key ()
365- delegator .add_key (role .name , key )
375+ delegator .add_key (key , role .name )
366376 self .add_signer (role .name , signer )
367377
368378 # Add metadata for the role
369379 if role .name not in self .md_delegates :
370380 self .md_delegates [role .name ] = Metadata (targets , {})
371381
382+ def add_succinct_roles (
383+ self , delegator_name : str , bit_length : int , name_prefix : str
384+ ) -> None :
385+ """Add succinct roles info to a delegator with name "delegator_name".
386+
387+ Note that for each delegated role represented by succinct roles an empty
388+ Targets instance is created.
389+ """
390+ delegator = self ._get_delegator (delegator_name )
391+
392+ if (
393+ delegator .delegations is not None
394+ and delegator .delegations .roles is not None
395+ ):
396+ raise ValueError (
397+ "Can't add a succinct_roles when delegated roles are used"
398+ )
399+
400+ key , signer = self .create_key ()
401+ succinct_roles = SuccinctRoles ([], 1 , bit_length , name_prefix )
402+ delegator .delegations = Delegations ({}, None , succinct_roles )
403+
404+ # Add targets metadata for all bins.
405+ for delegated_name in succinct_roles .get_roles ():
406+ self .md_delegates [delegated_name ] = Metadata (
407+ Targets (expires = self .safe_expiry )
408+ )
409+
410+ self .add_signer (delegated_name , signer )
411+
412+ delegator .add_key (key )
413+
372414 def write (self ) -> None :
373415 """Dump current repository metadata to self.dump_dir
374416
0 commit comments