diff --git a/admin.go b/admin.go index 5314ea8..04f051e 100644 --- a/admin.go +++ b/admin.go @@ -127,10 +127,12 @@ type AdminLDAPTplData struct { Props map[string]*PropValues CanDelete bool - HasMembers bool - Members []EntryName - HasGroups bool - Groups []EntryName + HasMembers bool + Members []EntryName + PossibleNewMembers []EntryName + HasGroups bool + Groups []EntryName + PossibleNewGroups []EntryName ListMemGro map[string]string @@ -321,6 +323,7 @@ func handleAdminLDAP(w http.ResponseWriter, r *http.Request) { object := sr.Entries[0] + // Read object properties and prepare appropriate form fields props := make(map[string]*PropValues) for _, attr := range object.Attributes { name_lower := strings.ToLower(attr.Name) @@ -355,6 +358,25 @@ func handleAdminLDAP(w http.ResponseWriter, r *http.Request) { } } + // Check objectclass to determine object type + objectClass := []string{} + if val, ok := props["objectclass"]; ok { + objectClass = val.Values + } + hasMembers, hasGroups, isOrganization := false, false, false + for _, oc := range objectClass { + if strings.EqualFold(oc, "organizationalperson") || strings.EqualFold(oc, "person") { + hasGroups = true + } + if strings.EqualFold(oc, "groupOfNames") { + hasMembers = true + } + if strings.EqualFold(oc, "organization") { + isOrganization = true + } + } + + // Parse member list and prepare form section members_dn := []string{} if mp, ok := props["member"]; ok { members_dn = mp.Values @@ -362,31 +384,53 @@ func handleAdminLDAP(w http.ResponseWriter, r *http.Request) { } members := []EntryName{} - mapDnToNameMember := make(map[string]string) - searchRequest = ldap.NewSearchRequest( - config.UserBaseDN, - ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, - fmt.Sprintf("(objectClass=organizationalPerson)"), - []string{"dn", "displayname", "description"}, - nil) - sr, err = login.conn.Search(searchRequest) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - for _, ent := range sr.Entries { - mapDnToNameMember[ent.DN] = ent.GetAttributeValue("displayname") - if mapDnToNameMember[ent.DN] == "" { - mapDnToNameMember[ent.DN] = ent.GetAttributeValue("description") + possibleNewMembers := []EntryName{} + if len(members_dn) > 0 || hasMembers { + // Lookup all existing users in the server + // to know the DN -> display name correspondance + searchRequest = ldap.NewSearchRequest( + config.UserBaseDN, + ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, + fmt.Sprintf("(objectClass=organizationalPerson)"), + []string{"dn", "displayname", "description"}, + nil) + sr, err = login.conn.Search(searchRequest) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + userMap := make(map[string]string) + for _, ent := range sr.Entries { + userMap[ent.DN] = ent.GetAttributeValue("displayname") + if userMap[ent.DN] == "" { + userMap[ent.DN] = ent.GetAttributeValue("description") + } + } + + // Select members with their name and remove them from map + for _, memdn := range members_dn { + members = append(members, EntryName{ + DN: memdn, + Name: userMap[memdn], + }) + delete(userMap, memdn) + } + + // Create list of members that can be added + for dn, name := range userMap { + entry := EntryName{ + DN: dn, + Name: name, + } + if entry.Name == "" { + entry.Name = entry.DN + } + possibleNewMembers = append(possibleNewMembers, entry) } } - for _, memdn := range members_dn { - members = append(members, EntryName{ - DN: memdn, - Name: mapDnToNameMember[memdn], - }) - } + // Parse group list and prepare form section groups_dn := []string{} if gp, ok := props["memberof"]; ok { groups_dn = gp.Values @@ -394,26 +438,50 @@ func handleAdminLDAP(w http.ResponseWriter, r *http.Request) { } groups := []EntryName{} - mapDnToNameGroup := make(map[string]string) - searchRequest = ldap.NewSearchRequest( - config.GroupBaseDN, - ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, - fmt.Sprintf("(objectClass=groupOfNames)"), - []string{"dn", "description"}, - nil) - sr, err = login.conn.Search(searchRequest) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - for _, ent := range sr.Entries { - mapDnToNameGroup[ent.DN] = ent.GetAttributeValue("description") - } - for _, grpdn := range groups_dn { - groups = append(groups, EntryName{ - DN: grpdn, - Name: mapDnToNameGroup[grpdn], - }) + possibleNewGroups := []EntryName{} + if len(groups_dn) > 0 || hasGroups { + // Lookup all existing groups in the server + // to know the DN -> display name correspondance + searchRequest = ldap.NewSearchRequest( + config.GroupBaseDN, + ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, + fmt.Sprintf("(objectClass=groupOfNames)"), + []string{"dn", "description"}, + nil) + sr, err = login.conn.Search(searchRequest) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + groupMap := make(map[string]string) + for _, ent := range sr.Entries { + groupMap[ent.DN] = ent.GetAttributeValue("displayname") + if groupMap[ent.DN] == "" { + groupMap[ent.DN] = ent.GetAttributeValue("description") + } + } + + // Calculate list of current groups + for _, grpdn := range groups_dn { + groups = append(groups, EntryName{ + DN: grpdn, + Name: groupMap[grpdn], + }) + delete(groupMap, grpdn) + } + + // Calculate list of possible new groups + for dn, name := range groupMap { + entry := EntryName{ + DN: dn, + Name: name, + } + if entry.Name == "" { + entry.Name = entry.DN + } + possibleNewGroups = append(possibleNewGroups, entry) + } } // Get children @@ -445,41 +513,7 @@ func handleAdminLDAP(w http.ResponseWriter, r *http.Request) { }) } - // Checkup objectclass - objectClass := []string{} - if val, ok := props["objectclass"]; ok { - objectClass = val.Values - } - hasMembers, hasGroups, isOrganization := false, false, false - for _, oc := range objectClass { - if strings.EqualFold(oc, "organizationalperson") || strings.EqualFold(oc, "person") { - hasGroups = true - } - if strings.EqualFold(oc, "groupOfNames") { - hasMembers = true - } - if strings.EqualFold(oc, "organization") { - isOrganization = true - } - } - - //Get the members or groups existing - var ExistList map[string]string - if hasMembers { - ExistList = mapDnToNameMember - //Suppress the members already in the group - for _, value := range members { - delete(ExistList, value.DN) - } - } else if hasGroups { - ExistList = mapDnToNameGroup - //Delete the groups where the user is already a member - for _, value := range groups { - delete(ExistList, value.DN) - } - } - - + // Run template, finally! templateAdminLDAP.Execute(w, &AdminLDAPTplData{ DN: dn, @@ -489,12 +523,12 @@ func handleAdminLDAP(w http.ResponseWriter, r *http.Request) { CanAddChild: dn_last_attr == "ou" || isOrganization, CanDelete: dn != config.BaseDN && len(children) == 0, - HasMembers: len(members) > 0 || hasMembers, - Members: members, - HasGroups: len(groups) > 0 || hasGroups, - Groups: groups, - - ListMemGro: ExistList, + HasMembers: len(members) > 0 || hasMembers, + Members: members, + PossibleNewMembers: possibleNewMembers, + HasGroups: len(groups) > 0 || hasGroups, + Groups: groups, + PossibleNewGroups: possibleNewGroups, Error: dError, Success: dSuccess, diff --git a/templates/admin_ldap.html b/templates/admin_ldap.html index d1aab29..5867209 100644 --- a/templates/admin_ldap.html +++ b/templates/admin_ldap.html @@ -148,8 +148,8 @@
- {{ range $key, $value := .ListMemGro}} - + {{range .PossibleNewMembers}} + {{end}}
@@ -189,8 +189,8 @@
- {{ range $key, $value := .ListMemGro}} - + {{range .PossibleNewGroups}} + {{end}}