in tough/src/lib.rs [1145:1232]
fn load_delegations(
transport: &dyn Transport,
snapshot: &Signed<Snapshot>,
consistent_snapshot: bool,
metadata_base_url: &Url,
max_targets_size: u64,
delegation: &mut Delegations,
datastore: &Datastore,
) -> Result<()> {
let mut delegated_roles: HashMap<String, Option<Signed<crate::schema::Targets>>> =
HashMap::new();
for delegated_role in &delegation.roles {
// find the role file metadata
let role_meta = snapshot
.signed
.meta
.get(&format!("{}.json", &delegated_role.name))
.context(error::RoleNotInMetaSnafu {
name: delegated_role.name.clone(),
})?;
let path = if consistent_snapshot {
format!(
"{}.{}.json",
&role_meta.version,
encode_filename(&delegated_role.name)
)
} else {
format!("{}.json", encode_filename(&delegated_role.name))
};
let role_url = metadata_base_url.join(&path).context(error::JoinUrlSnafu {
path: path.clone(),
url: metadata_base_url.clone(),
})?;
let specifier = "max_targets_size parameter";
// load the role json file
let reader = Box::new(fetch_max_size(
transport,
role_url,
max_targets_size,
specifier,
)?);
// since each role is a targets, we load them as such
let role: Signed<crate::schema::Targets> =
serde_json::from_reader(reader).context(error::ParseMetadataSnafu {
role: RoleType::Targets,
})?;
// verify each role with the delegation
delegation
.verify_role(&role, &delegated_role.name)
.context(error::VerifyMetadataSnafu {
role: RoleType::Targets,
})?;
ensure!(
role.signed.version == role_meta.version,
error::VersionMismatchSnafu {
role: RoleType::Targets,
fetched: role.signed.version,
expected: role_meta.version
}
);
datastore.create(&path, &role)?;
delegated_roles.insert(delegated_role.name.clone(), Some(role));
}
// load all roles delegated by this role
for delegated_role in &mut delegation.roles {
delegated_role.targets = delegated_roles.remove(&delegated_role.name).context(
error::DelegatedRolesNotConsistentSnafu {
name: delegated_role.name.clone(),
},
)?;
if let Some(targets) = &mut delegated_role.targets {
if let Some(delegations) = &mut targets.signed.delegations {
load_delegations(
transport,
snapshot,
consistent_snapshot,
metadata_base_url,
max_targets_size,
delegations,
datastore,
)?;
}
}
}
Ok(())
}