Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non-recursive DFS token tree revoke #2478

Merged
merged 37 commits into from
Dec 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
93fc947
first commit
lemondrank Mar 13, 2017
16eadf4
changed a few things, still doesnt work D:
lemondrank Mar 13, 2017
c856b8f
fixed list type problems i think
lemondrank Mar 13, 2017
0778317
Merge branch 'master' of https://github.com/hashicorp/vault
lemondrank Apr 6, 2017
2337ebc
properly prepends children array to dfs List
lemondrank Apr 6, 2017
b5684c5
Merge branch 'master' of https://github.com/hashicorp/vault
lemondrank Apr 14, 2017
5721a6e
implemented dfs with slice instead of list
lemondrank Apr 14, 2017
5985f6b
implemented dadgars testing for revokeTree
lemondrank Apr 14, 2017
b6b7632
Fixed improper function name
lemondrank Apr 14, 2017
a437562
Fixed improper function name for real this time
lemondrank Apr 14, 2017
0cc8616
Merge branch 'master' of https://github.com/hashicorp/vault
lemondrank Apr 21, 2017
352b15f
fixed some errors, but tests are hanging
lemondrank Apr 21, 2017
5ff2a92
fixed hanging problem, still need to clean up comments
lemondrank Apr 21, 2017
5b5fef5
cleaned up comments, should be ready for a review.
lemondrank Apr 23, 2017
0ad78e1
cleaned up comments for real this time
lemondrank Apr 23, 2017
87fc97b
clean up
lemondrank Apr 24, 2017
ad3a70c
Merge branch 'master' of https://github.com/hashicorp/vault
lemondrank Apr 24, 2017
5157969
commit
lemondrank Apr 28, 2017
c1dbae3
fixed merge conflict(i think)
lemondrank Apr 28, 2017
2b0cd93
ran gofmt, not sure if it worked
lemondrank Apr 28, 2017
947b9b9
hopefully formatted
lemondrank Apr 28, 2017
bebb56b
fixed handleTidy issue
lemondrank Apr 28, 2017
4b42e38
Merge branch 'master' of https://github.com/hashicorp/vault
lemondrank Apr 28, 2017
d30a433
added variety of depths for testing
lemondrank May 5, 2017
a0801a6
Merge branch 'master' of https://github.com/hashicorp/vault
lemondrank May 5, 2017
becaacb
formatting
lemondrank May 5, 2017
4e6a830
changed max testing depth to 10
lemondrank May 6, 2017
a97ea4e
Merge branch 'master' of https://github.com/hashicorp/vault
lemondrank May 6, 2017
358a85d
Merge branch 'master' of https://github.com/hashicorp/vault
lemondrank May 9, 2017
c9f7d82
checking if build will pass for depth 2
lemondrank May 9, 2017
73a579d
Merge branch 'master' of https://github.com/hashicorp/vault
lemondrank May 10, 2017
87c943b
trying again with depth 10
lemondrank May 10, 2017
605c521
Merge branch 'master' of https://github.com/hashicorp/vault
lemondrank May 12, 2017
d2c90ce
Merge branch 'master' of https://github.com/hashicorp/vault
lemondrank May 12, 2017
b121dfb
made requested changes, should be good to go
lemondrank May 12, 2017
2c2c890
Merge branch 'master' into master
jefferai Dec 4, 2017
e89ab44
Merge branch 'master' into master
jefferai Dec 11, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 27 additions & 17 deletions vault/token_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -1214,29 +1214,39 @@ func (ts *TokenStore) RevokeTree(id string) error {
return nil
}

// revokeTreeSalted is used to invalide a given token and all
// revokeTreeSalted is used to invalidate a given token and all
// child tokens using a saltedID.
// Updated to be non-recursive and revoke child tokens
// before parent tokens(DFS).
func (ts *TokenStore) revokeTreeSalted(saltedId string) error {
// Scan for child tokens
path := parentPrefix + saltedId + "/"
children, err := ts.view.List(path)
if err != nil {
return fmt.Errorf("failed to scan for children: %v", err)
}
var dfs []string
dfs = append(dfs, saltedId)

// Recursively nuke the children. The subtle nuance here is that
// we don't have the acutal ID of the child, but we have the salted
// value. Turns out, this is good enough!
for _, child := range children {
if err := ts.revokeTreeSalted(child); err != nil {
return err
for l := len(dfs); l > 0; l = len(dfs) {
id := dfs[0]
path := parentPrefix + id + "/"
children, err := ts.view.List(path)
if err != nil {
return fmt.Errorf("failed to scan for children: %v", err)
}
// If the length of the children array is zero,
// then we are at a leaf node.
if len(children) == 0 {
if err := ts.revokeSalted(id); err != nil {
return fmt.Errorf("failed to revoke entry: %v", err)
}
// If the length of l is equal to 1, then the last token has been deleted
if l == 1 {
return nil
}
dfs = dfs[1:]
} else {
// If we make it here, there are children and they must
// be prepended.
dfs = append(children, dfs...)
}
}

// Revoke this entry
if err := ts.revokeSalted(saltedId); err != nil {
return fmt.Errorf("failed to revoke entry: %v", err)
}
return nil
}

Expand Down
91 changes: 66 additions & 25 deletions vault/token_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -770,41 +770,36 @@ func TestTokenStore_Revoke_Orphan(t *testing.T) {
}
}

// This was the original function name, and now it just calls
// the non recursive version for a variety of depths.
func TestTokenStore_RevokeTree(t *testing.T) {
_, ts, _, _ := TestCoreWithTokenStore(t)

ent1 := &TokenEntry{}
if err := ts.create(ent1); err != nil {
t.Fatalf("err: %v", err)
}
testTokenStore_RevokeTree_NonRecursive(t, 1)
testTokenStore_RevokeTree_NonRecursive(t, 2)
testTokenStore_RevokeTree_NonRecursive(t, 10)
}

ent2 := &TokenEntry{Parent: ent1.ID}
if err := ts.create(ent2); err != nil {
t.Fatalf("err: %v", err)
}
// Revokes a given Token Store tree non recursively.
// The second parameter refers to the depth of the tree.
func testTokenStore_RevokeTree_NonRecursive(t testing.TB, depth uint64) {
_, ts, _, _ := TestCoreWithTokenStore(t)
root, children := buildTokenTree(t, ts, depth)
err := ts.RevokeTree("")

ent3 := &TokenEntry{Parent: ent2.ID}
if err := ts.create(ent3); err != nil {
if err.Error() != "cannot tree-revoke blank token" {
t.Fatalf("err: %v", err)
}

ent4 := &TokenEntry{Parent: ent2.ID}
if err := ts.create(ent4); err != nil {
t.Fatalf("err: %v", err)
}
// Nuke tree non recursively.
err = ts.RevokeTree(root.ID)

err := ts.RevokeTree("")
if err.Error() != "cannot tree-revoke blank token" {
t.Fatalf("err: %v", err)
}
err = ts.RevokeTree(ent1.ID)
if err != nil {
t.Fatalf("err: %v", err)
}

lookup := []string{ent1.ID, ent2.ID, ent3.ID, ent4.ID}
for _, id := range lookup {
out, err := ts.Lookup(id)
// Append the root to ensure it was successfully
// deleted.
children = append(children, root)
for _, entry := range children {
out, err := ts.Lookup(entry.ID)
if err != nil {
t.Fatalf("err: %v", err)
}
Expand All @@ -814,6 +809,52 @@ func TestTokenStore_RevokeTree(t *testing.T) {
}
}

// A benchmark function that tests testTokenStore_RevokeTree_NonRecursive
// for a variety of different depths.
func BenchmarkTokenStore_RevokeTree(b *testing.B) {
benchmarks := []uint64{0, 1, 2, 4, 8, 16, 20}
for _, depth := range benchmarks {
b.Run(fmt.Sprintf("Tree of Depth %d", depth), func(b *testing.B) {
for i := 0; i < b.N; i++ {
testTokenStore_RevokeTree_NonRecursive(b, depth)
}
})
}
}

// Builds a TokenTree of a specified depth, so that
// we may run revoke tests on it.
func buildTokenTree(t testing.TB, ts *TokenStore, depth uint64) (root *TokenEntry, children []*TokenEntry) {
root = &TokenEntry{}
if err := ts.create(root); err != nil {
t.Fatalf("err: %v", err)
}

frontier := []*TokenEntry{root}
current := uint64(0)
for current < depth {
next := make([]*TokenEntry, 0, 2*len(frontier))
for _, node := range frontier {
left := &TokenEntry{Parent: node.ID}
if err := ts.create(left); err != nil {
t.Fatalf("err: %v", err)
}

right := &TokenEntry{Parent: node.ID}
if err := ts.create(right); err != nil {
t.Fatalf("err: %v", err)
}

children = append(children, left, right)
next = append(next, left, right)
}
frontier = next
current++
}

return root, children
}

func TestTokenStore_RevokeSelf(t *testing.T) {
_, ts, _, _ := TestCoreWithTokenStore(t)

Expand Down