func loadTargetsFromStore(gun, role string, repo *tuf.Repo, store storage.MetaStore) error { tgtJSON, err := store.GetCurrent(gun, role) if err != nil { return err } t := &data.SignedTargets{} err = json.Unmarshal(tgtJSON, t) if err != nil { return err } return repo.SetTargets(role, t) }
func loadAndValidateTargets(gun string, repo *tuf.Repo, roles map[string]storage.MetaUpdate, store storage.MetaStore) ([]storage.MetaUpdate, error) { targetsRoles := make(utils.RoleList, 0) for role := range roles { if role == data.CanonicalTargetsRole || data.IsDelegation(role) { targetsRoles = append(targetsRoles, role) } } // N.B. RoleList sorts paths with fewer segments first. // By sorting, we'll always process shallower targets updates before deeper // ones (i.e. we'll load and validate targets before targets/foo). This // helps ensure we only load from storage when necessary in a cleaner way. sort.Sort(targetsRoles) updatesToApply := make([]storage.MetaUpdate, 0, len(targetsRoles)) for _, role := range targetsRoles { // don't load parent if current role is "targets", // we must load all ancestor roles for delegations to validate the full parent chain ancestorRole := role for ancestorRole != data.CanonicalTargetsRole { ancestorRole = path.Dir(ancestorRole) if _, ok := repo.Targets[ancestorRole]; !ok { err := loadTargetsFromStore(gun, ancestorRole, repo, store) if err != nil { return nil, err } } } var ( t *data.SignedTargets err error ) if t, err = validateTargets(role, roles, repo); err != nil { if _, ok := err.(data.ErrInvalidRole); ok { // role wasn't found in its parent. It has been removed // or never existed. Drop this role from the update // (by not adding it to updatesToApply) continue } logrus.Error("ErrBadTargets: ", err.Error()) return nil, validation.ErrBadTargets{Msg: err.Error()} } // this will load keys and roles into the kdb err = repo.SetTargets(role, t) if err != nil { return nil, err } updatesToApply = append(updatesToApply, roles[role]) } return updatesToApply, nil }