示例#1
0
// ExtractMembers returns the LDAP member entries for a group specified with a ldapGroupUID
func (e *LDAPInterface) ExtractMembers(ldapGroupUID string) ([]*ldap.Entry, error) {
	// get group entry from LDAP
	group, err := e.GroupEntryFor(ldapGroupUID)
	if err != nil {
		return nil, err
	}

	// extract member UIDs from group entry
	var ldapMemberUIDs []string
	for _, attribute := range e.groupMembershipAttributes {
		ldapMemberUIDs = append(ldapMemberUIDs, group.GetAttributeValues(attribute)...)
	}

	members := []*ldap.Entry{}
	// find members on LDAP server or in cache
	for _, ldapMemberUID := range ldapMemberUIDs {
		memberEntry, err := e.userEntryFor(ldapMemberUID)
		if err == nil {
			members = append(members, memberEntry)
			continue
		}

		err = syncerror.NewMemberLookupError(ldapGroupUID, ldapMemberUID, err)
		handled, fatalErr := e.errorHandler.HandleError(err)
		if fatalErr != nil {
			return nil, fatalErr
		}

		if !handled {
			return nil, err
		}

	}
	return members, nil
}
示例#2
0
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:   syncerror.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: "out of scope member lookup suppressed",
			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=other-example,dc=com")},
					},
				),
				"cn=testUser,ou=users,dc=other-example,dc=com",
				ldaputil.NewQueryOutOfBoundsError("cn=testUser,ou=users,dc=other-example,dc=com", "cn=testGroup,ou=groups,dc=example,dc=com"),
			),
			expectedError:   nil,
			expectedMembers: []*ldap.Entry{},
		},
		{
			name: "no such object member lookup error suppressed",
			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=other-example,dc=com")},
					},
				),
				"cn=testUser,ou=users,dc=other-example,dc=com",
				ldaputil.NewNoSuchObjectError("cn=testUser,ou=users,dc=other-example,dc=com"),
			),
			expectedError:   nil,
			expectedMembers: []*ldap.Entry{},
		},
		{
			name: "member not found member lookup error suppressed",
			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=other-example,dc=com")},
					},
				),
				"cn=testUser,ou=users,dc=other-example,dc=com",
				ldaputil.NewEntryNotFoundError("cn=testUser,ou=users,dc=other-example,dc=com", "objectClass=groupOfNames"),
			),
			expectedError:   nil,
			expectedMembers: []*ldap.Entry{},
		},
		{
			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)
		}
	}
}