mirror of
https://github.com/casdoor/casdoor.git
synced 2025-09-07 02:20:28 +08:00
feat: add posixAccount and posixGroup filter logic for more versatile usage in LDAP (#4014)
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
@@ -158,6 +159,38 @@ func handleSearch(w ldap.ResponseWriter, m *ldap.Message) {
|
||||
default:
|
||||
}
|
||||
|
||||
var isGroupSearch bool = false
|
||||
filter := r.Filter()
|
||||
if eq, ok := filter.(message.FilterEqualityMatch); ok && strings.EqualFold(string(eq.AttributeDesc()), "objectClass") && strings.EqualFold(string(eq.AssertionValue()), "posixGroup") {
|
||||
isGroupSearch = true
|
||||
}
|
||||
|
||||
if isGroupSearch {
|
||||
groups, code := GetFilteredGroups(m, string(r.BaseObject()), r.FilterString())
|
||||
if code != ldap.LDAPResultSuccess {
|
||||
res.SetResultCode(code)
|
||||
w.Write(res)
|
||||
return
|
||||
}
|
||||
|
||||
for _, group := range groups {
|
||||
dn := fmt.Sprintf("cn=%s,%s", group.Name, string(r.BaseObject()))
|
||||
e := ldap.NewSearchResultEntry(dn)
|
||||
e.AddAttribute("cn", message.AttributeValue(group.Name))
|
||||
gidNumberStr := fmt.Sprintf("%v", hash(group.Name))
|
||||
e.AddAttribute("gidNumber", message.AttributeValue(gidNumberStr))
|
||||
users := object.GetGroupUsersWithoutError(group.GetId())
|
||||
for _, user := range users {
|
||||
e.AddAttribute("memberUid", message.AttributeValue(user.Name))
|
||||
}
|
||||
e.AddAttribute("objectClass", "posixGroup")
|
||||
w.Write(e)
|
||||
}
|
||||
|
||||
w.Write(res)
|
||||
return
|
||||
}
|
||||
|
||||
users, code := GetFilteredUsers(m)
|
||||
if code != ldap.LDAPResultSuccess {
|
||||
res.SetResultCode(code)
|
||||
|
34
ldap/util.go
34
ldap/util.go
@@ -184,6 +184,10 @@ func buildUserFilterCondition(filter interface{}) (builder.Cond, error) {
|
||||
case message.FilterEqualityMatch:
|
||||
attr := string(f.AttributeDesc())
|
||||
|
||||
if strings.EqualFold(attr, "objectclass") && strings.EqualFold(string(f.AssertionValue()), "posixAccount") {
|
||||
return builder.Expr("1 = 1"), nil
|
||||
}
|
||||
|
||||
if attr == ldapMemberOfAttr {
|
||||
var names []string
|
||||
groupId := string(f.AssertionValue())
|
||||
@@ -324,6 +328,36 @@ func GetFilteredUsers(m *ldap.Message) (filteredUsers []*object.User, code int)
|
||||
}
|
||||
}
|
||||
|
||||
func GetFilteredGroups(m *ldap.Message, baseDN string, filterStr string) ([]*object.Group, int) {
|
||||
name, org, code := getNameAndOrgFromFilter(baseDN, filterStr)
|
||||
if code != ldap.LDAPResultSuccess {
|
||||
return nil, code
|
||||
}
|
||||
|
||||
var groups []*object.Group
|
||||
var err error
|
||||
|
||||
if name == "*" {
|
||||
if m.Client.IsGlobalAdmin && org == "*" {
|
||||
groups, err = object.GetGlobalGroups()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else if m.Client.IsGlobalAdmin || org == m.Client.OrgName {
|
||||
groups, err = object.GetGroups(org)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
return nil, ldap.LDAPResultInsufficientAccessRights
|
||||
}
|
||||
} else {
|
||||
return nil, ldap.LDAPResultNoSuchObject
|
||||
}
|
||||
|
||||
return groups, ldap.LDAPResultSuccess
|
||||
}
|
||||
|
||||
// get user password with hash type prefix
|
||||
// TODO not handle salt yet
|
||||
// @return {md5}5f4dcc3b5aa765d61d8327deb882cf99
|
||||
|
Reference in New Issue
Block a user