123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- package ldap_test
- import (
- "reflect"
- "testing"
- "notabug.org/makenotabuggreatagain/ldap"
- )
- func TestSuccessfulDNParsing(t *testing.T) {
- testcases := map[string]ldap.DN{
- "": ldap.DN{[]*ldap.RelativeDN{}},
- "cn=Jim\\2C \\22Hasse Hö\\22 Hansson!,dc=dummy,dc=com": ldap.DN{[]*ldap.RelativeDN{
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"cn", "Jim, \"Hasse Hö\" Hansson!"}}},
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"dc", "dummy"}}},
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"dc", "com"}}}}},
- "UID=jsmith,DC=example,DC=net": ldap.DN{[]*ldap.RelativeDN{
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"UID", "jsmith"}}},
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"DC", "example"}}},
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"DC", "net"}}}}},
- "OU=Sales+CN=J. Smith,DC=example,DC=net": ldap.DN{[]*ldap.RelativeDN{
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{
- &ldap.AttributeTypeAndValue{"OU", "Sales"},
- &ldap.AttributeTypeAndValue{"CN", "J. Smith"}}},
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"DC", "example"}}},
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"DC", "net"}}}}},
- "1.3.6.1.4.1.1466.0=#04024869": ldap.DN{[]*ldap.RelativeDN{
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"1.3.6.1.4.1.1466.0", "Hi"}}}}},
- "1.3.6.1.4.1.1466.0=#04024869,DC=net": ldap.DN{[]*ldap.RelativeDN{
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"1.3.6.1.4.1.1466.0", "Hi"}}},
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"DC", "net"}}}}},
- "CN=Lu\\C4\\8Di\\C4\\87": ldap.DN{[]*ldap.RelativeDN{
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"CN", "Lučić"}}}}},
- " CN = Lu\\C4\\8Di\\C4\\87 ": ldap.DN{[]*ldap.RelativeDN{
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"CN", "Lučić"}}}}},
- ` A = 1 , B = 2 `: ldap.DN{[]*ldap.RelativeDN{
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"A", "1"}}},
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"B", "2"}}}}},
- ` A = 1 + B = 2 `: ldap.DN{[]*ldap.RelativeDN{
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{
- &ldap.AttributeTypeAndValue{"A", "1"},
- &ldap.AttributeTypeAndValue{"B", "2"}}}}},
- ` \ \ A\ \ = \ \ 1\ \ , \ \ B\ \ = \ \ 2\ \ `: ldap.DN{[]*ldap.RelativeDN{
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{" A ", " 1 "}}},
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{" B ", " 2 "}}}}},
- ` \ \ A\ \ = \ \ 1\ \ + \ \ B\ \ = \ \ 2\ \ `: ldap.DN{[]*ldap.RelativeDN{
- &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{
- &ldap.AttributeTypeAndValue{" A ", " 1 "},
- &ldap.AttributeTypeAndValue{" B ", " 2 "}}}}},
- }
- for test, answer := range testcases {
- dn, err := ldap.ParseDN(test)
- if err != nil {
- t.Errorf(err.Error())
- continue
- }
- if !reflect.DeepEqual(dn, &answer) {
- t.Errorf("Parsed DN %s is not equal to the expected structure", test)
- t.Logf("Expected:")
- for _, rdn := range answer.RDNs {
- for _, attribs := range rdn.Attributes {
- t.Logf("#%v\n", attribs)
- }
- }
- t.Logf("Actual:")
- for _, rdn := range dn.RDNs {
- for _, attribs := range rdn.Attributes {
- t.Logf("#%v\n", attribs)
- }
- }
- }
- }
- }
- func TestErrorDNParsing(t *testing.T) {
- testcases := map[string]string{
- "*": "DN ended with incomplete type, value pair",
- "cn=Jim\\0Test": "failed to decode escaped character: encoding/hex: invalid byte: U+0054 'T'",
- "cn=Jim\\0": "got corrupted escaped character",
- "DC=example,=net": "DN ended with incomplete type, value pair",
- "1=#0402486": "failed to decode BER encoding: encoding/hex: odd length hex string",
- "test,DC=example,DC=com": "incomplete type, value pair",
- "=test,DC=example,DC=com": "incomplete type, value pair",
- }
- for test, answer := range testcases {
- _, err := ldap.ParseDN(test)
- if err == nil {
- t.Errorf("Expected %s to fail parsing but succeeded\n", test)
- } else if err.Error() != answer {
- t.Errorf("Unexpected error on %s:\n%s\nvs.\n%s\n", test, answer, err.Error())
- }
- }
- }
- func TestDNEqual(t *testing.T) {
- testcases := []struct {
- A string
- B string
- Equal bool
- }{
- // Exact match
- {"", "", true},
- {"o=A", "o=A", true},
- {"o=A", "o=B", false},
- {"o=A,o=B", "o=A,o=B", true},
- {"o=A,o=B", "o=A,o=C", false},
- {"o=A+o=B", "o=A+o=B", true},
- {"o=A+o=B", "o=A+o=C", false},
- // Case mismatch in type is ignored
- {"o=A", "O=A", true},
- {"o=A,o=B", "o=A,O=B", true},
- {"o=A+o=B", "o=A+O=B", true},
- // Case mismatch in value is significant
- {"o=a", "O=A", false},
- {"o=a,o=B", "o=A,O=B", false},
- {"o=a+o=B", "o=A+O=B", false},
- // Multi-valued RDN order mismatch is ignored
- {"o=A+o=B", "O=B+o=A", true},
- // Number of RDN attributes is significant
- {"o=A+o=B", "O=B+o=A+O=B", false},
- // Missing values are significant
- {"o=A+o=B", "O=B+o=A+O=C", false}, // missing values matter
- {"o=A+o=B+o=C", "O=B+o=A", false}, // missing values matter
- // Whitespace tests
- // Matching
- {
- "cn=John Doe, ou=People, dc=sun.com",
- "cn=John Doe, ou=People, dc=sun.com",
- true,
- },
- // Difference in leading/trailing chars is ignored
- {
- "cn=John Doe, ou=People, dc=sun.com",
- "cn=John Doe,ou=People,dc=sun.com",
- true,
- },
- // Difference in values is significant
- {
- "cn=John Doe, ou=People, dc=sun.com",
- "cn=John Doe, ou=People, dc=sun.com",
- false,
- },
- }
- for i, tc := range testcases {
- a, err := ldap.ParseDN(tc.A)
- if err != nil {
- t.Errorf("%d: %v", i, err)
- continue
- }
- b, err := ldap.ParseDN(tc.B)
- if err != nil {
- t.Errorf("%d: %v", i, err)
- continue
- }
- if expected, actual := tc.Equal, a.Equal(b); expected != actual {
- t.Errorf("%d: when comparing '%s' and '%s' expected %v, got %v", i, tc.A, tc.B, expected, actual)
- continue
- }
- if expected, actual := tc.Equal, b.Equal(a); expected != actual {
- t.Errorf("%d: when comparing '%s' and '%s' expected %v, got %v", i, tc.A, tc.B, expected, actual)
- continue
- }
- }
- }
- func TestDNAncestor(t *testing.T) {
- testcases := []struct {
- A string
- B string
- Ancestor bool
- }{
- // Exact match returns false
- {"", "", false},
- {"o=A", "o=A", false},
- {"o=A,o=B", "o=A,o=B", false},
- {"o=A+o=B", "o=A+o=B", false},
- // Mismatch
- {"ou=C,ou=B,o=A", "ou=E,ou=D,ou=B,o=A", false},
- // Descendant
- {"ou=C,ou=B,o=A", "ou=E,ou=C,ou=B,o=A", true},
- }
- for i, tc := range testcases {
- a, err := ldap.ParseDN(tc.A)
- if err != nil {
- t.Errorf("%d: %v", i, err)
- continue
- }
- b, err := ldap.ParseDN(tc.B)
- if err != nil {
- t.Errorf("%d: %v", i, err)
- continue
- }
- if expected, actual := tc.Ancestor, a.AncestorOf(b); expected != actual {
- t.Errorf("%d: when comparing '%s' and '%s' expected %v, got %v", i, tc.A, tc.B, expected, actual)
- continue
- }
- }
- }
|