func TestExtractMembers(t *testing.T) {
	var testCases = []struct {
		name            string
		client          ldap.Client
		expectedError   error
		expectedMembers []*ldap.Entry
	}{
		{
			name: "group lookup errors",
			client: testclient.NewMatchingSearchErrorClient(
				testclient.New(),
				"cn=testGroup,ou=groups,dc=example,dc=com",
				errors.New("generic search error"),
			),
			expectedError:   errors.New("generic search error"),
			expectedMembers: nil,
		},
		{
			name: "member lookup errors",
			// this is a nested test client, the first nest tries to error on the user DN
			// the second nest attempts to give back from the DN mapping
			// the third nest is the default "safe" impl from ldaputil
			client: testclient.NewMatchingSearchErrorClient(
				testclient.NewDNMappingClient(
					testclient.New(),
					map[string][]*ldap.Entry{
						"cn=testGroup,ou=groups,dc=example,dc=com": {newTestGroup("testGroup", "cn=testUser,ou=users,dc=example,dc=com")},
					},
				),
				"cn=testUser,ou=users,dc=example,dc=com",
				errors.New("generic search error"),
			),
			expectedError:   interfaces.NewMemberLookupError("cn=testGroup,ou=groups,dc=example,dc=com", "cn=testUser,ou=users,dc=example,dc=com", errors.New("generic search error")),
			expectedMembers: nil,
		},
		{
			name: "no errors",
			client: testclient.NewDNMappingClient(
				testclient.New(),
				map[string][]*ldap.Entry{
					"cn=testGroup,ou=groups,dc=example,dc=com": {newTestGroup("testGroup", "cn=testUser,ou=users,dc=example,dc=com")},
					"cn=testUser,ou=users,dc=example,dc=com":   {newTestUser("testUser")},
				},
			),
			expectedError:   nil,
			expectedMembers: []*ldap.Entry{newTestUser("testUser")},
		},
	}
	for _, testCase := range testCases {
		ldapInterface := newTestLDAPInterface(testCase.client)
		members, err := ldapInterface.ExtractMembers("cn=testGroup,ou=groups,dc=example,dc=com")
		if !reflect.DeepEqual(err, testCase.expectedError) {
			t.Errorf("%s: incorrect error returned:\n\texpected:\n\t%v\n\tgot:\n\t%v\n", testCase.name, testCase.expectedError, err)
		}
		if !reflect.DeepEqual(members, testCase.expectedMembers) {
			t.Errorf("%s: incorrect members returned:\n\texpected:\n\t%v\n\tgot:\n\t%v\n", testCase.name, testCase.expectedMembers, members)
		}
	}
}
Example #2
0
// TestErrNoSuchObject tests that our LDAP search correctly wraps the LDAP server error
func TestErrNoSuchObject(t *testing.T) {
	var testCases = []struct {
		name          string
		searchRequest *ldap.SearchRequest
		expectedError error
	}{
		{
			name: "valid search",
			searchRequest: &ldap.SearchRequest{
				BaseDN: "uid=john,o=users,dc=example,dc=com",
			},
			expectedError: nil,
		},
		{
			name: "invalid search",
			searchRequest: &ldap.SearchRequest{
				BaseDN: "ou=groups,dc=example,dc=com",
			},
			expectedError: &errNoSuchObject{baseDN: "ou=groups,dc=example,dc=com"},
		},
	}
	for _, testCase := range testCases {
		testClient := testclient.NewMatchingSearchErrorClient(testclient.New(),
			"ou=groups,dc=example,dc=com",
			ldap.NewError(ldap.LDAPResultNoSuchObject, errors.New("")),
		)
		testConfig := testclient.NewConfig(testClient)
		if _, err := QueryForEntries(testConfig, testCase.searchRequest); !reflect.DeepEqual(err, testCase.expectedError) {
			t.Errorf("%s: error did not match:\n\texpected:\n\t%v\n\tgot:\n\t%v", testCase.name, testCase.expectedError, err)
		}
	}
}
Example #3
0
func TestGroupEntryFor(t *testing.T) {
	var testCases = []struct {
		name                string
		cacheSeed           map[string]*ldap.Entry
		queryBaseDNOverride string
		client              ldap.Client
		expectedError       error
		expectedEntry       *ldap.Entry
	}{
		{
			name:          "cached get",
			cacheSeed:     map[string]*ldap.Entry{"cn=testGroup,ou=groups,dc=example,dc=com": newTestGroup("testGroup", "cn=testUser,ou=users,dc=example,dc=com")},
			expectedError: nil,
			expectedEntry: newTestGroup("testGroup", "cn=testUser,ou=users,dc=example,dc=com"),
		},
		{
			name:                "search request failure",
			queryBaseDNOverride: "dc=foo",
			expectedError:       ldaputil.NewQueryOutOfBoundsError("cn=testGroup,ou=groups,dc=example,dc=com", "dc=foo"),
			expectedEntry:       nil,
		},
		{
			name: "query failure",
			client: testclient.NewMatchingSearchErrorClient(
				testclient.New(),
				"cn=testGroup,ou=groups,dc=example,dc=com",
				errors.New("generic search error"),
			),
			expectedError: errors.New("generic search error"),
			expectedEntry: nil,
		},
		{
			name: "no errors",
			client: testclient.NewDNMappingClient(
				testclient.New(),
				map[string][]*ldap.Entry{
					"cn=testGroup,ou=groups,dc=example,dc=com": {newTestGroup("testGroup", "cn=testUser,ou=users,dc=example,dc=com")},
				},
			),
			expectedError: nil,
			expectedEntry: newTestGroup("testGroup", "cn=testUser,ou=users,dc=example,dc=com"),
		},
	}
	for _, testCase := range testCases {
		ldapInterface := newTestLDAPInterface(testCase.client)
		if len(testCase.cacheSeed) > 0 {
			ldapInterface.cachedGroups = testCase.cacheSeed
		}
		if len(testCase.queryBaseDNOverride) > 0 {
			ldapInterface.groupQuery.BaseDN = testCase.queryBaseDNOverride
		}
		entry, err := ldapInterface.GroupEntryFor("cn=testGroup,ou=groups,dc=example,dc=com")
		if !reflect.DeepEqual(err, testCase.expectedError) {
			t.Errorf("%s: incorrect error returned:\n\texpected:\n\t%v\n\tgot:\n\t%v\n", testCase.name, testCase.expectedError, err)
		}
		if !reflect.DeepEqual(entry, testCase.expectedEntry) {
			t.Errorf("%s: incorrect entry returned:\n\texpected:\n\t%v\n\tgot:\n\t%v\n", testCase.name, testCase.expectedEntry, entry)
		}
	}
}
Example #4
0
func TestPopulateCache(t *testing.T) {
	var testCases = []struct {
		name             string
		cacheSeed        map[string][]*ldap.Entry
		searchDNOverride string
		client           ldap.Client
		expectedError    error
		expectedCache    map[string][]*ldap.Entry
	}{
		{
			name: "cache already populated",
			cacheSeed: map[string][]*ldap.Entry{
				"testGroup": {newTestUser("testUser", "testGroup")},
			},
			expectedError: nil,
			expectedCache: map[string][]*ldap.Entry{
				"testGroup": {newTestUser("testUser", "testGroup")},
			},
		},
		{
			name: "user query error",
			client: testclient.NewMatchingSearchErrorClient(
				testclient.New(),
				"ou=users,dc=example,dc=com",
				errors.New("generic search error"),
			),
			expectedError: errors.New("generic search error"),
			expectedCache: make(map[string][]*ldap.Entry), // won't be nil but will be empty
		},
		{
			name: "cache populated correctly",
			client: testclient.NewDNMappingClient(
				testclient.New(),
				map[string][]*ldap.Entry{
					"ou=users,dc=example,dc=com": {newTestUser("testUser", "testGroup")},
				},
			),
			expectedError: nil,
			expectedCache: map[string][]*ldap.Entry{
				"testGroup": {newTestUser("testUser", "testGroup")},
			},
		},
	}
	for _, testCase := range testCases {
		ldapInterface := newTestADLDAPInterface(testCase.client)
		if len(testCase.cacheSeed) > 0 {
			ldapInterface.ldapGroupToLDAPMembers = testCase.cacheSeed
			ldapInterface.cacheFullyPopulated = true
		}
		err := ldapInterface.populateCache()
		if !reflect.DeepEqual(err, testCase.expectedError) {
			t.Errorf("%s: incorrect error returned:\n\texpected:\n\t%v\n\tgot:\n\t%v\n", testCase.name, testCase.expectedError, err)
		}
		if !reflect.DeepEqual(testCase.expectedCache, ldapInterface.ldapGroupToLDAPMembers) {
			t.Errorf("%s: incorrect cache state:\n\texpected:\n\t%v\n\tgot:\n\t%v\n", testCase.name, testCase.expectedCache, ldapInterface.ldapGroupToLDAPMembers)
		}
	}
}
Example #5
0
func TestListGroups(t *testing.T) {
	var testCases = []struct {
		name              string
		client            ldap.Client
		groupUIDAttribute string
		expectedError     error
		expectedGroups    []string
	}{
		{
			name: "query errors",
			client: testclient.NewMatchingSearchErrorClient(
				testclient.New(),
				"ou=groups,dc=example,dc=com",
				errors.New("generic search error"),
			),
			expectedError:  errors.New("generic search error"),
			expectedGroups: nil,
		},
		{
			name: "no UID on entry",
			client: testclient.NewDNMappingClient(
				testclient.New(),
				map[string][]*ldap.Entry{
					"ou=groups,dc=example,dc=com": {newTestGroup("", "cn=testUser,ou=users,dc=example,dc=com")},
				},
			),
			groupUIDAttribute: "cn",
			expectedError:     fmt.Errorf("unable to find LDAP group UID for %s", newTestGroup("", "cn=testUser,ou=users,dc=example,dc=com")),
			expectedGroups:    nil,
		},
		{
			name: "no error",
			client: testclient.NewDNMappingClient(
				testclient.New(),
				map[string][]*ldap.Entry{
					"ou=groups,dc=example,dc=com": {newTestGroup("testGroup", "cn=testUser,ou=users,dc=example,dc=com")},
				},
			),
			expectedError:  nil,
			expectedGroups: []string{"cn=testGroup,ou=groups,dc=example,dc=com"},
		},
	}
	for _, testCase := range testCases {
		ldapInterface := newTestLDAPInterface(testCase.client)
		if len(testCase.groupUIDAttribute) > 0 {
			ldapInterface.groupQuery.QueryAttribute = testCase.groupUIDAttribute
		}
		groupNames, err := ldapInterface.ListGroups()
		if !reflect.DeepEqual(err, testCase.expectedError) {
			t.Errorf("%s: incorrect error returned:\n\texpected:\n\t%v\n\tgot:\n\t%v\n", testCase.name, testCase.expectedError, err)
		}
		if !reflect.DeepEqual(groupNames, testCase.expectedGroups) {
			t.Errorf("%s: incorrect entry returned:\n\texpected:\n\t%v\n\tgot:\n\t%v\n", testCase.name, testCase.expectedGroups, groupNames)
		}
	}
}
Example #6
0
func TestExtractMembers(t *testing.T) {
	// we don't have a test case for an error on a bad search request as search request errors can only occur if
	// the search attribute is the DN, and we do not allow DN to be a group UID for this schema
	var testCases = []struct {
		name            string
		cacheSeed       map[string][]*ldap.Entry
		client          ldap.Client
		expectedError   error
		expectedMembers []*ldap.Entry
	}{
		{
			name: "members cached",
			cacheSeed: map[string][]*ldap.Entry{
				"testGroup": {newTestUser("testUser", "testGroup")},
			},
			expectedError:   nil,
			expectedMembers: []*ldap.Entry{newTestUser("testUser", "testGroup")},
		},
		{
			name: "user query error",
			client: testclient.NewMatchingSearchErrorClient(
				testclient.New(),
				"ou=users,dc=example,dc=com",
				errors.New("generic search error"),
			),
			expectedError:   errors.New("generic search error"),
			expectedMembers: nil,
		},
		{
			name: "no errors",
			client: testclient.NewDNMappingClient(
				testclient.New(),
				map[string][]*ldap.Entry{
					"ou=users,dc=example,dc=com": {newTestUser("testUser", "testGroup")},
				},
			),
			expectedError:   nil,
			expectedMembers: []*ldap.Entry{newTestUser("testUser", "testGroup")},
		},
	}
	for _, testCase := range testCases {
		ldapInterface := newTestADLDAPInterface(testCase.client)
		if len(testCase.cacheSeed) > 0 {
			ldapInterface.ldapGroupToLDAPMembers = testCase.cacheSeed
		}
		members, err := ldapInterface.ExtractMembers("testGroup")
		if !reflect.DeepEqual(err, testCase.expectedError) {
			t.Errorf("%s: incorrect error returned:\n\texpected:\n\t%v\n\tgot:\n\t%v\n", testCase.name, testCase.expectedError, err)
		}
		if !reflect.DeepEqual(members, testCase.expectedMembers) {
			t.Errorf("%s: incorrect members returned:\n\texpected:\n\t%v\n\tgot:\n\t%v\n", testCase.name, testCase.expectedMembers, members)
		}
	}
}