forked from mystiq/dex
249 lines
6.8 KiB
Go
249 lines
6.8 KiB
Go
|
package ldap_test
|
||
|
|
||
|
import (
|
||
|
"strings"
|
||
|
"testing"
|
||
|
|
||
|
"gopkg.in/asn1-ber.v1"
|
||
|
"gopkg.in/ldap.v2"
|
||
|
)
|
||
|
|
||
|
type compileTest struct {
|
||
|
filterStr string
|
||
|
|
||
|
expectedFilter string
|
||
|
expectedType int
|
||
|
expectedErr string
|
||
|
}
|
||
|
|
||
|
var testFilters = []compileTest{
|
||
|
compileTest{
|
||
|
filterStr: "(&(sn=Miller)(givenName=Bob))",
|
||
|
expectedFilter: "(&(sn=Miller)(givenName=Bob))",
|
||
|
expectedType: ldap.FilterAnd,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: "(|(sn=Miller)(givenName=Bob))",
|
||
|
expectedFilter: "(|(sn=Miller)(givenName=Bob))",
|
||
|
expectedType: ldap.FilterOr,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: "(!(sn=Miller))",
|
||
|
expectedFilter: "(!(sn=Miller))",
|
||
|
expectedType: ldap.FilterNot,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: "(sn=Miller)",
|
||
|
expectedFilter: "(sn=Miller)",
|
||
|
expectedType: ldap.FilterEqualityMatch,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: "(sn=Mill*)",
|
||
|
expectedFilter: "(sn=Mill*)",
|
||
|
expectedType: ldap.FilterSubstrings,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: "(sn=*Mill)",
|
||
|
expectedFilter: "(sn=*Mill)",
|
||
|
expectedType: ldap.FilterSubstrings,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: "(sn=*Mill*)",
|
||
|
expectedFilter: "(sn=*Mill*)",
|
||
|
expectedType: ldap.FilterSubstrings,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: "(sn=*i*le*)",
|
||
|
expectedFilter: "(sn=*i*le*)",
|
||
|
expectedType: ldap.FilterSubstrings,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: "(sn=Mi*l*r)",
|
||
|
expectedFilter: "(sn=Mi*l*r)",
|
||
|
expectedType: ldap.FilterSubstrings,
|
||
|
},
|
||
|
// substring filters escape properly
|
||
|
compileTest{
|
||
|
filterStr: `(sn=Mi*함*r)`,
|
||
|
expectedFilter: `(sn=Mi*\ed\95\a8*r)`,
|
||
|
expectedType: ldap.FilterSubstrings,
|
||
|
},
|
||
|
// already escaped substring filters don't get double-escaped
|
||
|
compileTest{
|
||
|
filterStr: `(sn=Mi*\ed\95\a8*r)`,
|
||
|
expectedFilter: `(sn=Mi*\ed\95\a8*r)`,
|
||
|
expectedType: ldap.FilterSubstrings,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: "(sn=Mi*le*)",
|
||
|
expectedFilter: "(sn=Mi*le*)",
|
||
|
expectedType: ldap.FilterSubstrings,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: "(sn=*i*ler)",
|
||
|
expectedFilter: "(sn=*i*ler)",
|
||
|
expectedType: ldap.FilterSubstrings,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: "(sn>=Miller)",
|
||
|
expectedFilter: "(sn>=Miller)",
|
||
|
expectedType: ldap.FilterGreaterOrEqual,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: "(sn<=Miller)",
|
||
|
expectedFilter: "(sn<=Miller)",
|
||
|
expectedType: ldap.FilterLessOrEqual,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: "(sn=*)",
|
||
|
expectedFilter: "(sn=*)",
|
||
|
expectedType: ldap.FilterPresent,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: "(sn~=Miller)",
|
||
|
expectedFilter: "(sn~=Miller)",
|
||
|
expectedType: ldap.FilterApproxMatch,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: `(objectGUID='\fc\fe\a3\ab\f9\90N\aaGm\d5I~\d12)`,
|
||
|
expectedFilter: `(objectGUID='\fc\fe\a3\ab\f9\90N\aaGm\d5I~\d12)`,
|
||
|
expectedType: ldap.FilterEqualityMatch,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: `(objectGUID=абвгдеёжзийклмнопрстуфхцчшщъыьэюя)`,
|
||
|
expectedFilter: `(objectGUID=\d0\b0\d0\b1\d0\b2\d0\b3\d0\b4\d0\b5\d1\91\d0\b6\d0\b7\d0\b8\d0\b9\d0\ba\d0\bb\d0\bc\d0\bd\d0\be\d0\bf\d1\80\d1\81\d1\82\d1\83\d1\84\d1\85\d1\86\d1\87\d1\88\d1\89\d1\8a\d1\8b\d1\8c\d1\8d\d1\8e\d1\8f)`,
|
||
|
expectedType: ldap.FilterEqualityMatch,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: `(objectGUID=함수목록)`,
|
||
|
expectedFilter: `(objectGUID=\ed\95\a8\ec\88\98\eb\aa\a9\eb\a1\9d)`,
|
||
|
expectedType: ldap.FilterEqualityMatch,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: `(objectGUID=`,
|
||
|
expectedFilter: ``,
|
||
|
expectedType: 0,
|
||
|
expectedErr: "unexpected end of filter",
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: `(objectGUID=함수목록`,
|
||
|
expectedFilter: ``,
|
||
|
expectedType: 0,
|
||
|
expectedErr: "unexpected end of filter",
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: `(&(objectclass=inetorgperson)(cn=中文))`,
|
||
|
expectedFilter: `(&(objectclass=inetorgperson)(cn=\e4\b8\ad\e6\96\87))`,
|
||
|
expectedType: 0,
|
||
|
},
|
||
|
// attr extension
|
||
|
compileTest{
|
||
|
filterStr: `(memberOf:=foo)`,
|
||
|
expectedFilter: `(memberOf:=foo)`,
|
||
|
expectedType: ldap.FilterExtensibleMatch,
|
||
|
},
|
||
|
// attr+named matching rule extension
|
||
|
compileTest{
|
||
|
filterStr: `(memberOf:test:=foo)`,
|
||
|
expectedFilter: `(memberOf:test:=foo)`,
|
||
|
expectedType: ldap.FilterExtensibleMatch,
|
||
|
},
|
||
|
// attr+oid matching rule extension
|
||
|
compileTest{
|
||
|
filterStr: `(cn:1.2.3.4.5:=Fred Flintstone)`,
|
||
|
expectedFilter: `(cn:1.2.3.4.5:=Fred Flintstone)`,
|
||
|
expectedType: ldap.FilterExtensibleMatch,
|
||
|
},
|
||
|
// attr+dn+oid matching rule extension
|
||
|
compileTest{
|
||
|
filterStr: `(sn:dn:2.4.6.8.10:=Barney Rubble)`,
|
||
|
expectedFilter: `(sn:dn:2.4.6.8.10:=Barney Rubble)`,
|
||
|
expectedType: ldap.FilterExtensibleMatch,
|
||
|
},
|
||
|
// attr+dn extension
|
||
|
compileTest{
|
||
|
filterStr: `(o:dn:=Ace Industry)`,
|
||
|
expectedFilter: `(o:dn:=Ace Industry)`,
|
||
|
expectedType: ldap.FilterExtensibleMatch,
|
||
|
},
|
||
|
// dn extension
|
||
|
compileTest{
|
||
|
filterStr: `(:dn:2.4.6.8.10:=Dino)`,
|
||
|
expectedFilter: `(:dn:2.4.6.8.10:=Dino)`,
|
||
|
expectedType: ldap.FilterExtensibleMatch,
|
||
|
},
|
||
|
compileTest{
|
||
|
filterStr: `(memberOf:1.2.840.113556.1.4.1941:=CN=User1,OU=blah,DC=mydomain,DC=net)`,
|
||
|
expectedFilter: `(memberOf:1.2.840.113556.1.4.1941:=CN=User1,OU=blah,DC=mydomain,DC=net)`,
|
||
|
expectedType: ldap.FilterExtensibleMatch,
|
||
|
},
|
||
|
|
||
|
// compileTest{ filterStr: "()", filterType: FilterExtensibleMatch },
|
||
|
}
|
||
|
|
||
|
var testInvalidFilters = []string{
|
||
|
`(objectGUID=\zz)`,
|
||
|
`(objectGUID=\a)`,
|
||
|
}
|
||
|
|
||
|
func TestFilter(t *testing.T) {
|
||
|
// Test Compiler and Decompiler
|
||
|
for _, i := range testFilters {
|
||
|
filter, err := ldap.CompileFilter(i.filterStr)
|
||
|
if err != nil {
|
||
|
if i.expectedErr == "" || !strings.Contains(err.Error(), i.expectedErr) {
|
||
|
t.Errorf("Problem compiling '%s' - '%v' (expected error to contain '%v')", i.filterStr, err, i.expectedErr)
|
||
|
}
|
||
|
} else if filter.Tag != ber.Tag(i.expectedType) {
|
||
|
t.Errorf("%q Expected %q got %q", i.filterStr, ldap.FilterMap[uint64(i.expectedType)], ldap.FilterMap[uint64(filter.Tag)])
|
||
|
} else {
|
||
|
o, err := ldap.DecompileFilter(filter)
|
||
|
if err != nil {
|
||
|
t.Errorf("Problem compiling %s - %s", i.filterStr, err.Error())
|
||
|
} else if i.expectedFilter != o {
|
||
|
t.Errorf("%q expected, got %q", i.expectedFilter, o)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestInvalidFilter(t *testing.T) {
|
||
|
for _, filterStr := range testInvalidFilters {
|
||
|
if _, err := ldap.CompileFilter(filterStr); err == nil {
|
||
|
t.Errorf("Problem compiling %s - expected err", filterStr)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func BenchmarkFilterCompile(b *testing.B) {
|
||
|
b.StopTimer()
|
||
|
filters := make([]string, len(testFilters))
|
||
|
|
||
|
// Test Compiler and Decompiler
|
||
|
for idx, i := range testFilters {
|
||
|
filters[idx] = i.filterStr
|
||
|
}
|
||
|
|
||
|
maxIdx := len(filters)
|
||
|
b.StartTimer()
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
ldap.CompileFilter(filters[i%maxIdx])
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func BenchmarkFilterDecompile(b *testing.B) {
|
||
|
b.StopTimer()
|
||
|
filters := make([]*ber.Packet, len(testFilters))
|
||
|
|
||
|
// Test Compiler and Decompiler
|
||
|
for idx, i := range testFilters {
|
||
|
filters[idx], _ = ldap.CompileFilter(i.filterStr)
|
||
|
}
|
||
|
|
||
|
maxIdx := len(filters)
|
||
|
b.StartTimer()
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
ldap.DecompileFilter(filters[i%maxIdx])
|
||
|
}
|
||
|
}
|