fix: 调整三方同步时分组与成员判断是否存在的依据,改为与ldap一致的DN (#84)

This commit is contained in:
二丫讲梵 2022-07-18 11:38:38 +08:00 committed by GitHub
parent efb2fd9872
commit 2c60a161f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 110 additions and 79 deletions

View File

@ -56,21 +56,20 @@ func (d DingTalkLogic) addDepts(depts []*model.Group) error {
// AddGroup 添加部门数据 // AddGroup 添加部门数据
func (d DingTalkLogic) AddDepts(group *model.Group) error { func (d DingTalkLogic) AddDepts(group *model.Group) error {
// 判断部门名称是否存在
parentGroup := new(model.Group) parentGroup := new(model.Group)
err := isql.Group.Find(tools.H{"source_dept_id": group.SourceDeptParentId}, parentGroup) // 查询当前分组父ID在MySQL中的数据信息 err := isql.Group.Find(tools.H{"source_dept_id": group.SourceDeptParentId}, parentGroup) // 查询当前分组父ID在MySQL中的数据信息
if err != nil { if err != nil {
return tools.NewMySqlError(fmt.Errorf("查询父级部门失败:%s", err.Error())) return tools.NewMySqlError(fmt.Errorf("查询父级部门失败:%s", err.Error()))
} }
if !isql.Group.Exist(tools.H{"source_dept_id": group.SourceDeptId}) { // 判断当前部门是否已落库
// 此时的 group 已经附带了Build后动态关联好的字段接下来将一些确定性的其他字段值添加上就可以创建这个分组了
group.Creator = "system"
group.GroupType = "cn"
group.ParentId = parentGroup.ID
group.Source = config.Conf.DingTalk.Flag
group.GroupDN = fmt.Sprintf("cn=%s,%s", group.GroupName, parentGroup.GroupDN)
fmt.Println(group.GroupName, group.Remark, group.GroupDN)
// 此时的 group 已经附带了Build后动态关联好的字段接下来将一些确定性的其他字段值添加上就可以创建这个分组了
group.Creator = "system"
group.GroupType = "cn"
group.ParentId = parentGroup.ID
group.Source = config.Conf.DingTalk.Flag
group.GroupDN = fmt.Sprintf("cn=%s,%s", group.GroupName, parentGroup.GroupDN)
if !isql.Group.Exist(tools.H{"group_dn": group.GroupDN}) { // 判断当前部门是否已落库
err = CommonAddGroup(group) err = CommonAddGroup(group)
if err != nil { if err != nil {
return tools.NewOperationError(fmt.Errorf("添加部门失败:%s", err.Error())) return tools.NewOperationError(fmt.Errorf("添加部门失败:%s", err.Error()))
@ -130,18 +129,19 @@ func (d DingTalkLogic) SyncDingTalkUsers(c *gin.Context, req interface{}) (data
// AddUser 添加用户数据 // AddUser 添加用户数据
func (d DingTalkLogic) AddUsers(user *model.User) error { func (d DingTalkLogic) AddUsers(user *model.User) error {
// 根据 unionid 查询用户,不存在则创建 // 根据角色id获取角色
if !isql.User.Exist(tools.H{"source_union_id": user.SourceUnionId}) { roles, err := isql.Role.GetRolesByIds([]uint{2}) // 默认添加为普通用户角色
// 根据角色id获取角色 if err != nil {
roles, err := isql.Role.GetRolesByIds([]uint{2}) // 默认添加为普通用户角色 return tools.NewValidatorError(fmt.Errorf("根据角色ID获取角色信息失败:%s", err.Error()))
if err != nil { }
return tools.NewValidatorError(fmt.Errorf("根据角色ID获取角色信息失败:%s", err.Error())) user.Roles = roles
} user.Creator = "system"
user.Creator = "system" user.Source = config.Conf.DingTalk.Flag
user.Roles = roles user.Password = config.Conf.Ldap.UserInitPassword
user.Password = config.Conf.Ldap.UserInitPassword user.UserDN = fmt.Sprintf("uid=%s,%s", user.Username, config.Conf.Ldap.UserDN)
user.Source = config.Conf.DingTalk.Flag
user.UserDN = fmt.Sprintf("uid=%s,%s", user.Username, config.Conf.Ldap.UserDN) // 根据 user_dn 查询用户,不存在则创建
if !isql.User.Exist(tools.H{"user_dn": user.UserDN}) {
// 获取用户将要添加的分组 // 获取用户将要添加的分组
groups, err := isql.Group.GetGroupByIds(tools.StringToSlice(user.DepartmentId, ",")) groups, err := isql.Group.GetGroupByIds(tools.StringToSlice(user.DepartmentId, ","))
if err != nil { if err != nil {
@ -152,6 +152,8 @@ func (d DingTalkLogic) AddUsers(user *model.User) error {
deptTmp = deptTmp + group.GroupName + "," deptTmp = deptTmp + group.GroupName + ","
} }
user.Departments = strings.TrimRight(deptTmp, ",") user.Departments = strings.TrimRight(deptTmp, ",")
// 新增用户
err = CommonAddUser(user, groups) err = CommonAddUser(user, groups)
if err != nil { if err != nil {
return err return err

View File

@ -57,19 +57,21 @@ func (d FeiShuLogic) addDepts(depts []*model.Group) error {
// AddGroup 添加部门数据 // AddGroup 添加部门数据
func (d FeiShuLogic) AddDepts(group *model.Group) error { func (d FeiShuLogic) AddDepts(group *model.Group) error {
// 判断部门名称是否存在 // 查询当前分组父ID在MySQL中的数据信息
parentGroup := new(model.Group) parentGroup := new(model.Group)
err := isql.Group.Find(tools.H{"source_dept_id": group.SourceDeptParentId}, parentGroup) err := isql.Group.Find(tools.H{"source_dept_id": group.SourceDeptParentId}, parentGroup)
if err != nil { if err != nil {
return tools.NewMySqlError(fmt.Errorf("查询父级部门失败:%s", err.Error())) return tools.NewMySqlError(fmt.Errorf("查询父级部门失败:%s", err.Error()))
} }
if !isql.Group.Exist(tools.H{"source_dept_id": group.SourceDeptId}) {
// 此时的 group 已经附带了Build后动态关联好的字段接下来将一些确定性的其他字段值添加上就可以创建这个分组了 // 此时的 group 已经附带了Build后动态关联好的字段接下来将一些确定性的其他字段值添加上就可以创建这个分组了
group.Creator = "system" group.Creator = "system"
group.GroupType = "cn" group.GroupType = "cn"
group.ParentId = parentGroup.ID group.ParentId = parentGroup.ID
group.Source = config.Conf.FeiShu.Flag group.Source = config.Conf.FeiShu.Flag
group.GroupDN = fmt.Sprintf("cn=%s,%s", group.GroupName, parentGroup.GroupDN) group.GroupDN = fmt.Sprintf("cn=%s,%s", group.GroupName, parentGroup.GroupDN)
if !isql.Group.Exist(tools.H{"group_dn": group.GroupDN}) {
err = CommonAddGroup(group) err = CommonAddGroup(group)
if err != nil { if err != nil {
return tools.NewOperationError(fmt.Errorf("添加部门失败:%s", err.Error())) return tools.NewOperationError(fmt.Errorf("添加部门失败:%s", err.Error()))
@ -129,18 +131,19 @@ func (d FeiShuLogic) SyncFeiShuUsers(c *gin.Context, req interface{}) (data inte
// AddUser 添加用户数据 // AddUser 添加用户数据
func (d FeiShuLogic) AddUsers(user *model.User) error { func (d FeiShuLogic) AddUsers(user *model.User) error {
// 根据 unionid 查询用户,不存在则创建 // 根据角色id获取角色
if !isql.User.Exist(tools.H{"source_union_id": user.SourceUnionId}) { roles, err := isql.Role.GetRolesByIds([]uint{2})
// 根据角色id获取角色 if err != nil {
roles, err := isql.Role.GetRolesByIds([]uint{2}) return tools.NewValidatorError(fmt.Errorf("根据角色ID获取角色信息失败:%s", err.Error()))
if err != nil { }
return tools.NewValidatorError(fmt.Errorf("根据角色ID获取角色信息失败:%s", err.Error())) user.Roles = roles
} user.Creator = "system"
user.Creator = "system" user.Source = config.Conf.FeiShu.Flag
user.Roles = roles user.Password = config.Conf.Ldap.UserInitPassword
user.Password = config.Conf.Ldap.UserInitPassword user.UserDN = fmt.Sprintf("uid=%s,%s", user.Username, config.Conf.Ldap.UserDN)
user.Source = config.Conf.FeiShu.Flag
user.UserDN = fmt.Sprintf("uid=%s,%s", user.Username, config.Conf.Ldap.UserDN) // 根据 user_dn 查询用户,不存在则创建
if !isql.User.Exist(tools.H{"user_dn": user.UserDN}) {
// 获取用户将要添加的分组 // 获取用户将要添加的分组
groups, err := isql.Group.GetGroupByIds(tools.StringToSlice(user.DepartmentId, ",")) groups, err := isql.Group.GetGroupByIds(tools.StringToSlice(user.DepartmentId, ","))
if err != nil { if err != nil {
@ -151,6 +154,8 @@ func (d FeiShuLogic) AddUsers(user *model.User) error {
deptTmp = deptTmp + group.GroupName + "," deptTmp = deptTmp + group.GroupName + ","
} }
user.Departments = strings.TrimRight(deptTmp, ",") user.Departments = strings.TrimRight(deptTmp, ",")
// 添加用户
err = CommonAddUser(user, groups) err = CommonAddUser(user, groups)
if err != nil { if err != nil {
return err return err

View File

@ -27,10 +27,6 @@ func (l GroupLogic) Add(c *gin.Context, req interface{}) (data interface{}, rspE
} }
_ = c _ = c
if isql.Group.Exist(tools.H{"group_name": r.GroupName}) {
return nil, tools.NewValidatorError(fmt.Errorf("组名已存在"))
}
// 获取当前用户 // 获取当前用户
ctxUser, err := isql.User.GetCurrentLoginUser(c) ctxUser, err := isql.User.GetCurrentLoginUser(c)
if err != nil { if err != nil {
@ -45,6 +41,7 @@ func (l GroupLogic) Add(c *gin.Context, req interface{}) (data interface{}, rspE
Creator: ctxUser.Username, Creator: ctxUser.Username,
Source: "platform", //默认是平台添加 Source: "platform", //默认是平台添加
} }
if r.ParentId == 0 { if r.ParentId == 0 {
group.SourceDeptId = "platform_0" group.SourceDeptId = "platform_0"
group.SourceDeptParentId = "platform_0" group.SourceDeptParentId = "platform_0"
@ -60,6 +57,11 @@ func (l GroupLogic) Add(c *gin.Context, req interface{}) (data interface{}, rspE
group.GroupDN = fmt.Sprintf("%s=%s,%s", r.GroupType, r.GroupName, parentGroup.GroupDN) group.GroupDN = fmt.Sprintf("%s=%s,%s", r.GroupType, r.GroupName, parentGroup.GroupDN)
} }
// 根据 group_dn 判断分组是否已存在
if isql.Group.Exist(tools.H{"group_dn": group.GroupDN}) {
return nil, tools.NewValidatorError(fmt.Errorf("该分组对应DN已存在"))
}
// 先在ldap中创建组 // 先在ldap中创建组
err = ildap.Group.Add(&group) err = ildap.Group.Add(&group)
if err != nil { if err != nil {

View File

@ -59,19 +59,18 @@ func (d OpenLdapLogic) addDepts(depts []*model.Group) error {
// AddGroup 添加部门数据 // AddGroup 添加部门数据
func (d OpenLdapLogic) AddDepts(group *model.Group) error { func (d OpenLdapLogic) AddDepts(group *model.Group) error {
// 判断部门名称是否存在 // 判断部门名称是否存在,此处使用ldap中的唯一值dn,以免出现数据同步不全的问题
parentGroup := new(model.Group) if !isql.Group.Exist(tools.H{"group_dn": group.GroupDN}) {
err := isql.Group.Find(tools.H{"source_dept_id": group.SourceDeptParentId}, parentGroup)
if err != nil {
return tools.NewMySqlError(fmt.Errorf("查询父级部门失败:%s", err.Error()))
}
if !isql.Group.Exist(tools.H{"source_dept_id": group.SourceDeptId}) {
// 此时的 group 已经附带了Build后动态关联好的字段接下来将一些确定性的其他字段值添加上就可以创建这个分组了 // 此时的 group 已经附带了Build后动态关联好的字段接下来将一些确定性的其他字段值添加上就可以创建这个分组了
group.Creator = "system" group.Creator = "system"
group.GroupType = "cn" group.GroupType = "cn"
group.ParentId = parentGroup.ID parentid, err := d.getParentGroupID(group)
if err != nil {
return err
}
group.ParentId = parentid
group.Source = "openldap" group.Source = "openldap"
err := isql.Group.Add(group) err = isql.Group.Add(group)
if err != nil { if err != nil {
return err return err
} }
@ -80,6 +79,24 @@ func (d OpenLdapLogic) AddDepts(group *model.Group) error {
} }
// AddGroup 添加部门数据
func (d OpenLdapLogic) getParentGroupID(group *model.Group) (id uint, err error) {
switch group.SourceDeptParentId {
case "dingtalkroot":
group.SourceDeptParentId = "dingtalk_1"
case "feishuroot":
group.SourceDeptParentId = "feishu_0"
case "wecomroot":
group.SourceDeptParentId = "wecom_1"
}
parentGroup := new(model.Group)
err = isql.Group.Find(tools.H{"source_dept_id": group.SourceDeptParentId}, parentGroup)
if err != nil {
return id, tools.NewMySqlError(fmt.Errorf("查询父级部门失败:%s,%s", err.Error(), group.GroupName))
}
return parentGroup.ID, nil
}
//根据现有数据库同步到的部门信息,开启用户同步 //根据现有数据库同步到的部门信息,开启用户同步
func (d OpenLdapLogic) SyncOpenLdapUsers(c *gin.Context, req interface{}) (data interface{}, rspError interface{}) { func (d OpenLdapLogic) SyncOpenLdapUsers(c *gin.Context, req interface{}) (data interface{}, rspError interface{}) {
// 1.获取ldap用户列表 // 1.获取ldap用户列表
@ -127,8 +144,8 @@ func (d OpenLdapLogic) SyncOpenLdapUsers(c *gin.Context, req interface{}) (data
// AddUser 添加用户数据 // AddUser 添加用户数据
func (d OpenLdapLogic) AddUsers(user *model.User) error { func (d OpenLdapLogic) AddUsers(user *model.User) error {
// 根据 unionid 查询用户,不存在则创建 // 根据 user_dn 查询用户,不存在则创建
if !isql.User.Exist(tools.H{"source_union_id": user.SourceUnionId}) { if !isql.User.Exist(tools.H{"user_dn": user.UserDN}) {
if user.Departments == "" { if user.Departments == "" {
user.Departments = "默认:研发中心" user.Departments = "默认:研发中心"
} }

View File

@ -6,7 +6,6 @@ import (
"github.com/eryajf/go-ldap-admin/config" "github.com/eryajf/go-ldap-admin/config"
"github.com/eryajf/go-ldap-admin/model" "github.com/eryajf/go-ldap-admin/model"
"github.com/eryajf/go-ldap-admin/model/request"
"github.com/eryajf/go-ldap-admin/public/client/wechat" "github.com/eryajf/go-ldap-admin/public/client/wechat"
"github.com/eryajf/go-ldap-admin/public/tools" "github.com/eryajf/go-ldap-admin/public/tools"
@ -64,13 +63,15 @@ func (d WeComLogic) AddDepts(group *model.Group) error {
if err != nil { if err != nil {
return tools.NewMySqlError(fmt.Errorf("查询父级部门失败:%s", err.Error())) return tools.NewMySqlError(fmt.Errorf("查询父级部门失败:%s", err.Error()))
} }
if !isql.Group.Exist(tools.H{"source_dept_id": group.SourceDeptId}) {
// 此时的 group 已经附带了Build后动态关联好的字段接下来将一些确定性的其他字段值添加上就可以创建这个分组了 // 此时的 group 已经附带了Build后动态关联好的字段接下来将一些确定性的其他字段值添加上就可以创建这个分组了
group.Creator = "system" group.Creator = "system"
group.GroupType = "cn" group.GroupType = "cn"
group.ParentId = parentGroup.ID group.ParentId = parentGroup.ID
group.Source = config.Conf.WeCom.Flag group.Source = config.Conf.WeCom.Flag
group.GroupDN = fmt.Sprintf("cn=%s,%s", group.GroupName, parentGroup.GroupDN) group.GroupDN = fmt.Sprintf("cn=%s,%s", group.GroupName, parentGroup.GroupDN)
if !isql.Group.Exist(tools.H{"group_dn": group.GroupDN}) {
err = CommonAddGroup(group) err = CommonAddGroup(group)
if err != nil { if err != nil {
return tools.NewOperationError(fmt.Errorf("添加部门失败:%s", err.Error())) return tools.NewOperationError(fmt.Errorf("添加部门失败:%s", err.Error()))
@ -100,14 +101,15 @@ func (d WeComLogic) SyncWeComUsers(c *gin.Context, req interface{}) (data interf
} }
// 3.获取企业微信已离职用户id列表 // 3.获取企业微信已离职用户id列表
// 拿到MySQL所有用户数据远程没有的则说明被删除了 // 拿到MySQL所有用户数据(来源为 wecom的用户),远程没有的,则说明被删除了
// 如果以后企业微信透出了已离职用户列表的接口,则这里可以进行改进
var res []*model.User var res []*model.User
users, err := isql.User.List(&request.UserListReq{}) users, err := isql.User.ListAll()
if err != nil { if err != nil {
return nil, tools.NewMySqlError(fmt.Errorf("获取用户列表失败:" + err.Error())) return nil, tools.NewMySqlError(fmt.Errorf("获取用户列表失败:" + err.Error()))
} }
for _, user := range users { for _, user := range users {
if user.Username == "admin" { if user.Source != config.Conf.WeCom.Flag {
continue continue
} }
in := true in := true
@ -144,18 +146,19 @@ func (d WeComLogic) SyncWeComUsers(c *gin.Context, req interface{}) (data interf
// AddUser 添加用户数据 // AddUser 添加用户数据
func (d WeComLogic) AddUsers(user *model.User) error { func (d WeComLogic) AddUsers(user *model.User) error {
// 根据 unionid 查询用户,不存在则创建 // 根据角色id获取角色
if !isql.User.Exist(tools.H{"source_union_id": user.SourceUnionId}) { roles, err := isql.Role.GetRolesByIds([]uint{2})
// 根据角色id获取角色 if err != nil {
roles, err := isql.Role.GetRolesByIds([]uint{2}) return tools.NewValidatorError(fmt.Errorf("根据角色ID获取角色信息失败:%s", err.Error()))
if err != nil { }
return tools.NewValidatorError(fmt.Errorf("根据角色ID获取角色信息失败:%s", err.Error())) user.Creator = "system"
} user.Roles = roles
user.Creator = "system" user.Password = config.Conf.Ldap.UserInitPassword
user.Roles = roles user.Source = config.Conf.WeCom.Flag
user.Password = config.Conf.Ldap.UserInitPassword user.UserDN = fmt.Sprintf("uid=%s,%s", user.Username, config.Conf.Ldap.UserDN)
user.Source = config.Conf.WeCom.Flag
user.UserDN = fmt.Sprintf("uid=%s,%s", user.Username, config.Conf.Ldap.UserDN) // 根据 user_dn 查询用户,不存在则创建
if !isql.User.Exist(tools.H{"user_dn": user.UserDN}) {
// 获取用户将要添加的分组 // 获取用户将要添加的分组
groups, err := isql.Group.GetGroupByIds(tools.StringToSlice(user.DepartmentId, ",")) groups, err := isql.Group.GetGroupByIds(tools.StringToSlice(user.DepartmentId, ","))
if err != nil { if err != nil {
@ -166,6 +169,8 @@ func (d WeComLogic) AddUsers(user *model.User) error {
deptTmp = deptTmp + group.GroupName + "," deptTmp = deptTmp + group.GroupName + ","
} }
user.Departments = strings.TrimRight(deptTmp, ",") user.Departments = strings.TrimRight(deptTmp, ",")
// 创建用户
err = CommonAddUser(user, groups) err = CommonAddUser(user, groups)
if err != nil { if err != nil {
return err return err