fix: align directory wildcard matching
This commit is contained in:
@@ -108,22 +108,43 @@ func matchPath(pattern, path string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for i, p := range pp {
|
for i, p := range pp {
|
||||||
if p == "*" {
|
if !matchSegment(p, ps[i]) {
|
||||||
return true
|
|
||||||
}
|
|
||||||
if p == "?" {
|
|
||||||
if ps[i] == "" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if p != ps[i] {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func matchSegment(pattern, value string) bool {
|
||||||
|
p := []rune(pattern)
|
||||||
|
v := []rune(value)
|
||||||
|
dp := make([][]bool, len(p)+1)
|
||||||
|
for i := range dp {
|
||||||
|
dp[i] = make([]bool, len(v)+1)
|
||||||
|
}
|
||||||
|
dp[0][0] = true
|
||||||
|
for i := 1; i <= len(p); i++ {
|
||||||
|
if p[i-1] == '*' {
|
||||||
|
dp[i][0] = dp[i-1][0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 1; i <= len(p); i++ {
|
||||||
|
for j := 1; j <= len(v); j++ {
|
||||||
|
switch p[i-1] {
|
||||||
|
case '*':
|
||||||
|
dp[i][j] = dp[i-1][j] || dp[i][j-1]
|
||||||
|
case '?':
|
||||||
|
dp[i][j] = dp[i-1][j-1]
|
||||||
|
default:
|
||||||
|
dp[i][j] = dp[i-1][j-1] && p[i-1] == v[j-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[len(p)][len(v)]
|
||||||
|
}
|
||||||
|
|
||||||
|
func MatchPath(pattern, path string) bool { return matchPath(pattern, path) }
|
||||||
|
|
||||||
func NewToken() string {
|
func NewToken() string {
|
||||||
b := make([]byte, 32)
|
b := make([]byte, 32)
|
||||||
if _, e := rand.Read(b); e != nil {
|
if _, e := rand.Read(b); e != nil {
|
||||||
|
|||||||
@@ -2,19 +2,52 @@ package auth
|
|||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
func TestParseRules(t *testing.T) {
|
func TestMatchPath(t *testing.T) {
|
||||||
m, err := ParseRules([]string{"::r|admin:secret:rw:private:d"})
|
cases := []struct {
|
||||||
if err != nil {
|
pattern, path string
|
||||||
t.Fatal(err)
|
want bool
|
||||||
|
}{
|
||||||
|
{"test", "test", true},
|
||||||
|
{"test", "test/sub", true},
|
||||||
|
{"test", "testing", false},
|
||||||
|
{"test*", "test2", true},
|
||||||
|
{"test*", "test/sub", true},
|
||||||
|
{"te?t", "test", true},
|
||||||
|
{"te?t", "teat", true},
|
||||||
|
{"te?t", "te", false},
|
||||||
|
{"test/sub", "test/sub/file", true},
|
||||||
|
{"test/sub", "test/other/file", false},
|
||||||
}
|
}
|
||||||
if !m.Guest.Mask.HasRead() || m.Guest.Mask.HasWrite() {
|
for _, tc := range cases {
|
||||||
t.Fatal("guest mask")
|
if got := MatchPath(tc.pattern, tc.path); got != tc.want {
|
||||||
|
t.Errorf("MatchPath(%q,%q)=%v want %v", tc.pattern, tc.path, got, tc.want)
|
||||||
}
|
}
|
||||||
a := m.Accounts["admin"]
|
|
||||||
if a == nil || !a.Mask.HasWrite() || a.Mask.HasDelete() {
|
|
||||||
t.Fatal("admin mask")
|
|
||||||
}
|
}
|
||||||
if got := a.MaskFor("private/x"); !got.HasDelete() {
|
}
|
||||||
t.Fatalf("subrule=%v", got)
|
|
||||||
|
func TestMaskForLongestRule(t *testing.T) {
|
||||||
|
a := &Account{Mask: Read, Rules: []PathRule{
|
||||||
|
{Dir: "team", Mask: Write},
|
||||||
|
{Dir: "team/private", Mask: None},
|
||||||
|
}}
|
||||||
|
if got := a.MaskFor("team/file"); got != Write {
|
||||||
|
t.Fatalf("team/file mask=%d", got)
|
||||||
|
}
|
||||||
|
if got := a.MaskFor("team/private/file"); got != None {
|
||||||
|
t.Fatalf("team/private/file mask=%d", got)
|
||||||
|
}
|
||||||
|
if got := a.MaskFor("other/file"); got != Read {
|
||||||
|
t.Fatalf("other/file mask=%d", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseRulesGuestDefaultAndOverride(t *testing.T) {
|
||||||
|
m, err := ParseRules(nil)
|
||||||
|
if err != nil || m.Guest.Mask != (Read|Write|Delete) {
|
||||||
|
t.Fatalf("unexpected guest default: %#v err=%v", m.Guest, err)
|
||||||
|
}
|
||||||
|
m, err = ParseRules([]string{"::r|demo:pw:rw"})
|
||||||
|
if err != nil || m.Guest.Mask != Read || m.Accounts["demo"].Mask != (Read|Write) {
|
||||||
|
t.Fatalf("unexpected parsed masks: %#v %#v err=%v", m.Guest, m.Accounts["demo"], err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user