This commit is contained in:
laodaming 2023-11-27 18:34:58 +08:00
parent 3052c5192b
commit dfbc125e69
3 changed files with 65 additions and 60 deletions

View File

@ -46,62 +46,34 @@ type DNItem struct {
} }
func (l *GetLdapOrganizationsLogic) GetLdapOrganizations(req *types.Request, r *http.Request) (resp *basic.Response) { func (l *GetLdapOrganizationsLogic) GetLdapOrganizations(req *types.Request, r *http.Request) (resp *basic.Response) {
if !l.svcCtx.Ldap.VerifyAuthority(r) { if !l.svcCtx.Ldap.VerifyAuthority(r) {
return resp.SetStatusWithMessage(basic.CodeUnAuth, "无权限,请联系管理员开通") return resp.SetStatusWithMessage(basic.CodeUnAuth, "无权限,请联系管理员开通")
} }
//从ldap获取组织架构数据 //查询部门信息
rootCn := strings.Split(l.svcCtx.Config.Ldap.RootDN, ",") organizations, err := l.svcCtx.Ldap.GetOrganizationList(ldap.ScopeWholeSubtree, nil, nil, nil)
if len(rootCn) == 0 {
return resp.SetStatusWithMessage(basic.CodeServiceErr, "root用户DN未设置")
}
peopleDNSlice := strings.Split(l.svcCtx.Config.Ldap.PeopleGroupDN, ",")
if len(peopleDNSlice) <= 1 {
return resp.SetStatusWithMessage(basic.CodeServiceErr, "基础用户组的DN未配置")
}
filter := "(&(objectClass=groupOfUniqueNames)(objectClass=top))"
fields := []string{"businessCategory", "owner", "dn", "uniqueMember"}
searchResult, err := l.svcCtx.Ldap.Search(l.svcCtx.Config.Ldap.BaseDN, ldap.ScopeWholeSubtree, filter, fields, nil)
if err != nil { if err != nil {
return resp.SetStatusWithMessage(basic.CodeServiceErr, "查询失败:"+err.Error()) logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "获取用户所属部门以及负责部门列表失败")
} }
mapDN := make(map[string]*DNItem) mapDN := make(map[string]*DNItem)
sortNum := 0 sortNum := 0
ownerFilterBuilder := strings.Builder{} ownerFilterBuilder := strings.Builder{}
//每个DN存入map //每个DN存入map
ownerDN := "" for _, organization := range organizations {
for _, v := range searchResult.Entries {
sortNum++ sortNum++
memberCount := 0 //成员数 ownerFilterBuilder.WriteString(fmt.Sprintf("(%s)", organization.Owner))
departmentName := "" //部门名称 dnSlice := strings.ReplaceAll(organization.DN, ","+l.svcCtx.Config.Ldap.BaseDN, "") //把最顶级的组织去掉
for _, attr := range v.Attributes {
switch attr.Name {
case "uniqueMember":
memberCount = len(attr.Values)
case "owner":
if len(attr.Values) == 0 {
continue
}
ownerDN = attr.Values[0]
//解析用户DN只需要提取cn
userCn := strings.Split(attr.Values[0], ",")[0]
ownerFilterBuilder.WriteString(fmt.Sprintf("(%s)", userCn))
case "businessCategory":
departmentName = strings.Join(attr.Values, ",")
}
}
dnSlice := strings.ReplaceAll(v.DN, ","+l.svcCtx.Config.Ldap.BaseDN, "") //把最顶级的组织去掉
level := len(strings.Split(dnSlice, ",")) level := len(strings.Split(dnSlice, ","))
data := &DNItem{ data := &DNItem{
OrganizationDN: v.DN, OrganizationDN: organization.DN,
OrganizationName: departmentName, OrganizationName: organization.Name,
Level: level, Level: level,
MemberCount: memberCount, MemberCount: len(organization.Members),
OwnerDN: ownerDN, OwnerDN: organization.Owner,
Sort: sortNum, Sort: sortNum,
Child: make([]*DNItem, 0, 100), Child: make([]*DNItem, 0, 100),
} }
mapDN[v.DN] = data mapDN[organization.DN] = data
} }
ownerFilters := ownerFilterBuilder.String() ownerFilters := ownerFilterBuilder.String()
if ownerFilters != "" { if ownerFilters != "" {

View File

@ -2,7 +2,6 @@ package logic
import ( import (
"context" "context"
"fmt"
"fusenapi/server/ldap-admin/internal/svc" "fusenapi/server/ldap-admin/internal/svc"
"fusenapi/server/ldap-admin/internal/types" "fusenapi/server/ldap-admin/internal/types"
"fusenapi/utils/basic" "fusenapi/utils/basic"
@ -50,33 +49,24 @@ func (l *GetLdapUserInfoLogic) GetLdapUserInfo(req *types.GetLdapUserInfoReq, r
return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error()) return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error())
} }
//属于哪些部门 //属于哪些部门
filterBuilder := strings.Builder{} organizationDNs := make([]string, 0, 20)
for _, v := range user.OrganizationDNList { for _, v := range user.OrganizationDNList {
//提取 ou organizationDNs = append(organizationDNs, v)
filterBuilder.WriteString(fmt.Sprintf("(%s)", strings.Split(v, ",")[0]))
} }
for _, v := range user.ManageOrganizationDNList { for _, v := range user.ManageOrganizationDNList {
//提取 ou organizationDNs = append(organizationDNs, v)
filterBuilder.WriteString(fmt.Sprintf("(%s)", strings.Split(v, ",")[0]))
} }
//存储map //存储map
mapOrganization := make(map[string]string) mapOrganization := make(map[string]string)
if filterBuilder.Len() > 0 { if len(organizationDNs) > 0 {
//查询部门信息 //查询部门信息
filter := "(&(objectClass=groupOfUniqueNames)(objectClass=top)(|" + filterBuilder.String() + "))" organizations, err := l.svcCtx.Ldap.GetOrganizationList(ldap.ScopeWholeSubtree, organizationDNs, nil, nil)
fields := []string{"businessCategory", "dn"}
organizationsResult, err := l.svcCtx.Ldap.Search(l.svcCtx.Config.Ldap.BaseDN, ldap.ScopeWholeSubtree, filter, fields, nil)
if err != nil { if err != nil {
return resp.SetStatusWithMessage(basic.CodeServiceErr, "查询失败:"+err.Error()) logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "获取用户所属部门以及负责部门列表失败")
} }
for _, entry := range organizationsResult.Entries { for _, v := range organizations {
for _, attr := range entry.Attributes { mapOrganization[v.DN] = v.Name
switch attr.Name {
case "businessCategory":
mapOrganization[entry.DN] = strings.Join(attr.Values, ",")
break //结束这层小循环
}
}
} }
} }
belongOrganizationList := make([]string, 0, len(user.OrganizationDNList)) belongOrganizationList := make([]string, 0, len(user.OrganizationDNList))

View File

@ -2,6 +2,7 @@ package ldap_lib
import ( import (
"errors" "errors"
"fmt"
"strings" "strings"
"github.com/go-ldap/ldap/v3" "github.com/go-ldap/ldap/v3"
@ -109,7 +110,49 @@ func (l *Ldap) SearchWithPaging(DN string, scope int, filter string, attr []stri
return l.conn.Search(searchRequest) return l.conn.Search(searchRequest)
} }
//********************************************************************************************* // *********************************************************************************************
// 查询组织列表
type OrganizationInfo struct {
Name string `json:"name"`
DN string `json:"dn"`
Owner string `json:"owner"`
Members []string `json:"members"`
}
func (l *Ldap) GetOrganizationList(scope int, organizationDNs []string, fields []string, control []ldap.Control) ([]OrganizationInfo, error) {
filterBuilder := strings.Builder{}
for _, dn := range organizationDNs {
//提取 ou
filterBuilder.WriteString(fmt.Sprintf("(%s)", strings.Split(dn, ",")[0]))
}
filter := "(&(objectClass=groupOfUniqueNames)(objectClass=top))"
if filterBuilder.Len() > 0 {
filter = "(&(objectClass=groupOfUniqueNames)(objectClass=top)(|" + filterBuilder.String() + "))"
}
organizationsResult, err := l.Search(l.baseDN, scope, filter, fields, nil)
if err != nil {
return nil, err
}
list := make([]OrganizationInfo, 0, len(organizationsResult.Entries))
for _, entry := range organizationsResult.Entries {
data := OrganizationInfo{
DN: entry.DN,
}
for _, attr := range entry.Attributes {
switch attr.Name {
case "businessCategory": //名称
data.Name = strings.Join(attr.Values, ",")
case "owner": //负责人
data.Owner = strings.Join(attr.Values, ",")
case "uniqueMember": //成员
data.Members = attr.Values
}
}
list = append(list, data)
}
return list, nil
}
// AddUserToGroup 添加用户到组织 // AddUserToGroup 添加用户到组织
func (l *Ldap) AddUserToOrganization(organizationDN, userDN string) error { func (l *Ldap) AddUserToOrganization(organizationDN, userDN string) error {