...

Source file src/github.com/theupdateframework/go-tuf/pkg/targets/delegation_test.go

Documentation: github.com/theupdateframework/go-tuf/pkg/targets

     1  package targets
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  	"github.com/theupdateframework/go-tuf/data"
     8  	"github.com/theupdateframework/go-tuf/verify"
     9  )
    10  
    11  var (
    12  	defaultPathPatterns = []string{"tmp", "*"}
    13  	noMatchPathPatterns = []string{"vars", "null"}
    14  )
    15  
    16  func TestDelegationsIterator(t *testing.T) {
    17  	topTargetsPubKey := &data.PublicKey{
    18  		Type:       data.KeyTypeEd25519,
    19  		Scheme:     data.KeySchemeEd25519,
    20  		Algorithms: data.HashAlgorithms,
    21  		Value:      []byte(`{"public":"aaaaec567e5901ba3976c34f7cd5169704292439bf71e6aa19c64b96706f95ef"}`),
    22  	}
    23  	delTargetsPubKey := &data.PublicKey{
    24  		Type:       data.KeyTypeEd25519,
    25  		Scheme:     data.KeySchemeEd25519,
    26  		Algorithms: data.HashAlgorithms,
    27  		Value:      []byte(`{"public":"bbbbec567e5901ba3976c34f7cd5169704292439bf71e6aa19c64b96706f95ef"}`),
    28  	}
    29  
    30  	defaultKeyIDs := delTargetsPubKey.IDs()
    31  	var iteratorTests = []struct {
    32  		testName    string
    33  		roles       map[string][]data.DelegatedRole
    34  		file        string
    35  		resultOrder []string
    36  		err         error
    37  	}{
    38  		{
    39  			testName: "no delegation",
    40  			roles: map[string][]data.DelegatedRole{
    41  				"targets": {},
    42  			},
    43  			file:        "test.txt",
    44  			resultOrder: []string{"targets"},
    45  		},
    46  		{
    47  			testName: "no termination",
    48  			roles: map[string][]data.DelegatedRole{
    49  				"targets": {
    50  					{Name: "b", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    51  					{Name: "e", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    52  				},
    53  				"b": {
    54  					{Name: "c", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    55  				},
    56  				"c": {
    57  					{Name: "d", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    58  				},
    59  				"e": {
    60  					{Name: "f", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    61  					{Name: "g", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    62  				},
    63  				"g": {
    64  					{Name: "h", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    65  					{Name: "i", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    66  					{Name: "j", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    67  				},
    68  			},
    69  			file:        "",
    70  			resultOrder: []string{"targets", "b", "c", "d", "e", "f", "g", "h", "i", "j"},
    71  		},
    72  		{
    73  			testName: "terminated in b",
    74  			roles: map[string][]data.DelegatedRole{
    75  				"targets": {
    76  					{Name: "b", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs, Terminating: true},
    77  					{Name: "e", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    78  				},
    79  				"b": {
    80  					{Name: "c", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    81  					{Name: "d", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    82  				},
    83  			},
    84  			file:        "",
    85  			resultOrder: []string{"targets", "b", "c", "d"},
    86  		},
    87  		{
    88  			testName: "path does not match b",
    89  			roles: map[string][]data.DelegatedRole{
    90  				"targets": {
    91  					{Name: "b", Paths: noMatchPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    92  					{Name: "e", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    93  				},
    94  				"b": {
    95  					{Name: "c", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    96  					{Name: "d", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
    97  				},
    98  			},
    99  			file:        "",
   100  			resultOrder: []string{"targets", "e"},
   101  		},
   102  		{
   103  			testName: "path does not match b - path prefixes",
   104  			roles: map[string][]data.DelegatedRole{
   105  				"targets": {
   106  					{Name: "b", PathHashPrefixes: []string{"33472a4909"}, Threshold: 1, KeyIDs: defaultKeyIDs},
   107  					{Name: "c", PathHashPrefixes: []string{"34c85d1ee84f61f10d7dc633"}, Threshold: 1, KeyIDs: defaultKeyIDs},
   108  				},
   109  				"c": {
   110  
   111  					{Name: "d", PathHashPrefixes: []string{"8baf"}, Threshold: 1, KeyIDs: defaultKeyIDs},
   112  					{Name: "e", PathHashPrefixes: []string{"34c85d1ee84f61f10d7dc633472a49096ed87f8f764bd597831eac371f40ac39"}, Threshold: 1, KeyIDs: defaultKeyIDs},
   113  				},
   114  			},
   115  			file:        "/e/f/g.txt",
   116  			resultOrder: []string{"targets", "c", "e"},
   117  		},
   118  		{
   119  			testName: "err paths and pathHashPrefixes are set",
   120  			roles: map[string][]data.DelegatedRole{
   121  				"targets": {
   122  					{Name: "b", Paths: defaultPathPatterns, PathHashPrefixes: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   123  				},
   124  				"b": {},
   125  			},
   126  			file:        "",
   127  			resultOrder: []string{"targets"},
   128  			err:         data.ErrPathsAndPathHashesSet,
   129  		},
   130  		{
   131  			testName: "cycle avoided 1",
   132  			roles: map[string][]data.DelegatedRole{
   133  				"targets": {
   134  					{Name: "a", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   135  				},
   136  				"a": {
   137  					{Name: "b", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   138  					{Name: "e", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   139  				},
   140  				"b": {
   141  					{Name: "a", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   142  					{Name: "d", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   143  				},
   144  			},
   145  			file:        "",
   146  			resultOrder: []string{"targets", "a", "b", "d", "e"},
   147  		},
   148  		{
   149  			testName: "cycle avoided 2",
   150  			roles: map[string][]data.DelegatedRole{
   151  				"targets": {
   152  					{Name: "a", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   153  				},
   154  				"a": {
   155  					{Name: "a", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   156  					{Name: "b", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   157  				},
   158  				"b": {
   159  					{Name: "a", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   160  					{Name: "b", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   161  					{Name: "c", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   162  				},
   163  				"c": {
   164  					{Name: "c", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   165  				},
   166  			},
   167  			file:        "",
   168  			resultOrder: []string{"targets", "a", "b", "c"},
   169  		},
   170  		{
   171  			testName: "diamond delegation",
   172  			roles: map[string][]data.DelegatedRole{
   173  				"targets": {
   174  					{Name: "b", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   175  					{Name: "c", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   176  				},
   177  				"b": {
   178  					{Name: "d", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   179  				},
   180  				"c": {
   181  					{Name: "d", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   182  				},
   183  			},
   184  			file:        "",
   185  			resultOrder: []string{"targets", "b", "d", "c"},
   186  		},
   187  		{
   188  			testName: "simple cycle",
   189  			roles: map[string][]data.DelegatedRole{
   190  				"targets": {
   191  					{Name: "a", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   192  				},
   193  				"a": {
   194  					{Name: "a", Paths: defaultPathPatterns, Threshold: 1, KeyIDs: defaultKeyIDs},
   195  				},
   196  			},
   197  			file:        "",
   198  			resultOrder: []string{"targets", "a"},
   199  		},
   200  	}
   201  
   202  	for _, tt := range iteratorTests {
   203  		t.Run(tt.testName, func(t *testing.T) {
   204  			topLevelDB := verify.NewDB()
   205  			topLevelDB.AddKey(topTargetsPubKey.IDs()[0], topTargetsPubKey)
   206  			topLevelDB.AddRole("targets", &data.Role{
   207  				KeyIDs:    topTargetsPubKey.IDs(),
   208  				Threshold: 1,
   209  			})
   210  
   211  			d, err := NewDelegationsIterator(tt.file, topLevelDB)
   212  			assert.NoError(t, err)
   213  
   214  			var iterationOrder []string
   215  			for {
   216  				r, ok := d.Next()
   217  				if !ok {
   218  					break
   219  				}
   220  
   221  				// A delegation should have associated keys. Testing the exact keys
   222  				// isn't useful in this module since the keys are supplied by the
   223  				// caller in the arguments to Add().
   224  				assert.Greater(t, len(r.Delegatee.KeyIDs), 0)
   225  
   226  				iterationOrder = append(iterationOrder, r.Delegatee.Name)
   227  				delegations, ok := tt.roles[r.Delegatee.Name]
   228  				if !ok {
   229  					continue
   230  				}
   231  
   232  				db, err := verify.NewDBFromDelegations(&data.Delegations{
   233  					Roles: delegations,
   234  				})
   235  				assert.NoError(t, err)
   236  
   237  				err = d.Add(delegations, r.Delegatee.Name, db)
   238  				assert.Equal(t, tt.err, err)
   239  			}
   240  			assert.Equal(t, tt.resultOrder, iterationOrder)
   241  		})
   242  	}
   243  }
   244  
   245  func TestNewDelegationsIteratorError(t *testing.T) {
   246  	// Empty DB. It is supposed to have at least the top-level targets role and
   247  	// keys.
   248  	tldb := verify.NewDB()
   249  
   250  	_, err := NewDelegationsIterator("targets", tldb)
   251  	assert.ErrorIs(t, err, ErrTopLevelTargetsRoleMissing)
   252  }
   253  

View as plain text