diff --git a/api/ldap/ldap.go b/api/ldap/ldap.go index 523c672cd..e49d7e29b 100644 --- a/api/ldap/ldap.go +++ b/api/ldap/ldap.go @@ -165,6 +165,7 @@ func (*Service) SearchUsers(settings *portainer.LDAPSettings) ([]string, error) // SearchGroups searches for groups with the specified settings func (*Service) SearchGroups(settings *portainer.LDAPSettings) ([]portainer.LDAPUser, error) { + type groupSet map[string]bool connection, err := createConnection(settings) if err != nil { @@ -179,7 +180,7 @@ func (*Service) SearchGroups(settings *portainer.LDAPSettings) ([]portainer.LDAP } } - users := []portainer.LDAPUser{} + userGroups := map[string]groupSet{} for _, searchSettings := range settings.GroupSearchSettings { searchRequest := ldap.NewSearchRequest( @@ -190,25 +191,37 @@ func (*Service) SearchGroups(settings *portainer.LDAPSettings) ([]portainer.LDAP nil, ) - // Deliberately skip errors on the search request so that we can jump to other search settings - // if any issue arise with the current one. sr, err := connection.Search(searchRequest) if err != nil { - return users, err + return nil, err } for _, entry := range sr.Entries { members := entry.GetAttributeValues(searchSettings.GroupAttribute) for _, username := range members { - user := portainer.LDAPUser{ - Name: username, - Group: entry.GetAttributeValue("cn"), + _, ok := userGroups[username] + if !ok { + userGroups[username] = groupSet{} } - users = append(users, user) + userGroups[username][entry.GetAttributeValue("cn")] = true } } } + users := []portainer.LDAPUser{} + + for username, groups := range userGroups { + groupList := []string{} + for group := range groups { + groupList = append(groupList, group) + } + user := portainer.LDAPUser{ + Name: username, + Groups: groupList, + } + users = append(users, user) + } + return users, nil } diff --git a/api/portainer.go b/api/portainer.go index e2eca0d1a..515817d37 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -422,8 +422,8 @@ type ( // LDAPUser represents a LDAP user LDAPUser struct { - Name string - Group string + Name string + Groups []string } // LicenseInfo represents aggregated information about an instance license diff --git a/app/portainer/settings/authentication/ldap/ldap-custom-group-search/ldap-custom-group-search.html b/app/portainer/settings/authentication/ldap/ldap-custom-group-search/ldap-custom-group-search.html index 4473456d8..2423aa316 100644 --- a/app/portainer/settings/authentication/ldap/ldap-custom-group-search/ldap-custom-group-search.html +++ b/app/portainer/settings/authentication/ldap/ldap-custom-group-search/ldap-custom-group-search.html @@ -52,7 +52,7 @@
diff --git a/app/portainer/settings/authentication/ldap/ldap-group-search/ldap-group-search.html b/app/portainer/settings/authentication/ldap/ldap-group-search/ldap-group-search.html index 384f6fe67..1b5840f6d 100644 --- a/app/portainer/settings/authentication/ldap/ldap-group-search/ldap-group-search.html +++ b/app/portainer/settings/authentication/ldap/ldap-group-search/ldap-group-search.html @@ -20,7 +20,7 @@
diff --git a/app/portainer/settings/authentication/ldap/ldap-groups-datatable/ldap-groups-datatable.html b/app/portainer/settings/authentication/ldap/ldap-groups-datatable/ldap-groups-datatable.html index 36ab4a445..061448f70 100644 --- a/app/portainer/settings/authentication/ldap/ldap-groups-datatable/ldap-groups-datatable.html +++ b/app/portainer/settings/authentication/ldap/ldap-groups-datatable/ldap-groups-datatable.html @@ -28,11 +28,7 @@ - - Group Name - - - + Groups @@ -45,7 +41,7 @@ {{ item.Name }} - {{ item.Group }} +

{{ group }}

diff --git a/app/portainer/settings/authentication/ldap/ldap.service.js b/app/portainer/settings/authentication/ldap/ldap.service.js index 4e0de9427..875f83a02 100644 --- a/app/portainer/settings/authentication/ldap/ldap.service.js +++ b/app/portainer/settings/authentication/ldap/ldap.service.js @@ -6,8 +6,17 @@ export function LDAPService(LDAP) { return LDAP.users({ ldapSettings }).$promise; } - function groups(ldapSettings) { - return LDAP.groups({ ldapSettings }).$promise; + async function groups(ldapSettings) { + const userGroups = await LDAP.groups({ ldapSettings }).$promise; + return userGroups.map(({ Name, Groups }) => { + let name = Name; + if (Name.includes(',') && Name.includes('=')) { + const [cnName] = Name.split(','); + const split = cnName.split('='); + name = split[1]; + } + return { Groups, Name: name }; + }); } function check(ldapSettings) {