2015-09-10 01:58:09 +00:00
|
|
|
package vault
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
"sort"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2015-12-16 17:56:20 +00:00
|
|
|
"github.com/hashicorp/go-uuid"
|
2015-09-10 01:58:09 +00:00
|
|
|
"github.com/hashicorp/vault/logical"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestCubbyholeBackend_RootPaths(t *testing.T) {
|
|
|
|
b := testCubbyholeBackend()
|
|
|
|
root := b.SpecialPaths()
|
|
|
|
if root != nil {
|
|
|
|
t.Fatalf("unexpected: %v", root)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCubbyholeBackend_Write(t *testing.T) {
|
|
|
|
b := testCubbyholeBackend()
|
2016-01-07 15:30:47 +00:00
|
|
|
req := logical.TestRequest(t, logical.UpdateOperation, "foo")
|
2016-01-13 18:40:08 +00:00
|
|
|
clientToken, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-09-10 01:58:09 +00:00
|
|
|
req.ClientToken = clientToken
|
|
|
|
storage := req.Storage
|
|
|
|
req.Data["raw"] = "test"
|
|
|
|
|
|
|
|
resp, err := b.HandleRequest(req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if resp != nil {
|
|
|
|
t.Fatalf("bad: %v", resp)
|
|
|
|
}
|
|
|
|
|
|
|
|
req = logical.TestRequest(t, logical.ReadOperation, "foo")
|
|
|
|
req.Storage = storage
|
|
|
|
req.ClientToken = clientToken
|
|
|
|
_, err = b.HandleRequest(req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCubbyholeBackend_Read(t *testing.T) {
|
|
|
|
b := testCubbyholeBackend()
|
2016-01-07 15:30:47 +00:00
|
|
|
req := logical.TestRequest(t, logical.UpdateOperation, "foo")
|
2015-09-10 01:58:09 +00:00
|
|
|
req.Data["raw"] = "test"
|
|
|
|
storage := req.Storage
|
2016-01-13 18:40:08 +00:00
|
|
|
clientToken, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-09-10 01:58:09 +00:00
|
|
|
req.ClientToken = clientToken
|
|
|
|
|
|
|
|
if _, err := b.HandleRequest(req); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
req = logical.TestRequest(t, logical.ReadOperation, "foo")
|
|
|
|
req.Storage = storage
|
|
|
|
req.ClientToken = clientToken
|
|
|
|
|
|
|
|
resp, err := b.HandleRequest(req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expected := &logical.Response{
|
|
|
|
Data: map[string]interface{}{
|
|
|
|
"raw": "test",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(resp, expected) {
|
|
|
|
t.Fatalf("bad response.\n\nexpected: %#v\n\nGot: %#v", expected, resp)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCubbyholeBackend_Delete(t *testing.T) {
|
|
|
|
b := testCubbyholeBackend()
|
2016-01-07 15:30:47 +00:00
|
|
|
req := logical.TestRequest(t, logical.UpdateOperation, "foo")
|
2015-09-10 01:58:09 +00:00
|
|
|
req.Data["raw"] = "test"
|
|
|
|
storage := req.Storage
|
2016-01-13 18:40:08 +00:00
|
|
|
clientToken, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-09-10 01:58:09 +00:00
|
|
|
req.ClientToken = clientToken
|
|
|
|
|
|
|
|
if _, err := b.HandleRequest(req); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
req = logical.TestRequest(t, logical.DeleteOperation, "foo")
|
|
|
|
req.Storage = storage
|
|
|
|
req.ClientToken = clientToken
|
|
|
|
resp, err := b.HandleRequest(req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if resp != nil {
|
|
|
|
t.Fatalf("bad: %v", resp)
|
|
|
|
}
|
|
|
|
|
|
|
|
req = logical.TestRequest(t, logical.ReadOperation, "foo")
|
|
|
|
req.Storage = storage
|
|
|
|
req.ClientToken = clientToken
|
|
|
|
resp, err = b.HandleRequest(req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if resp != nil {
|
|
|
|
t.Fatalf("bad: %v", resp)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCubbyholeBackend_List(t *testing.T) {
|
|
|
|
b := testCubbyholeBackend()
|
2016-01-07 15:30:47 +00:00
|
|
|
req := logical.TestRequest(t, logical.UpdateOperation, "foo")
|
2016-01-13 18:40:08 +00:00
|
|
|
clientToken, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-09-10 01:58:09 +00:00
|
|
|
req.Data["raw"] = "test"
|
|
|
|
req.ClientToken = clientToken
|
|
|
|
storage := req.Storage
|
|
|
|
|
|
|
|
if _, err := b.HandleRequest(req); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2016-01-07 15:30:47 +00:00
|
|
|
req = logical.TestRequest(t, logical.UpdateOperation, "bar")
|
2015-09-10 01:58:09 +00:00
|
|
|
req.Data["raw"] = "baz"
|
|
|
|
req.ClientToken = clientToken
|
|
|
|
req.Storage = storage
|
|
|
|
|
|
|
|
if _, err := b.HandleRequest(req); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
req = logical.TestRequest(t, logical.ListOperation, "")
|
|
|
|
req.Storage = storage
|
|
|
|
req.ClientToken = clientToken
|
|
|
|
resp, err := b.HandleRequest(req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expKeys := []string{"foo", "bar"}
|
|
|
|
respKeys := resp.Data["keys"].([]string)
|
|
|
|
sort.Strings(expKeys)
|
|
|
|
sort.Strings(respKeys)
|
|
|
|
if !reflect.DeepEqual(respKeys, expKeys) {
|
|
|
|
t.Fatalf("bad response.\n\nexpected: %#v\n\nGot: %#v", expKeys, respKeys)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCubbyholeIsolation(t *testing.T) {
|
|
|
|
b := testCubbyholeBackend()
|
|
|
|
|
2016-01-13 18:40:08 +00:00
|
|
|
clientTokenA, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
clientTokenB, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-09-10 01:58:09 +00:00
|
|
|
var storageA logical.Storage
|
|
|
|
var storageB logical.Storage
|
|
|
|
|
|
|
|
// Populate and test A entries
|
2016-01-07 15:30:47 +00:00
|
|
|
req := logical.TestRequest(t, logical.UpdateOperation, "foo")
|
2015-09-10 01:58:09 +00:00
|
|
|
req.ClientToken = clientTokenA
|
|
|
|
storageA = req.Storage
|
|
|
|
req.Data["raw"] = "test"
|
|
|
|
|
|
|
|
resp, err := b.HandleRequest(req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if resp != nil {
|
|
|
|
t.Fatalf("bad: %v", resp)
|
|
|
|
}
|
|
|
|
|
|
|
|
req = logical.TestRequest(t, logical.ReadOperation, "foo")
|
|
|
|
req.Storage = storageA
|
|
|
|
req.ClientToken = clientTokenA
|
|
|
|
resp, err = b.HandleRequest(req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expected := &logical.Response{
|
|
|
|
Data: map[string]interface{}{
|
|
|
|
"raw": "test",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(resp, expected) {
|
|
|
|
t.Fatalf("bad response.\n\nexpected: %#v\n\nGot: %#v", expected, resp)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Populate and test B entries
|
2016-01-07 15:30:47 +00:00
|
|
|
req = logical.TestRequest(t, logical.UpdateOperation, "bar")
|
2015-09-10 01:58:09 +00:00
|
|
|
req.ClientToken = clientTokenB
|
|
|
|
storageB = req.Storage
|
|
|
|
req.Data["raw"] = "baz"
|
|
|
|
|
|
|
|
resp, err = b.HandleRequest(req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if resp != nil {
|
|
|
|
t.Fatalf("bad: %v", resp)
|
|
|
|
}
|
|
|
|
|
|
|
|
req = logical.TestRequest(t, logical.ReadOperation, "bar")
|
|
|
|
req.Storage = storageB
|
|
|
|
req.ClientToken = clientTokenB
|
|
|
|
resp, err = b.HandleRequest(req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expected = &logical.Response{
|
|
|
|
Data: map[string]interface{}{
|
|
|
|
"raw": "baz",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(resp, expected) {
|
|
|
|
t.Fatalf("bad response.\n\nexpected: %#v\n\nGot: %#v", expected, resp)
|
|
|
|
}
|
|
|
|
|
|
|
|
// We shouldn't be able to read A from B and vice versa
|
|
|
|
req = logical.TestRequest(t, logical.ReadOperation, "foo")
|
|
|
|
req.Storage = storageB
|
|
|
|
req.ClientToken = clientTokenB
|
|
|
|
resp, err = b.HandleRequest(req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if resp != nil {
|
|
|
|
t.Fatalf("err: was able to read from other user's cubbyhole")
|
|
|
|
}
|
|
|
|
|
|
|
|
req = logical.TestRequest(t, logical.ReadOperation, "bar")
|
|
|
|
req.Storage = storageA
|
|
|
|
req.ClientToken = clientTokenA
|
|
|
|
resp, err = b.HandleRequest(req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if resp != nil {
|
|
|
|
t.Fatalf("err: was able to read from other user's cubbyhole")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func testCubbyholeBackend() logical.Backend {
|
|
|
|
b, _ := CubbyholeBackendFactory(&logical.BackendConfig{
|
|
|
|
Logger: nil,
|
|
|
|
System: logical.StaticSystemView{
|
|
|
|
DefaultLeaseTTLVal: time.Hour * 24,
|
|
|
|
MaxLeaseTTLVal: time.Hour * 24 * 30,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
return b
|
|
|
|
}
|