package logic import ( "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/utils/ldap_lib" "sort" "strings" "context" "fusenapi/server/ldap-admin/internal/svc" "fusenapi/server/ldap-admin/internal/types" "github.com/zeromicro/go-zero/core/logx" ) type GetOrganizationsLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewGetOrganizationsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetOrganizationsLogic { return &GetOrganizationsLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } // 处理进入前逻辑w,r // func (l *GetOrganizationsLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { // } type DNItem struct { Attribute map[string]interface{} `json:"attribute"` DN string `json:"dn"` ParentDN string `json:"parent_dn"` Sort int `json:"sort"` Child []*DNItem `json:"child"` } func (l *GetOrganizationsLogic) GetOrganizations(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) { //从ldap获取组织架构数据 rootCn := strings.Split(l.svcCtx.Config.Ldap.RootDN, ",") if len(rootCn) == 0 { return resp.SetStatusWithMessage(basic.CodeServiceErr, "root用户DN未设置") } ldapServer := ldap_lib.NewLdap(l.svcCtx.Ldap, l.svcCtx.Config.Ldap.BaseDN, l.svcCtx.Config.Ldap.RootDN) filter := "(&(objectClass=*)(!(ou=" + l.svcCtx.Config.Ldap.PeopleGroupOu + "))(!(" + rootCn[0] + ")))" //所有object但是不包括people以及root用户 searchResult, err := ldapServer.Search(l.svcCtx.Config.Ldap.BaseDN, filter, nil, nil) if err != nil { return resp.SetStatusWithMessage(basic.CodeServiceErr, "查询失败:"+err.Error()) } mapDN := make(map[string]*DNItem) sortNum := 0 //每个DN存入map for _, v := range searchResult.Entries { sortNum++ attribute := make(map[string]interface{}) for _, attr := range v.Attributes { switch attr.Name { case "objectClass": //objectcalss属性特别处理 mapObjectClass := make(map[string]struct{}) for _, objectClassItem := range attr.Values { mapObjectClass[objectClassItem] = struct{}{} } attribute[attr.Name] = mapObjectClass case "member": //成员不用变 attribute[attr.Name] = attr.Values default: //普通属性 attribute[attr.Name] = strings.Join(attr.Values, ",") } } mapDN[v.DN] = &DNItem{ DN: v.DN, ParentDN: "", Attribute: attribute, Sort: sortNum, Child: make([]*DNItem, 0, 100), } } //组织树形层级关系 minLevel := 0 for dn, v := range mapDN { sl := strings.Split(dn, ",") lensl := len(sl) if lensl < minLevel || minLevel == 0 { minLevel = lensl } //没有父级 if lensl <= 1 { continue } //有父级 parentDN := strings.Join(sl[1:], ",") if parent, ok := mapDN[parentDN]; ok { v.ParentDN = parentDN parent.Child = append(parent.Child, v) //排序 sort.Slice(parent.Child, func(i, j int) bool { return parent.Child[i].Sort < parent.Child[j].Sort }) } } //只获取最顶层 list := make([]interface{}, 0, len(mapDN)) for dn, v := range mapDN { sl := strings.Split(dn, ",") if len(sl) == minLevel { list = append(list, v) } } return resp.SetStatusWithMessage(basic.CodeOK, "", list) } // 处理逻辑后 w,r 如:重定向, resp 必须重新处理 // func (l *GetOrganizationsLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { // // httpx.OkJsonCtx(r.Context(), w, resp) // }