fusenapi/server/ldap-admin/internal/logic/getldaporganizationmemberslogic.go
laodaming e5a73420b6 fix
2023-11-22 13:07:05 +08:00

143 lines
4.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package logic
import (
"fmt"
"fusenapi/utils/basic"
"github.com/go-ldap/ldap/v3"
"net/http"
"strings"
"context"
"fusenapi/server/ldap-admin/internal/svc"
"fusenapi/server/ldap-admin/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetLdapOrganizationMembersLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetLdapOrganizationMembersLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetLdapOrganizationMembersLogic {
return &GetLdapOrganizationMembersLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
// 处理进入前逻辑w,r
// func (l *GetLdapOrganizationMembersLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
// }
func (l *GetLdapOrganizationMembersLogic) GetLdapOrganizationMembers(req *types.GetLdapOrganizationMembersReq, r *http.Request) (resp *basic.Response) {
if !l.svcCtx.Ldap.VerifyAuthority(r) {
return resp.SetStatusWithMessage(basic.CodeUnAuth, "无权限,请联系管理员开通")
}
req.OrganizationDN = strings.Trim(req.OrganizationDN, " ")
if len(req.OrganizationDN) <= 3 || req.OrganizationDN[:3] != "ou=" {
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "参数错误,无效的组织DN")
}
//先获取组织成员
//获取跟用户dn筛选排除该用户
rootDNSlice := strings.Split(l.svcCtx.Config.Ldap.RootDN, ",")
if len(rootDNSlice) == 0 {
return resp.SetStatusWithMessage(basic.CodeServiceErr, "根用户DN未设置")
}
rootCn := rootDNSlice[0]
filter := "(&(objectClass=groupOfUniqueNames)(!(" + rootCn + ")))"
fields := []string{"uniqueMember"} //只是查询成员
result, err := l.svcCtx.Ldap.Search(req.OrganizationDN, ldap.ScopeWholeSubtree, filter, fields, nil)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "查询ldap组织成员错误,"+err.Error())
}
//遍历成员提取cn用于从用户基础组中获取用户信息列表
filterBuilder := strings.Builder{}
memberCount := 0
memberDNList := make([]string, 0, 100)
if len(result.Entries) == 0 {
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetLdapOrganizationMembersRsp{
List: []types.GetLdapOrganizationMembersItem{},
})
}
teamGroup := result.Entries[0]
if teamGroup.DN != req.OrganizationDN {
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetLdapOrganizationMembersRsp{
List: []types.GetLdapOrganizationMembersItem{},
})
}
//查到用户信息了
for _, attr := range teamGroup.Attributes {
if attr.Name != "uniqueMember" {
continue
}
memberCount = len(attr.Values)
memberDNList = attr.Values
for _, memberDn := range attr.Values {
//不需要根用户
if memberDn == l.svcCtx.Config.Ldap.RootDN {
continue
}
//解析dn成每个小的单元
cellList := strings.Split(memberDn, ",") //取cn邮箱
filterBuilder.WriteString(fmt.Sprintf("(%s)", cellList[0]))
}
break
}
//从新赋值filter
filter = "(&(objectClass=posixAccount)(objectClass=inetOrgPerson)(|" + filterBuilder.String() + "))"
//从用户基本组中找到员工
userList, err := l.svcCtx.Ldap.GetLdapBaseTeamUsersByParams(filter)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "查询ldap帐号信息失败,"+err.Error())
}
list := make([]types.GetLdapOrganizationMembersItem, 0, memberCount)
mapUser := make(map[string]struct{})
for _, user := range userList {
if user.Status != 1 {
//从部门member中移出
if err = l.svcCtx.Ldap.RemoveUserFromOrganization(req.OrganizationDN, user.UserDN); err != nil {
logx.Error("移除用户成员失败:", err)
}
continue
}
mapUser[user.UserDN] = struct{}{}
list = append(list, types.GetLdapOrganizationMembersItem{
UserId: user.UserId,
UserDN: user.UserDN,
UserName: user.UserName,
Email: user.Email,
Mobile: user.Mobile,
Avatar: user.Avatar,
EmployeeType: user.EmployeeType,
Status: user.Status,
})
}
//成员组成员DN数跟查出来的不一致有可能是帐号被物理删除了则也把帐号从组织中移除
if memberCount != len(userList) {
for _, memberDN := range memberDNList {
if _, ok := mapUser[memberDN]; ok {
continue
}
//从组织中移除没有帐号的用户
if err = l.svcCtx.Ldap.RemoveUserFromOrganization(req.OrganizationDN, memberDN); err != nil {
logx.Error("移除用户成员失败!:", err)
}
}
}
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetLdapOrganizationMembersRsp{
List: list,
})
}
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
// func (l *GetLdapOrganizationMembersLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
// // httpx.OkJsonCtx(r.Context(), w, resp)
// }