Allowed/Denied parameters support for globs (#2438)
* Add check for globbed strings * Add tests for the acl globbing * Fix bad test case
This commit is contained in:
parent
111fbc5747
commit
e62f5dbc31
|
@ -255,3 +255,22 @@ func StrListDelete(s []string, d string) []string {
|
|||
|
||||
return s
|
||||
}
|
||||
|
||||
func GlobbedStringsMatch(item, val string) bool {
|
||||
if len(item) < 2 {
|
||||
return val == item
|
||||
}
|
||||
|
||||
hasPrefix := strings.HasPrefix(item, "*")
|
||||
hasSuffix := strings.HasSuffix(item, "*")
|
||||
|
||||
if hasPrefix && hasSuffix {
|
||||
return strings.Contains(val, item[1:len(item)-1])
|
||||
} else if hasPrefix {
|
||||
return strings.HasSuffix(val, item[1:])
|
||||
} else if hasSuffix {
|
||||
return strings.HasPrefix(val, item[:len(item)-1])
|
||||
}
|
||||
|
||||
return val == item
|
||||
}
|
||||
|
|
|
@ -279,3 +279,39 @@ $$`,
|
|||
t.Fatalf("bad: expected:\n%#v\nactual:\n%#v", jsonExpected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGlobbedStringsMatch(t *testing.T) {
|
||||
type tCase struct {
|
||||
item string
|
||||
val string
|
||||
expect bool
|
||||
}
|
||||
|
||||
tCases := []tCase{
|
||||
tCase{"", "", true},
|
||||
tCase{"*", "*", true},
|
||||
tCase{"**", "**", true},
|
||||
tCase{"*t", "t", true},
|
||||
tCase{"*t", "test", true},
|
||||
tCase{"t*", "test", true},
|
||||
tCase{"*test", "test", true},
|
||||
tCase{"*test", "a test", true},
|
||||
tCase{"test", "a test", false},
|
||||
tCase{"*test", "tests", false},
|
||||
tCase{"test*", "test", true},
|
||||
tCase{"test*", "testsss", true},
|
||||
tCase{"test**", "testsss", false},
|
||||
tCase{"test**", "test*", true},
|
||||
tCase{"**test", "*test", true},
|
||||
tCase{"TEST", "test", false},
|
||||
tCase{"test", "test", true},
|
||||
}
|
||||
|
||||
for _, tc := range tCases {
|
||||
actual := GlobbedStringsMatch(tc.item, tc.val)
|
||||
|
||||
if actual != tc.expect {
|
||||
t.Fatalf("Bad testcase %#v, expected %b, got %b", tc, tc.expect, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
vault/acl.go
10
vault/acl.go
|
@ -5,6 +5,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/armon/go-radix"
|
||||
"github.com/hashicorp/vault/helper/strutil"
|
||||
"github.com/hashicorp/vault/logical"
|
||||
)
|
||||
|
||||
|
@ -348,7 +349,14 @@ func valueInParameterList(v interface{}, list []interface{}) bool {
|
|||
|
||||
func valueInSlice(v interface{}, list []interface{}) bool {
|
||||
for _, el := range list {
|
||||
if reflect.DeepEqual(el, v) {
|
||||
if reflect.TypeOf(el).String() == "string" && reflect.TypeOf(v).String() == "string" {
|
||||
item := el.(string)
|
||||
val := v.(string)
|
||||
|
||||
if strutil.GlobbedStringsMatch(item, val) {
|
||||
return true
|
||||
}
|
||||
} else if reflect.DeepEqual(el, v) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -366,6 +366,7 @@ func TestACL_ValuePermissions(t *testing.T) {
|
|||
{"dev/ops", []string{"allow"}, []interface{}{"good"}, true},
|
||||
{"dev/ops", []string{"allow"}, []interface{}{"bad"}, false},
|
||||
{"foo/bar", []string{"deny"}, []interface{}{"bad"}, false},
|
||||
{"foo/bar", []string{"deny"}, []interface{}{"bad glob"}, false},
|
||||
{"foo/bar", []string{"deny"}, []interface{}{"good"}, true},
|
||||
{"foo/bar", []string{"allow"}, []interface{}{"good"}, true},
|
||||
{"foo/baz", []string{"aLLow"}, []interface{}{"good"}, true},
|
||||
|
@ -379,6 +380,9 @@ func TestACL_ValuePermissions(t *testing.T) {
|
|||
{"fizz/buzz", []string{"allow_multi"}, []interface{}{"good"}, true},
|
||||
{"fizz/buzz", []string{"allow_multi"}, []interface{}{"good1"}, true},
|
||||
{"fizz/buzz", []string{"allow_multi"}, []interface{}{"good2"}, true},
|
||||
{"fizz/buzz", []string{"allow_multi"}, []interface{}{"glob good2"}, false},
|
||||
{"fizz/buzz", []string{"allow_multi"}, []interface{}{"glob good3"}, true},
|
||||
{"fizz/buzz", []string{"allow_multi"}, []interface{}{"bad"}, false},
|
||||
{"fizz/buzz", []string{"allow_multi"}, []interface{}{"bad"}, false},
|
||||
{"fizz/buzz", []string{"allow_multi", "allow"}, []interface{}{"good1", "good"}, true},
|
||||
{"fizz/buzz", []string{"deny_multi"}, []interface{}{"bad2"}, false},
|
||||
|
@ -686,7 +690,7 @@ path "dev/*" {
|
|||
path "foo/bar" {
|
||||
policy = "write"
|
||||
denied_parameters = {
|
||||
"deny" = ["bad"]
|
||||
"deny" = ["bad*"]
|
||||
}
|
||||
}
|
||||
path "foo/baz" {
|
||||
|
@ -701,7 +705,7 @@ path "foo/baz" {
|
|||
path "fizz/buzz" {
|
||||
policy = "write"
|
||||
allowed_parameters = {
|
||||
"allow_multi" = ["good", "good1", "good2"]
|
||||
"allow_multi" = ["good", "good1", "good2", "*good3"]
|
||||
"allow" = ["good"]
|
||||
}
|
||||
denied_parameters = {
|
||||
|
|
Loading…
Reference in New Issue