open-vault/vault/policy_store_test.go
Jeff Mitchell 654e7d92ac Properly lowercase policy names. (#3210)
Previously we lowercased names on ingress but not on lookup or delete
which could cause unexpected results. Now, just unilaterally lowercase
policy names on write and delete. On get, to avoid the performance hit
of always lowercasing when not necessary since it's in the critical
path, we have a minor optimization -- we check the LRU first before
normalizing. For tokens, because they're already normalized when adding
policies during creation, this should always work; it might just be
slower for API calls.

Fixes #3187
2017-08-18 19:47:23 -04:00

219 lines
4.5 KiB
Go

package vault
import (
"reflect"
"testing"
"github.com/hashicorp/vault/logical"
)
func mockPolicyStore(t *testing.T) *PolicyStore {
_, barrier, _ := mockBarrier(t)
view := NewBarrierView(barrier, "foo/")
p := NewPolicyStore(view, logical.TestSystemView())
return p
}
func mockPolicyStoreNoCache(t *testing.T) *PolicyStore {
sysView := logical.TestSystemView()
sysView.CachingDisabledVal = true
_, barrier, _ := mockBarrier(t)
view := NewBarrierView(barrier, "foo/")
p := NewPolicyStore(view, sysView)
return p
}
func TestPolicyStore_Root(t *testing.T) {
ps := mockPolicyStore(t)
// Get should return a special policy
p, err := ps.GetPolicy("root")
if err != nil {
t.Fatalf("err: %v", err)
}
if p == nil {
t.Fatalf("bad: %v", p)
}
if p.Name != "root" {
t.Fatalf("bad: %v", p)
}
// Set should fail
err = ps.SetPolicy(p)
if err.Error() != "cannot update root policy" {
t.Fatalf("err: %v", err)
}
// Delete should fail
err = ps.DeletePolicy("root")
if err.Error() != "cannot delete root policy" {
t.Fatalf("err: %v", err)
}
}
func TestPolicyStore_CRUD(t *testing.T) {
ps := mockPolicyStore(t)
testPolicyStore_CRUD(t, ps)
ps = mockPolicyStoreNoCache(t)
testPolicyStore_CRUD(t, ps)
}
func testPolicyStore_CRUD(t *testing.T, ps *PolicyStore) {
// Get should return nothing
p, err := ps.GetPolicy("Dev")
if err != nil {
t.Fatalf("err: %v", err)
}
if p != nil {
t.Fatalf("bad: %v", p)
}
// Delete should be no-op
err = ps.DeletePolicy("deV")
if err != nil {
t.Fatalf("err: %v", err)
}
// List should be blank
out, err := ps.ListPolicies()
if err != nil {
t.Fatalf("err: %v", err)
}
if len(out) != 0 {
t.Fatalf("bad: %v", out)
}
// Set should work
policy, _ := Parse(aclPolicy)
err = ps.SetPolicy(policy)
if err != nil {
t.Fatalf("err: %v", err)
}
// Get should work
p, err = ps.GetPolicy("dEv")
if err != nil {
t.Fatalf("err: %v", err)
}
if !reflect.DeepEqual(p, policy) {
t.Fatalf("bad: %v", p)
}
// List should be one element
out, err = ps.ListPolicies()
if err != nil {
t.Fatalf("err: %v", err)
}
if len(out) != 1 || out[0] != "dev" {
t.Fatalf("bad: %v", out)
}
// Delete should be clear the entry
err = ps.DeletePolicy("Dev")
if err != nil {
t.Fatalf("err: %v", err)
}
// Get should fail
p, err = ps.GetPolicy("deV")
if err != nil {
t.Fatalf("err: %v", err)
}
if p != nil {
t.Fatalf("bad: %v", p)
}
}
// Test predefined policy handling
func TestPolicyStore_Predefined(t *testing.T) {
core, _, _ := TestCoreUnsealed(t)
// Ensure both default policies are created
err := core.setupPolicyStore()
if err != nil {
t.Fatalf("err: %v", err)
}
// List should be two elements
out, err := core.policyStore.ListPolicies()
if err != nil {
t.Fatalf("err: %v", err)
}
// This shouldn't contain response-wrapping since it's non-assignable
if len(out) != 1 || out[0] != "default" {
t.Fatalf("bad: %v", out)
}
pCubby, err := core.policyStore.GetPolicy("response-wrapping")
if err != nil {
t.Fatalf("err: %v", err)
}
if pCubby.Raw != responseWrappingPolicy {
t.Fatalf("bad: expected\n%s\ngot\n%s\n", responseWrappingPolicy, pCubby.Raw)
}
pRoot, err := core.policyStore.GetPolicy("root")
if err != nil {
t.Fatalf("err: %v", err)
}
err = core.policyStore.SetPolicy(pCubby)
if err == nil {
t.Fatalf("expected err setting %s", pCubby.Name)
}
err = core.policyStore.SetPolicy(pRoot)
if err == nil {
t.Fatalf("expected err setting %s", pRoot.Name)
}
err = core.policyStore.DeletePolicy(pCubby.Name)
if err == nil {
t.Fatalf("expected err deleting %s", pCubby.Name)
}
err = core.policyStore.DeletePolicy(pRoot.Name)
if err == nil {
t.Fatalf("expected err deleting %s", pRoot.Name)
}
}
func TestPolicyStore_ACL(t *testing.T) {
ps := mockPolicyStore(t)
policy, _ := Parse(aclPolicy)
err := ps.SetPolicy(policy)
if err != nil {
t.Fatalf("err: %v", err)
}
policy, _ = Parse(aclPolicy2)
err = ps.SetPolicy(policy)
if err != nil {
t.Fatalf("err: %v", err)
}
acl, err := ps.ACL("dev", "ops")
if err != nil {
t.Fatalf("err: %v", err)
}
testLayeredACL(t, acl)
}
func TestPolicyStore_v1Upgrade(t *testing.T) {
ps := mockPolicyStore(t)
// Put a V1 record
raw := `path "foo" { policy = "read" }`
ps.view.Put(&logical.StorageEntry{Key: "old", Value: []byte(raw)})
// Do a read
p, err := ps.GetPolicy("old")
if err != nil {
t.Fatalf("err: %v", err)
}
if p == nil || len(p.Paths) != 1 {
t.Fatalf("bad policy: %#v", p)
}
// Check that glob is enabled
if !p.Paths[0].Glob {
t.Fatalf("should enable glob")
}
}