mirror of https://github.com/docker/docs.git
Do not create the delegation metadata when the delegation is created.
Only create it when a target is added to it, or other delegations are added to it, or when getting a child delegation. Signed-off-by: Ying Li <ying.li@docker.com>
This commit is contained in:
parent
f1761afc25
commit
7592a029ef
|
@ -764,6 +764,44 @@ func TestApplyTargetsDelegationParentDoesntExist(t *testing.T) {
|
|||
assert.IsType(t, data.ErrInvalidRole{}, err)
|
||||
}
|
||||
|
||||
// If there is no delegation target, ApplyTargets creates it
|
||||
func TestApplyChangelistCreatesDelegation(t *testing.T) {
|
||||
_, repo, cs := testutils.EmptyRepo()
|
||||
|
||||
newKey, err := cs.Create("targets/level1", data.ED25519Key)
|
||||
assert.NoError(t, err)
|
||||
|
||||
r, err := data.NewRole("targets/level1", 1, []string{newKey.ID()}, nil, nil)
|
||||
assert.NoError(t, err)
|
||||
repo.UpdateDelegations(r, []data.PublicKey{newKey})
|
||||
delete(repo.Targets, "targets/level1")
|
||||
|
||||
hash := sha256.Sum256([]byte{})
|
||||
f := &data.FileMeta{
|
||||
Length: 1,
|
||||
Hashes: map[string][]byte{
|
||||
"sha256": hash[:],
|
||||
},
|
||||
}
|
||||
fjson, err := json.Marshal(f)
|
||||
assert.NoError(t, err)
|
||||
|
||||
cl := changelist.NewMemChangelist()
|
||||
assert.NoError(t, cl.Add(&changelist.TufChange{
|
||||
Actn: changelist.ActionCreate,
|
||||
Role: "targets/level1",
|
||||
ChangeType: "target",
|
||||
ChangePath: "latest",
|
||||
Data: fjson,
|
||||
}))
|
||||
|
||||
assert.NoError(t, applyChangelist(repo, cl))
|
||||
_, ok := repo.Targets["targets/level1"]
|
||||
assert.True(t, ok, "Failed to create the delegation target")
|
||||
_, ok = repo.Targets["targets/level1"].Signed.Targets["latest"]
|
||||
assert.True(t, ok, "Failed to write change to delegation target")
|
||||
}
|
||||
|
||||
// Each change applies only to the role specified
|
||||
func TestApplyChangelistTargetsToMultipleRoles(t *testing.T) {
|
||||
_, repo, cs := testutils.EmptyRepo()
|
||||
|
@ -808,7 +846,8 @@ func TestApplyChangelistTargetsToMultipleRoles(t *testing.T) {
|
|||
assert.NoError(t, applyChangelist(repo, cl))
|
||||
_, ok := repo.Targets["targets/level1"].Signed.Targets["latest"]
|
||||
assert.True(t, ok)
|
||||
assert.Empty(t, repo.Targets["targets/level2"].Signed.Targets)
|
||||
_, ok = repo.Targets["targets/level2"]
|
||||
assert.False(t, ok, "no change to targets/level2, so metadata not created")
|
||||
}
|
||||
|
||||
// ApplyTargets falls back to role that exists when adding or deleting a change
|
||||
|
|
|
@ -836,7 +836,11 @@ func TestValidateTargetsLoadParent(t *testing.T) {
|
|||
r, err := data.NewRole("targets/level1", 1, []string{k.ID()}, []string{""}, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
baseRepo.UpdateDelegations(r, []data.PublicKey{k})
|
||||
err = baseRepo.UpdateDelegations(r, []data.PublicKey{k})
|
||||
assert.NoError(t, err)
|
||||
|
||||
// no targets file is created for the new delegations, so force one
|
||||
baseRepo.InitTargets("targets/level1")
|
||||
|
||||
// we're not going to validate things loaded from storage, so no need
|
||||
// to sign the base targets, just Marshal it and set it into storage
|
||||
|
@ -885,6 +889,9 @@ func TestValidateTargetsParentInUpdate(t *testing.T) {
|
|||
|
||||
baseRepo.UpdateDelegations(r, []data.PublicKey{k})
|
||||
|
||||
// no targets file is created for the new delegations, so force one
|
||||
baseRepo.InitTargets("targets/level1")
|
||||
|
||||
targets, err := baseRepo.SignTargets("targets", data.DefaultExpires(data.CanonicalTargetsRole))
|
||||
|
||||
tgtsJSON, err := json.Marshal(targets)
|
||||
|
@ -939,6 +946,9 @@ func TestValidateTargetsParentNotFound(t *testing.T) {
|
|||
|
||||
baseRepo.UpdateDelegations(r, []data.PublicKey{k})
|
||||
|
||||
// no targets file is created for the new delegations, so force one
|
||||
baseRepo.InitTargets("targets/level1")
|
||||
|
||||
// generate the update object we're doing to use to call loadAndValidateTargets
|
||||
del, err := baseRepo.SignTargets("targets/level1", data.DefaultExpires(data.CanonicalTargetsRole))
|
||||
assert.NoError(t, err)
|
||||
|
|
52
tuf/tuf.go
52
tuf/tuf.go
|
@ -164,11 +164,20 @@ func (tr *Repo) GetDelegation(role string) (*data.Role, error) {
|
|||
if !r.IsDelegation() {
|
||||
return nil, data.ErrInvalidRole{Role: role, Reason: "not a valid delegated role"}
|
||||
}
|
||||
|
||||
parent := filepath.Dir(role)
|
||||
p, ok := tr.Targets[parent]
|
||||
if !ok {
|
||||
|
||||
// check the parent role
|
||||
if parentRole := tr.keysDB.GetRole(parent); parentRole == nil {
|
||||
return nil, data.ErrInvalidRole{Role: role, Reason: "parent role not found"}
|
||||
}
|
||||
|
||||
// check the parent role's metadata
|
||||
p, ok := tr.Targets[parent]
|
||||
if !ok { // the parent targetfile may not exist yet, so it can't be in the list
|
||||
return nil, data.ErrNoSuchRole{Role: role}
|
||||
}
|
||||
|
||||
foundAt := utils.FindRoleIndex(p.Signed.Delegations.Roles, role)
|
||||
if foundAt < 0 {
|
||||
return nil, data.ErrNoSuchRole{Role: role}
|
||||
|
@ -185,10 +194,19 @@ func (tr *Repo) UpdateDelegations(role *data.Role, keys []data.PublicKey) error
|
|||
return data.ErrInvalidRole{Role: role.Name, Reason: "not a valid delegated role"}
|
||||
}
|
||||
parent := filepath.Dir(role.Name)
|
||||
p, ok := tr.Targets[parent]
|
||||
if !ok {
|
||||
|
||||
// check the parent role
|
||||
if parentRole := tr.keysDB.GetRole(parent); parentRole == nil {
|
||||
return data.ErrInvalidRole{Role: role.Name, Reason: "parent role not found"}
|
||||
}
|
||||
|
||||
// check the parent role's metadata
|
||||
p, ok := tr.Targets[parent]
|
||||
if !ok { // the parent targetfile may not exist yet - if not, then create it
|
||||
p = data.NewTargets()
|
||||
tr.Targets[parent] = p
|
||||
}
|
||||
|
||||
for _, k := range keys {
|
||||
if !utils.StrSliceContains(role.KeyIDs, k.ID()) {
|
||||
role.KeyIDs = append(role.KeyIDs, k.ID())
|
||||
|
@ -214,11 +232,11 @@ func (tr *Repo) UpdateDelegations(role *data.Role, keys []data.PublicKey) error
|
|||
// We've made a change to parent. Set it to dirty
|
||||
p.Dirty = true
|
||||
|
||||
roleTargets := data.NewTargets() // NewTargets always marked Dirty
|
||||
tr.Targets[role.Name] = roleTargets
|
||||
// We don't actually want to create the new delegation metadata yet.
|
||||
// When we add a delegation, it may only be signable by a key we don't have
|
||||
// (hence we are delegating signing).
|
||||
|
||||
tr.keysDB.AddRole(role)
|
||||
|
||||
utils.RemoveUnusedKeys(p)
|
||||
|
||||
return nil
|
||||
|
@ -476,18 +494,26 @@ func (tr Repo) FindTarget(path string) *data.FileMeta {
|
|||
}
|
||||
|
||||
// AddTargets will attempt to add the given targets specifically to
|
||||
// the directed role. If the user does not have the signing keys for the role
|
||||
// the function will return an error and the full slice of targets.
|
||||
// the directed role. If the metadata for the role doesn't exist yet,
|
||||
// AddTargets will create one.
|
||||
func (tr *Repo) AddTargets(role string, targets data.Files) (data.Files, error) {
|
||||
t, ok := tr.Targets[role]
|
||||
if !ok {
|
||||
return targets, data.ErrInvalidRole{Role: role, Reason: "does not exist"}
|
||||
// check the role exists
|
||||
r := tr.keysDB.GetRole(role)
|
||||
if r == nil {
|
||||
return nil, data.ErrInvalidRole{Role: role, Reason: "does not exist"}
|
||||
}
|
||||
|
||||
// check the role's metadata
|
||||
t, ok := tr.Targets[role]
|
||||
if !ok { // the targetfile may not exist yet - if not, then create it
|
||||
t = data.NewTargets()
|
||||
tr.Targets[role] = t
|
||||
}
|
||||
|
||||
invalid := make(data.Files)
|
||||
for path, target := range targets {
|
||||
pathDigest := sha256.Sum256([]byte(path))
|
||||
pathHex := hex.EncodeToString(pathDigest[:])
|
||||
r := tr.keysDB.GetRole(role)
|
||||
if role == data.ValidRoles["targets"] || (r.CheckPaths(path) || r.CheckPrefixes(pathHex)) {
|
||||
t.Signed.Targets[path] = target
|
||||
} else {
|
||||
|
|
245
tuf/tuf_test.go
245
tuf/tuf_test.go
|
@ -1,6 +1,7 @@
|
|||
package tuf
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
@ -155,7 +156,12 @@ func TestUpdateDelegations(t *testing.T) {
|
|||
err = repo.UpdateDelegations(role, data.KeyList{testKey})
|
||||
assert.NoError(t, err)
|
||||
|
||||
r := repo.Targets[data.CanonicalTargetsRole]
|
||||
// no empty metadata is created for this role
|
||||
_, ok := repo.Targets["targets/test"]
|
||||
assert.False(t, ok, "no empty targets file should be created for deepest delegation")
|
||||
|
||||
r, ok := repo.Targets[data.CanonicalTargetsRole]
|
||||
assert.True(t, ok)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 1)
|
||||
assert.Len(t, r.Signed.Delegations.Keys, 1)
|
||||
keyIDs := r.Signed.Delegations.Roles[0].KeyIDs
|
||||
|
@ -170,13 +176,20 @@ func TestUpdateDelegations(t *testing.T) {
|
|||
err = repo.UpdateDelegations(roleDeep, data.KeyList{testDeepKey})
|
||||
assert.NoError(t, err)
|
||||
|
||||
r = repo.Targets["targets/test"]
|
||||
// this metadata didn't exist before, but creating targets/test/deep created
|
||||
// the targets/test metadata
|
||||
r, ok = repo.Targets["targets/test"]
|
||||
assert.True(t, ok)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 1)
|
||||
assert.Len(t, r.Signed.Delegations.Keys, 1)
|
||||
keyIDs = r.Signed.Delegations.Roles[0].KeyIDs
|
||||
assert.Len(t, keyIDs, 1)
|
||||
assert.Equal(t, testDeepKey.ID(), keyIDs[0])
|
||||
assert.True(t, r.Dirty)
|
||||
|
||||
// no empty delegation metadata is created for targets/test/deep
|
||||
_, ok = repo.Targets["targets/test/deep"]
|
||||
assert.False(t, ok, "no empty targets file should be created for deepest delegation")
|
||||
}
|
||||
|
||||
func TestUpdateDelegationsParentMissing(t *testing.T) {
|
||||
|
@ -193,8 +206,13 @@ func TestUpdateDelegationsParentMissing(t *testing.T) {
|
|||
assert.Error(t, err)
|
||||
assert.IsType(t, data.ErrInvalidRole{}, err)
|
||||
|
||||
r := repo.Targets[data.CanonicalTargetsRole]
|
||||
r, ok := repo.Targets[data.CanonicalTargetsRole]
|
||||
assert.True(t, ok)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 0)
|
||||
|
||||
// no delegation metadata created for non-existent parent
|
||||
_, ok = repo.Targets["targets/test"]
|
||||
assert.False(t, ok, "no targets file should be created for nonexistent parent delegation")
|
||||
}
|
||||
|
||||
func TestUpdateDelegationsInvalidRole(t *testing.T) {
|
||||
|
@ -214,8 +232,13 @@ func TestUpdateDelegationsInvalidRole(t *testing.T) {
|
|||
assert.Error(t, err)
|
||||
assert.IsType(t, data.ErrInvalidRole{}, err)
|
||||
|
||||
r := repo.Targets[data.CanonicalTargetsRole]
|
||||
r, ok := repo.Targets[data.CanonicalTargetsRole]
|
||||
assert.True(t, ok)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 0)
|
||||
|
||||
// no delegation metadata created for invalid delgation
|
||||
_, ok = repo.Targets["root"]
|
||||
assert.False(t, ok, "no targets file should be created since delegation failed")
|
||||
}
|
||||
|
||||
func TestUpdateDelegationsRoleMissingKey(t *testing.T) {
|
||||
|
@ -233,13 +256,18 @@ func TestUpdateDelegationsRoleMissingKey(t *testing.T) {
|
|||
err = repo.UpdateDelegations(role, data.KeyList{roleKey})
|
||||
assert.NoError(t, err)
|
||||
|
||||
r := repo.Targets[data.CanonicalTargetsRole]
|
||||
r, ok := repo.Targets[data.CanonicalTargetsRole]
|
||||
assert.True(t, ok)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 1)
|
||||
assert.Len(t, r.Signed.Delegations.Keys, 1)
|
||||
keyIDs := r.Signed.Delegations.Roles[0].KeyIDs
|
||||
assert.Len(t, keyIDs, 1)
|
||||
assert.Equal(t, roleKey.ID(), keyIDs[0])
|
||||
assert.True(t, r.Dirty)
|
||||
|
||||
// no empty delegation metadata created for new delegation
|
||||
_, ok = repo.Targets["targets/role"]
|
||||
assert.False(t, ok, "no targets file should be created for empty delegation")
|
||||
}
|
||||
|
||||
func TestUpdateDelegationsNotEnoughKeys(t *testing.T) {
|
||||
|
@ -253,10 +281,13 @@ func TestUpdateDelegationsNotEnoughKeys(t *testing.T) {
|
|||
role, err := data.NewRole("targets/role", 2, []string{}, []string{""}, []string{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
// key should get added to role as part of updating the delegation
|
||||
err = repo.UpdateDelegations(role, data.KeyList{roleKey})
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, data.ErrInvalidRole{}, err)
|
||||
|
||||
// no delegation metadata created for failed delegation
|
||||
_, ok := repo.Targets["targets/role"]
|
||||
assert.False(t, ok, "no targets file should be created since delegation failed")
|
||||
}
|
||||
|
||||
func TestUpdateDelegationsReplaceRole(t *testing.T) {
|
||||
|
@ -272,13 +303,22 @@ func TestUpdateDelegationsReplaceRole(t *testing.T) {
|
|||
err = repo.UpdateDelegations(role, data.KeyList{testKey})
|
||||
assert.NoError(t, err)
|
||||
|
||||
r := repo.Targets[data.CanonicalTargetsRole]
|
||||
r, ok := repo.Targets[data.CanonicalTargetsRole]
|
||||
assert.True(t, ok)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 1)
|
||||
assert.Len(t, r.Signed.Delegations.Keys, 1)
|
||||
keyIDs := r.Signed.Delegations.Roles[0].KeyIDs
|
||||
assert.Len(t, keyIDs, 1)
|
||||
assert.Equal(t, testKey.ID(), keyIDs[0])
|
||||
|
||||
// no empty delegation metadata created for new delegation
|
||||
_, ok = repo.Targets["targets/test"]
|
||||
assert.False(t, ok, "no targets file should be created for empty delegation")
|
||||
|
||||
// create one now to assert that replacing the delegation doesn't delete the
|
||||
// metadata
|
||||
repo.Targets["targets/test"] = data.NewTargets()
|
||||
|
||||
// create another role with the same name and ensure it replaces the
|
||||
// previous role
|
||||
testKey2, err := ed25519.Create("targets/test", data.ED25519Key)
|
||||
|
@ -289,13 +329,18 @@ func TestUpdateDelegationsReplaceRole(t *testing.T) {
|
|||
err = repo.UpdateDelegations(role2, data.KeyList{testKey2})
|
||||
assert.NoError(t, err)
|
||||
|
||||
r = repo.Targets["targets"]
|
||||
r, ok = repo.Targets["targets"]
|
||||
assert.True(t, ok)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 1)
|
||||
assert.Len(t, r.Signed.Delegations.Keys, 1)
|
||||
keyIDs = r.Signed.Delegations.Roles[0].KeyIDs
|
||||
assert.Len(t, keyIDs, 1)
|
||||
assert.Equal(t, testKey2.ID(), keyIDs[0])
|
||||
assert.True(t, r.Dirty)
|
||||
|
||||
// delegation was not deleted
|
||||
_, ok = repo.Targets["targets/test"]
|
||||
assert.True(t, ok, "targets file should still be here")
|
||||
}
|
||||
|
||||
func TestUpdateDelegationsAddKeyToRole(t *testing.T) {
|
||||
|
@ -311,7 +356,8 @@ func TestUpdateDelegationsAddKeyToRole(t *testing.T) {
|
|||
err = repo.UpdateDelegations(role, data.KeyList{testKey})
|
||||
assert.NoError(t, err)
|
||||
|
||||
r := repo.Targets[data.CanonicalTargetsRole]
|
||||
r, ok := repo.Targets[data.CanonicalTargetsRole]
|
||||
assert.True(t, ok)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 1)
|
||||
assert.Len(t, r.Signed.Delegations.Keys, 1)
|
||||
keyIDs := r.Signed.Delegations.Roles[0].KeyIDs
|
||||
|
@ -324,7 +370,8 @@ func TestUpdateDelegationsAddKeyToRole(t *testing.T) {
|
|||
err = repo.UpdateDelegations(role, data.KeyList{testKey2})
|
||||
assert.NoError(t, err)
|
||||
|
||||
r = repo.Targets["targets"]
|
||||
r, ok = repo.Targets["targets"]
|
||||
assert.True(t, ok)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 1)
|
||||
assert.Len(t, r.Signed.Delegations.Keys, 2)
|
||||
keyIDs = r.Signed.Delegations.Roles[0].KeyIDs
|
||||
|
@ -348,17 +395,26 @@ func TestDeleteDelegations(t *testing.T) {
|
|||
err = repo.UpdateDelegations(role, data.KeyList{testKey})
|
||||
assert.NoError(t, err)
|
||||
|
||||
r := repo.Targets[data.CanonicalTargetsRole]
|
||||
r, ok := repo.Targets[data.CanonicalTargetsRole]
|
||||
assert.True(t, ok)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 1)
|
||||
assert.Len(t, r.Signed.Delegations.Keys, 1)
|
||||
keyIDs := r.Signed.Delegations.Roles[0].KeyIDs
|
||||
assert.Len(t, keyIDs, 1)
|
||||
assert.Equal(t, testKey.ID(), keyIDs[0])
|
||||
|
||||
// ensure that the metadata is there
|
||||
repo.Targets["targets/test"] = data.NewTargets()
|
||||
|
||||
err = repo.DeleteDelegation(*role)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 0)
|
||||
assert.Len(t, r.Signed.Delegations.Keys, 0)
|
||||
assert.True(t, r.Dirty)
|
||||
|
||||
// metadata should be deleted
|
||||
_, ok = repo.Targets["targets/test"]
|
||||
assert.False(t, ok)
|
||||
|
||||
}
|
||||
|
||||
func TestDeleteDelegationsRoleNotExist(t *testing.T) {
|
||||
|
@ -376,7 +432,8 @@ func TestDeleteDelegationsRoleNotExist(t *testing.T) {
|
|||
|
||||
err = repo.DeleteDelegation(*role)
|
||||
assert.NoError(t, err)
|
||||
r := repo.Targets[data.CanonicalTargetsRole]
|
||||
r, ok := repo.Targets[data.CanonicalTargetsRole]
|
||||
assert.True(t, ok)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 0)
|
||||
assert.Len(t, r.Signed.Delegations.Keys, 0)
|
||||
assert.False(t, r.Dirty)
|
||||
|
@ -396,7 +453,8 @@ func TestDeleteDelegationsInvalidRole(t *testing.T) {
|
|||
assert.Error(t, err)
|
||||
assert.IsType(t, data.ErrInvalidRole{}, err)
|
||||
|
||||
r := repo.Targets[data.CanonicalTargetsRole]
|
||||
r, ok := repo.Targets[data.CanonicalTargetsRole]
|
||||
assert.True(t, ok)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 0)
|
||||
}
|
||||
|
||||
|
@ -412,7 +470,8 @@ func TestDeleteDelegationsParentMissing(t *testing.T) {
|
|||
assert.Error(t, err)
|
||||
assert.IsType(t, data.ErrInvalidRole{}, err)
|
||||
|
||||
r := repo.Targets[data.CanonicalTargetsRole]
|
||||
r, ok := repo.Targets[data.CanonicalTargetsRole]
|
||||
assert.True(t, ok)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 0)
|
||||
}
|
||||
|
||||
|
@ -444,12 +503,85 @@ func TestDeleteDelegationsMidSliceRole(t *testing.T) {
|
|||
err = repo.DeleteDelegation(*role2)
|
||||
assert.NoError(t, err)
|
||||
|
||||
r := repo.Targets[data.CanonicalTargetsRole]
|
||||
r, ok := repo.Targets[data.CanonicalTargetsRole]
|
||||
assert.True(t, ok)
|
||||
assert.Len(t, r.Signed.Delegations.Roles, 2)
|
||||
assert.Len(t, r.Signed.Delegations.Keys, 1)
|
||||
assert.True(t, r.Dirty)
|
||||
}
|
||||
|
||||
// If the parent exists, the metadata exists, and the delegation is in it,
|
||||
// returns the role that was found
|
||||
func TestGetDelegationRoleAndMetadataExistDelegationExists(t *testing.T) {
|
||||
ed25519 := signed.NewEd25519()
|
||||
keyDB := keys.NewDB()
|
||||
repo := initRepo(t, ed25519, keyDB)
|
||||
|
||||
testKey, err := ed25519.Create("meh", data.ED25519Key)
|
||||
assert.NoError(t, err)
|
||||
|
||||
role, err := data.NewRole(
|
||||
"targets/level1", 1, []string{testKey.ID()}, []string{}, []string{})
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, repo.UpdateDelegations(role, data.KeyList{testKey}))
|
||||
|
||||
role, err = data.NewRole(
|
||||
"targets/level1/level2", 1, []string{testKey.ID()}, []string{}, []string{})
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, repo.UpdateDelegations(role, data.KeyList{testKey}))
|
||||
|
||||
gottenRole, err := repo.GetDelegation("targets/level1/level2")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, role, gottenRole)
|
||||
}
|
||||
|
||||
// If the parent exists, the metadata exists, and the delegation isn't in it,
|
||||
// returns an ErrNoSuchRole
|
||||
func TestGetDelegationRoleAndMetadataExistDelegationDoesntExists(t *testing.T) {
|
||||
ed25519 := signed.NewEd25519()
|
||||
keyDB := keys.NewDB()
|
||||
repo := initRepo(t, ed25519, keyDB)
|
||||
|
||||
testKey, err := ed25519.Create("meh", data.ED25519Key)
|
||||
assert.NoError(t, err)
|
||||
|
||||
role, err := data.NewRole(
|
||||
"targets/level1", 1, []string{testKey.ID()}, []string{}, []string{})
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, repo.UpdateDelegations(role, data.KeyList{testKey}))
|
||||
|
||||
// ensure metadata exists
|
||||
repo.Targets["targets/level1"] = data.NewTargets()
|
||||
|
||||
_, err = repo.GetDelegation("targets/level1/level2")
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, data.ErrNoSuchRole{}, err)
|
||||
}
|
||||
|
||||
// If the parent exists but the metadata doesn't exist, returns an ErrNoSuchRole
|
||||
func TestGetDelegationRoleAndMetadataDoesntExists(t *testing.T) {
|
||||
ed25519 := signed.NewEd25519()
|
||||
keyDB := keys.NewDB()
|
||||
repo := initRepo(t, ed25519, keyDB)
|
||||
|
||||
testKey, err := ed25519.Create("meh", data.ED25519Key)
|
||||
assert.NoError(t, err)
|
||||
|
||||
role, err := data.NewRole(
|
||||
"targets/level1", 1, []string{testKey.ID()}, []string{}, []string{})
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, repo.UpdateDelegations(role, data.KeyList{testKey}))
|
||||
|
||||
// no empty delegation metadata created for new delegation
|
||||
_, ok := repo.Targets["targets/test"]
|
||||
assert.False(t, ok, "no targets file should be created for empty delegation")
|
||||
|
||||
_, err = repo.GetDelegation("targets/level1/level2")
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, data.ErrNoSuchRole{}, err)
|
||||
}
|
||||
|
||||
// If the parent role doesn't exist, GetDelegation fails with an ErrInvalidRole
|
||||
func TestGetDelegationParentMissing(t *testing.T) {
|
||||
ed25519 := signed.NewEd25519()
|
||||
keyDB := keys.NewDB()
|
||||
|
@ -459,3 +591,86 @@ func TestGetDelegationParentMissing(t *testing.T) {
|
|||
assert.Error(t, err)
|
||||
assert.IsType(t, data.ErrInvalidRole{}, err)
|
||||
}
|
||||
|
||||
// Adding targets to a role that exists and has metadata (like targets)
|
||||
// correctly adds the target
|
||||
func TestAddTargetsRoleAndMetadataExist(t *testing.T) {
|
||||
ed25519 := signed.NewEd25519()
|
||||
keyDB := keys.NewDB()
|
||||
repo := initRepo(t, ed25519, keyDB)
|
||||
|
||||
hash := sha256.Sum256([]byte{})
|
||||
f := data.FileMeta{
|
||||
Length: 1,
|
||||
Hashes: map[string][]byte{
|
||||
"sha256": hash[:],
|
||||
},
|
||||
}
|
||||
|
||||
_, err := repo.AddTargets(data.CanonicalTargetsRole, data.Files{"f": f})
|
||||
assert.NoError(t, err)
|
||||
|
||||
r, ok := repo.Targets[data.CanonicalTargetsRole]
|
||||
assert.True(t, ok)
|
||||
targetsF, ok := r.Signed.Targets["f"]
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, f, targetsF)
|
||||
}
|
||||
|
||||
// Adding targets to a role that exists and has not metadata first creates the
|
||||
// metadata and then correctly adds the target
|
||||
func TestAddTargetsRoleExistsAndMetadataDoesntExist(t *testing.T) {
|
||||
hash := sha256.Sum256([]byte{})
|
||||
f := data.FileMeta{
|
||||
Length: 1,
|
||||
Hashes: map[string][]byte{
|
||||
"sha256": hash[:],
|
||||
},
|
||||
}
|
||||
|
||||
ed25519 := signed.NewEd25519()
|
||||
keyDB := keys.NewDB()
|
||||
repo := initRepo(t, ed25519, keyDB)
|
||||
|
||||
testKey, err := ed25519.Create("targets/test", data.ED25519Key)
|
||||
assert.NoError(t, err)
|
||||
role, err := data.NewRole(
|
||||
"targets/test", 1, []string{testKey.ID()}, []string{"test"}, []string{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = repo.UpdateDelegations(role, data.KeyList{testKey})
|
||||
assert.NoError(t, err)
|
||||
|
||||
// no empty metadata is created for this role
|
||||
_, ok := repo.Targets["targets/test"]
|
||||
assert.False(t, ok, "no empty targets file should be created")
|
||||
|
||||
// adding the targets to the role should create the metadata though
|
||||
_, err = repo.AddTargets("targets/test", data.Files{"f": f})
|
||||
assert.NoError(t, err)
|
||||
|
||||
r, ok := repo.Targets["targets/test"]
|
||||
assert.True(t, ok)
|
||||
targetsF, ok := r.Signed.Targets["f"]
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, f, targetsF)
|
||||
}
|
||||
|
||||
// Adding targets to a role that doesn't exist fails
|
||||
func TestAddTargetsRoleDoesntExist(t *testing.T) {
|
||||
hash := sha256.Sum256([]byte{})
|
||||
f := data.FileMeta{
|
||||
Length: 1,
|
||||
Hashes: map[string][]byte{
|
||||
"sha256": hash[:],
|
||||
},
|
||||
}
|
||||
|
||||
ed25519 := signed.NewEd25519()
|
||||
keyDB := keys.NewDB()
|
||||
repo := initRepo(t, ed25519, keyDB)
|
||||
|
||||
_, err := repo.AddTargets("targets/test", data.Files{"f": f})
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, data.ErrInvalidRole{}, err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue