2015-03-17 22:53:29 +00:00
|
|
|
package vault
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
2016-03-10 18:36:54 +00:00
|
|
|
"strings"
|
2015-03-17 22:53:29 +00:00
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
2016-03-10 18:36:54 +00:00
|
|
|
var rawPolicy = strings.TrimSpace(`
|
|
|
|
# Developer policy
|
|
|
|
name = "dev"
|
|
|
|
|
|
|
|
# Deny all paths by default
|
|
|
|
path "*" {
|
|
|
|
policy = "deny"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Allow full access to staging
|
|
|
|
path "stage/*" {
|
|
|
|
policy = "sudo"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Limited read privilege to production
|
|
|
|
path "prod/version" {
|
|
|
|
policy = "read"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Read access to foobar
|
|
|
|
# Also tests stripping of leading slash
|
|
|
|
path "/foo/bar" {
|
|
|
|
policy = "read"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Add capabilities for creation and sudo to foobar
|
|
|
|
# This will be separate; they are combined when compiled into an ACL
|
|
|
|
path "foo/bar" {
|
|
|
|
capabilities = ["create", "sudo"]
|
|
|
|
}
|
2016-10-28 17:18:31 +00:00
|
|
|
|
2017-01-20 00:40:19 +00:00
|
|
|
# Check that only allowed_parameters are being added to foobar
|
2016-10-28 17:18:31 +00:00
|
|
|
path "foo/bar" {
|
|
|
|
capabilities = ["create", "sudo"]
|
|
|
|
permissions = {
|
2017-01-20 00:40:19 +00:00
|
|
|
allowed_parameters = {
|
2016-12-07 02:14:15 +00:00
|
|
|
"zip" = []
|
|
|
|
"zap" = []
|
2016-10-28 17:18:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-20 00:40:19 +00:00
|
|
|
# Check that only denied_parameters are being added to bazbar
|
2016-10-28 17:18:31 +00:00
|
|
|
path "baz/bar" {
|
|
|
|
capabilities = ["create", "sudo"]
|
|
|
|
permissions = {
|
2017-01-20 00:40:19 +00:00
|
|
|
denied_parameters = {
|
2016-12-07 02:14:15 +00:00
|
|
|
"zip" = []
|
|
|
|
"zap" = []
|
2016-10-28 17:18:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Check that both allowed and denied parameters are being added to bizbar
|
|
|
|
path "biz/bar" {
|
|
|
|
capabilities = ["create", "sudo"]
|
|
|
|
permissions = {
|
2017-01-20 00:40:19 +00:00
|
|
|
allowed_parameters = {
|
2016-12-07 02:14:15 +00:00
|
|
|
"zim" = []
|
|
|
|
"zam" = []
|
2016-10-28 17:18:31 +00:00
|
|
|
}
|
2017-01-20 00:40:19 +00:00
|
|
|
denied_parameters = {
|
2016-12-07 02:14:15 +00:00
|
|
|
"zip" = []
|
|
|
|
"zap" = []
|
2016-10-28 17:18:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-01-20 02:13:39 +00:00
|
|
|
path "test/types" {
|
|
|
|
capabilities = ["create", "sudo"]
|
|
|
|
permissions = {
|
|
|
|
allowed_parameters = {
|
|
|
|
"map" = [{"good" = "one"}]
|
|
|
|
"int" = [1, 2]
|
|
|
|
}
|
|
|
|
denied_parameters = {
|
|
|
|
"string" = ["test"]
|
|
|
|
"bool" = [false]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-03-10 18:36:54 +00:00
|
|
|
`)
|
|
|
|
|
2015-03-17 22:53:29 +00:00
|
|
|
func TestPolicy_Parse(t *testing.T) {
|
|
|
|
p, err := Parse(rawPolicy)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if p.Name != "dev" {
|
2016-03-10 18:36:54 +00:00
|
|
|
t.Fatalf("bad name: %q", p.Name)
|
2015-03-17 22:53:29 +00:00
|
|
|
}
|
|
|
|
|
2016-01-07 20:10:05 +00:00
|
|
|
expect := []*PathCapabilities{
|
|
|
|
&PathCapabilities{"", "deny",
|
|
|
|
[]string{
|
|
|
|
"deny",
|
2017-01-20 02:13:39 +00:00
|
|
|
},
|
|
|
|
&Permissions{CapabilitiesBitmap: DenyCapabilityInt},
|
|
|
|
true,
|
|
|
|
},
|
2016-01-07 20:10:05 +00:00
|
|
|
&PathCapabilities{"stage/", "sudo",
|
|
|
|
[]string{
|
|
|
|
"create",
|
|
|
|
"read",
|
|
|
|
"update",
|
|
|
|
"delete",
|
|
|
|
"list",
|
|
|
|
"sudo",
|
2017-01-20 02:13:39 +00:00
|
|
|
},
|
|
|
|
&Permissions{
|
|
|
|
CapabilitiesBitmap: (CreateCapabilityInt | ReadCapabilityInt | UpdateCapabilityInt | DeleteCapabilityInt | ListCapabilityInt | SudoCapabilityInt),
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
},
|
2016-01-07 20:10:05 +00:00
|
|
|
&PathCapabilities{"prod/version", "read",
|
|
|
|
[]string{
|
|
|
|
"read",
|
|
|
|
"list",
|
2017-01-20 02:13:39 +00:00
|
|
|
},
|
|
|
|
&Permissions{CapabilitiesBitmap: (ReadCapabilityInt | ListCapabilityInt)},
|
|
|
|
false,
|
|
|
|
},
|
2016-01-07 20:10:05 +00:00
|
|
|
&PathCapabilities{"foo/bar", "read",
|
|
|
|
[]string{
|
|
|
|
"read",
|
|
|
|
"list",
|
2017-01-20 02:13:39 +00:00
|
|
|
},
|
|
|
|
&Permissions{CapabilitiesBitmap: (ReadCapabilityInt | ListCapabilityInt)},
|
|
|
|
false,
|
|
|
|
},
|
2016-01-07 20:10:05 +00:00
|
|
|
&PathCapabilities{"foo/bar", "",
|
|
|
|
[]string{
|
|
|
|
"create",
|
|
|
|
"sudo",
|
2017-01-20 02:13:39 +00:00
|
|
|
},
|
|
|
|
&Permissions{CapabilitiesBitmap: (CreateCapabilityInt | SudoCapabilityInt)},
|
|
|
|
false,
|
|
|
|
},
|
2016-10-28 17:18:31 +00:00
|
|
|
&PathCapabilities{"foo/bar", "",
|
|
|
|
[]string{
|
|
|
|
"create",
|
|
|
|
"sudo",
|
2017-01-20 02:13:39 +00:00
|
|
|
},
|
|
|
|
&Permissions{
|
|
|
|
CapabilitiesBitmap: (CreateCapabilityInt | SudoCapabilityInt),
|
|
|
|
AllowedParameters: map[string][]interface{}{"zip": {}, "zap": {}},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2016-10-28 17:18:31 +00:00
|
|
|
&PathCapabilities{"baz/bar", "",
|
|
|
|
[]string{
|
|
|
|
"create",
|
|
|
|
"sudo",
|
2017-01-20 02:13:39 +00:00
|
|
|
},
|
|
|
|
&Permissions{
|
|
|
|
CapabilitiesBitmap: (CreateCapabilityInt | SudoCapabilityInt),
|
|
|
|
DeniedParameters: map[string][]interface{}{"zip": []interface{}{}, "zap": []interface{}{}},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2016-10-28 17:18:31 +00:00
|
|
|
&PathCapabilities{"biz/bar", "",
|
|
|
|
[]string{
|
|
|
|
"create",
|
|
|
|
"sudo",
|
2017-01-20 02:13:39 +00:00
|
|
|
},
|
|
|
|
&Permissions{
|
|
|
|
CapabilitiesBitmap: (CreateCapabilityInt | SudoCapabilityInt),
|
|
|
|
AllowedParameters: map[string][]interface{}{"zim": {}, "zam": {}},
|
|
|
|
DeniedParameters: map[string][]interface{}{"zip": {}, "zap": {}},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
&PathCapabilities{"test/types", "",
|
|
|
|
[]string{
|
|
|
|
"create",
|
|
|
|
"sudo",
|
|
|
|
},
|
|
|
|
&Permissions{
|
|
|
|
CapabilitiesBitmap: (CreateCapabilityInt | SudoCapabilityInt),
|
|
|
|
AllowedParameters: map[string][]interface{}{"map": []interface{}{map[string]interface{}{"good": "one"}}, "int": []interface{}{1, 2}},
|
|
|
|
DeniedParameters: map[string][]interface{}{"string": []interface{}{"test"}, "bool": []interface{}{false}},
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
2015-03-17 22:53:29 +00:00
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(p.Paths, expect) {
|
2016-03-10 18:36:54 +00:00
|
|
|
t.Errorf("expected \n\n%#v\n\n to be \n\n%#v\n\n", p.Paths, expect)
|
2015-03-17 22:53:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-10 18:36:54 +00:00
|
|
|
func TestPolicy_ParseBadRoot(t *testing.T) {
|
|
|
|
_, err := Parse(strings.TrimSpace(`
|
|
|
|
name = "test"
|
|
|
|
bad = "foo"
|
|
|
|
nope = "yes"
|
|
|
|
`))
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("expected error")
|
|
|
|
}
|
2015-03-17 22:53:29 +00:00
|
|
|
|
2016-03-10 18:36:54 +00:00
|
|
|
if !strings.Contains(err.Error(), "invalid key 'bad' on line 2") {
|
|
|
|
t.Errorf("bad error: %q", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !strings.Contains(err.Error(), "invalid key 'nope' on line 3") {
|
|
|
|
t.Errorf("bad error: %q", err)
|
|
|
|
}
|
2015-03-17 22:53:29 +00:00
|
|
|
}
|
|
|
|
|
2016-03-10 18:36:54 +00:00
|
|
|
func TestPolicy_ParseBadPath(t *testing.T) {
|
|
|
|
_, err := Parse(strings.TrimSpace(`
|
|
|
|
path "/" {
|
|
|
|
capabilities = ["read"]
|
|
|
|
capabilites = ["read"]
|
2015-03-17 22:53:29 +00:00
|
|
|
}
|
2016-03-10 18:36:54 +00:00
|
|
|
`))
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("expected error")
|
|
|
|
}
|
2015-03-17 22:53:29 +00:00
|
|
|
|
2016-03-10 18:36:54 +00:00
|
|
|
if !strings.Contains(err.Error(), "invalid key 'capabilites' on line 3") {
|
|
|
|
t.Errorf("bad error: %s", err)
|
|
|
|
}
|
2015-03-17 22:53:29 +00:00
|
|
|
}
|
2016-01-07 20:10:05 +00:00
|
|
|
|
2016-03-10 18:36:54 +00:00
|
|
|
func TestPolicy_ParseBadPolicy(t *testing.T) {
|
|
|
|
_, err := Parse(strings.TrimSpace(`
|
|
|
|
path "/" {
|
|
|
|
policy = "banana"
|
2016-01-07 20:10:05 +00:00
|
|
|
}
|
2016-03-10 18:36:54 +00:00
|
|
|
`))
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("expected error")
|
|
|
|
}
|
2016-01-07 20:10:05 +00:00
|
|
|
|
2016-03-10 18:36:54 +00:00
|
|
|
if !strings.Contains(err.Error(), `path "/": invalid policy 'banana'`) {
|
|
|
|
t.Errorf("bad error: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPolicy_ParseBadCapabilities(t *testing.T) {
|
|
|
|
_, err := Parse(strings.TrimSpace(`
|
|
|
|
path "/" {
|
|
|
|
capabilities = ["read", "banana"]
|
|
|
|
}
|
|
|
|
`))
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("expected error")
|
|
|
|
}
|
|
|
|
|
|
|
|
if !strings.Contains(err.Error(), `path "/": invalid capability 'banana'`) {
|
|
|
|
t.Errorf("bad error: %s", err)
|
|
|
|
}
|
2016-01-07 20:10:05 +00:00
|
|
|
}
|