...
1 package targets
2
3 import (
4 "errors"
5
6 "github.com/theupdateframework/go-tuf/data"
7 "github.com/theupdateframework/go-tuf/internal/sets"
8 "github.com/theupdateframework/go-tuf/verify"
9 )
10
11 type Delegation struct {
12 Delegator string
13 Delegatee data.DelegatedRole
14 DB *verify.DB
15 }
16
17 type delegationsIterator struct {
18 stack []Delegation
19 target string
20 visitedRoles map[string]struct{}
21 parents map[string]string
22 }
23
24 var ErrTopLevelTargetsRoleMissing = errors.New("tuf: top level targets role missing from top level keys DB")
25
26
27
28 func NewDelegationsIterator(target string, topLevelKeysDB *verify.DB) (*delegationsIterator, error) {
29 targetsRole := topLevelKeysDB.GetRole("targets")
30 if targetsRole == nil {
31 return nil, ErrTopLevelTargetsRoleMissing
32 }
33
34 i := &delegationsIterator{
35 target: target,
36 stack: []Delegation{
37 {
38 Delegatee: data.DelegatedRole{
39 Name: "targets",
40 KeyIDs: sets.StringSetToSlice(targetsRole.KeyIDs),
41 Threshold: targetsRole.Threshold,
42 },
43 DB: topLevelKeysDB,
44 },
45 },
46 visitedRoles: make(map[string]struct{}),
47 parents: make(map[string]string),
48 }
49 return i, nil
50 }
51
52 func (d *delegationsIterator) Next() (value Delegation, ok bool) {
53 if len(d.stack) == 0 {
54 return Delegation{}, false
55 }
56 delegation := d.stack[len(d.stack)-1]
57 d.stack = d.stack[:len(d.stack)-1]
58
59
60
61 roleName := delegation.Delegatee.Name
62 if _, ok := d.visitedRoles[roleName]; ok {
63 return d.Next()
64 }
65 d.visitedRoles[roleName] = struct{}{}
66
67
68
69
70 if delegation.Delegatee.Terminating {
71
72 d.stack = d.stack[0:0]
73 }
74 return delegation, true
75 }
76
77 func (d *delegationsIterator) Add(roles []data.DelegatedRole, delegator string, db *verify.DB) error {
78 for i := len(roles) - 1; i >= 0; i-- {
79
80
81 r := roles[i]
82 matchesPath, err := r.MatchesPath(d.target)
83 if err != nil {
84 return err
85 }
86 if matchesPath {
87 delegation := Delegation{
88 Delegator: delegator,
89 Delegatee: r,
90 DB: db,
91 }
92 d.stack = append(d.stack, delegation)
93 d.parents[r.Name] = delegator
94 }
95 }
96
97 return nil
98 }
99
100 func (d *delegationsIterator) Parent(role string) string {
101 return d.parents[role]
102 }
103
View as plain text