diff --git a/Dockerfile b/Dockerfile index 8d2cc57..d4aa178 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,12 +5,13 @@ FROM golang:1.17.10 AS builder RUN mkdir /app ADD . /app/ WORKDIR /app -RUN go build -o go-ldap-admin . +RUN sed -i 's@localhost:389@openldap:389@g' /app/config.yml \ + && sed -i 's@host: localhost@host: mysql@g' /app/config.yml && go build -o go-ldap-admin . FROM centos:centos7 RUN mkdir /app WORKDIR /app COPY --from=builder /app/ . -RUN chmod +x wait go-ldap-admin docker-start.sh && yum -y install vim net-tools telnet wget curl && yum clean all +RUN chmod +x wait go-ldap-admin && yum -y install vim net-tools telnet wget curl && yum clean all -CMD [ "sh", "-c", "/app/docker-start.sh" ] \ No newline at end of file +CMD ./wait && ./go-ldap-admin \ No newline at end of file diff --git a/docker-start.sh b/docker-start.sh deleted file mode 100644 index a2ce7aa..0000000 --- a/docker-start.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -# 等待依赖项初始化成功 -/app/wait - -# 修改配置文件中的连接地址 -sed -i 's@localhost:389@openldap:389@g' /app/config.yml -sed -i 's@host: localhost@host: mysql@g' /app/config.yml - -# 启动服务 -/app/go-ldap-admin \ No newline at end of file diff --git a/docs/docker-compose/config/config.yml b/docs/docker-compose/config/config.yml deleted file mode 120000 index b70e642..0000000 --- a/docs/docker-compose/config/config.yml +++ /dev/null @@ -1 +0,0 @@ -../../../config.yml \ No newline at end of file diff --git a/docs/docker-compose/docker-compose.yaml b/docs/docker-compose/docker-compose.yaml index b6baf35..dd57f3a 100644 --- a/docs/docker-compose/docker-compose.yaml +++ b/docs/docker-compose/docker-compose.yaml @@ -76,7 +76,7 @@ services: WAIT_HOSTS: mysql:3306, openldap:389 ports: - 8888:8888 - # volumes: # 可按需打开此配置,将配置文件挂载到本地,如果挂载,需要注意修改本地配置中MySQL与ldap的连接信息 + # volumes: # 可按需打开此配置,将配置文件挂载到本地 可在服务运行之后,执行 docker cp go-ldap-admin-server:/app/config.yml ./config 然后再取消改行注释 # - ./config/config.yml:/app/config.yml depends_on: - mysql diff --git a/logic/feishu_logic.go b/logic/feishu_logic.go index e4dafa9..6ca5521 100644 --- a/logic/feishu_logic.go +++ b/logic/feishu_logic.go @@ -27,31 +27,31 @@ func (d *FeiShuLogic) SyncFeiShuDepts(c *gin.Context, req interface{}) (data int if err != nil { return nil, tools.NewOperationError(fmt.Errorf("转换飞书部门数据失败:%s", err.Error())) } - // 2.将部门这个数组进行拆分,一组是父ID为根的,一组是父ID不为根的 - var firstDepts []*model.Group // 父ID为根的部门 - var otherDepts []*model.Group // 父ID不为根的部门 - for _, dept := range depts { - if dept.SourceDeptParentId == fmt.Sprintf("%s_0", config.Conf.FeiShu.Flag) { - firstDepts = append(firstDepts, dept) - } else { - otherDepts = append(otherDepts, dept) - } - } - // 3.先写父ID为根的,再写父ID不为根的 - for _, dept := range firstDepts { - err := d.AddDepts(dept) - if err != nil { - return nil, tools.NewOperationError(fmt.Errorf("SyncFeiShuDepts添加根部门失败:%s", err.Error())) - } - } - for _, dept := range otherDepts { + // 2.将远程数据转换成树 + deptTree := GroupListToTree(fmt.Sprintf("%s_0", config.Conf.FeiShu.Flag), depts) + + // 3.根据树进行创建 + err = d.addDepts(deptTree.Children) + + return nil, err +} + +// 添加部门 +func (d FeiShuLogic) addDepts(depts []*model.Group) error { + for _, dept := range depts { err := d.AddDepts(dept) if err != nil { - return nil, tools.NewOperationError(fmt.Errorf("SyncFeiShuDepts添加其他部门失败:%s", err.Error())) + return tools.NewOperationError(fmt.Errorf("DsyncFeiShuDepts添加部门失败: %s", err.Error())) + } + if len(dept.Children) != 0 { + err = d.addDepts(dept.Children) + if err != nil { + return tools.NewOperationError(fmt.Errorf("DsyncFeiShuDepts添加部门失败: %s", err.Error())) + } } } - return nil, nil + return nil } // AddGroup 添加部门数据 diff --git a/logic/openldap_logic.go b/logic/openldap_logic.go index 507acb3..124038e 100644 --- a/logic/openldap_logic.go +++ b/logic/openldap_logic.go @@ -21,69 +21,63 @@ func (d *OpenLdapLogic) SyncOpenLdapDepts(c *gin.Context, req interface{}) (data if err != nil { return nil, tools.NewOperationError(fmt.Errorf("获取ldap部门列表失败:%s", err.Error())) } - // 2.将部门这个数组进行拆分,一组是父ID为根的,一组是父ID不为根的 - var firstDepts []*openldap.Dept // 父ID为根的部门 - var otherDepts []*openldap.Dept // 父ID不为根的部门 + groups := make([]*model.Group, 0) for _, dept := range depts { - if dept.ParentId == "openldap_0" { - firstDepts = append(firstDepts, dept) - } else { - otherDepts = append(otherDepts, dept) - } - } - // 3.先写父ID为根的,再写父ID不为根的 - for _, dept := range firstDepts { - err := d.AddDepts(&model.Group{ + groups = append(groups, &model.Group{ GroupName: dept.Name, Remark: dept.Remark, - Creator: "system", - GroupType: "cn", SourceDeptId: dept.Id, - Source: "openldap", SourceDeptParentId: dept.ParentId, - ParentId: 0, GroupDN: dept.DN, }) - if err != nil { - return nil, tools.NewOperationError(fmt.Errorf("SyncOpenLdapDepts添加根部门失败:%s", err.Error())) - } } + // 2.将远程数据转换成树 + deptTree := GroupListToTree("0", groups) - for _, dept := range otherDepts { - // 判断部门名称是否存在 - parentGroup := new(model.Group) - err := isql.Group.Find(tools.H{"source_dept_id": dept.ParentId}, parentGroup) + // 3.根据树进行创建 + err = d.addDepts(deptTree.Children) + + return nil, err +} + +// 添加部门 +func (d OpenLdapLogic) addDepts(depts []*model.Group) error { + for _, dept := range depts { + err := d.AddDepts(dept) if err != nil { - return nil, tools.NewMySqlError(fmt.Errorf("查询父级部门失败:%s", err.Error())) + return tools.NewOperationError(fmt.Errorf("DsyncOpenLdapDepts添加部门失败: %s", err.Error())) } - err = d.AddDepts(&model.Group{ - GroupName: dept.Name, - Remark: dept.Remark, - Creator: "system", - GroupType: "cn", - SourceDeptId: dept.Id, - Source: "openldap", - SourceDeptParentId: dept.ParentId, - GroupDN: dept.DN, - ParentId: parentGroup.ID, - }) - if err != nil { - return nil, tools.NewOperationError(fmt.Errorf("SyncOpenLdapDepts添加其他部门失败:%s", err.Error())) + if len(dept.Children) != 0 { + err = d.addDepts(dept.Children) + if err != nil { + return tools.NewOperationError(fmt.Errorf("DsyncOpenLdapDepts添加部门失败: %s", err.Error())) + } } } - return nil, nil + return nil } // AddGroup 添加部门数据 func (d OpenLdapLogic) AddDepts(group *model.Group) error { - // 在数据库中创建组 + // 判断部门名称是否存在 + parentGroup := new(model.Group) + 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.Creator = "system" + group.GroupType = "cn" + group.ParentId = parentGroup.ID + group.Source = "openldap" err := isql.Group.Add(group) if err != nil { return err } } return nil + } //根据现有数据库同步到的部门信息,开启用户同步 diff --git a/logic/wecom_logic.go b/logic/wecom_logic.go index 2d6efc8..226382c 100644 --- a/logic/wecom_logic.go +++ b/logic/wecom_logic.go @@ -28,34 +28,31 @@ func (d *WeComLogic) SyncWeComDepts(c *gin.Context, req interface{}) (data inter if err != nil { return nil, tools.NewOperationError(fmt.Errorf("转换企业微信部门数据失败:%s", err.Error())) } - // 2.将部门这个数组进行拆分,一组是父ID为1的,一组是父ID不为1的 - var firstDepts []*model.Group // 父ID为1的部门 - var otherDepts []*model.Group // 父ID不为1的部门 - for _, dept := range depts { - if dept.SourceDeptId == fmt.Sprintf("%s_1", config.Conf.WeCom.Flag) { // 跳过ID为1的根部门,由系统配置的根部门进行占位 - continue - } - if dept.SourceDeptParentId == fmt.Sprintf("%s_1", config.Conf.WeCom.Flag) { - firstDepts = append(firstDepts, dept) - } else { - otherDepts = append(otherDepts, dept) - } - } - // 3.先写父ID为1的,再写父ID不为1的 - for _, dept := range firstDepts { - err := d.AddDepts(dept) - if err != nil { - return nil, tools.NewOperationError(fmt.Errorf("SyncWeComDepts添加根部门失败:%s", err.Error())) - } - } - for _, dept := range otherDepts { + // 2.将远程数据转换成树 + deptTree := GroupListToTree(fmt.Sprintf("%s_1", config.Conf.WeCom.Flag), depts) + + // 3.根据树进行创建 + err = d.addDepts(deptTree.Children) + + return nil, err +} + +// 添加部门 +func (d WeComLogic) addDepts(depts []*model.Group) error { + for _, dept := range depts { err := d.AddDepts(dept) if err != nil { - return nil, tools.NewOperationError(fmt.Errorf("SyncWeComDepts添加其他部门失败:%s", err.Error())) + return tools.NewOperationError(fmt.Errorf("DsyncWeComDepts添加部门失败: %s", err.Error())) + } + if len(dept.Children) != 0 { + err = d.addDepts(dept.Children) + if err != nil { + return tools.NewOperationError(fmt.Errorf("DsyncWeComDepts添加部门失败: %s", err.Error())) + } } } - return nil, nil + return nil } // AddGroup 添加部门数据 diff --git a/public/client/openldap/openldap.go b/public/client/openldap/openldap.go index b24a2e1..d7d92ab 100644 --- a/public/client/openldap/openldap.go +++ b/public/client/openldap/openldap.go @@ -61,7 +61,7 @@ func GetAllDepts() (ret []*Dept, err error) { ele.Id = strings.Split(strings.Split(v.DN, ",")[0], "=")[1] ele.Remark = v.GetAttributeValue("description") if len(strings.Split(v.DN, ","))-len(strings.Split(config.Conf.Ldap.BaseDN, ",")) == 1 { - ele.ParentId = "openldap_0" + ele.ParentId = "0" } else { ele.ParentId = strings.Split(strings.Split(v.DN, ",")[1], "=")[1] } diff --git a/public/common/init_mysql_data.go b/public/common/init_mysql_data.go index aad3384..33ba6d7 100644 --- a/public/common/init_mysql_data.go +++ b/public/common/init_mysql_data.go @@ -702,35 +702,47 @@ func InitData() { groups := []model.Group{ { Model: gorm.Model{ID: 1}, + GroupName: "root", + Remark: "Base", + Creator: "system", + GroupType: "ou", + ParentId: 0, + SourceDeptId: "0", + Source: "openldap", + SourceDeptParentId: "0", + GroupDN: config.Conf.Ldap.BaseDN, + }, + { + Model: gorm.Model{ID: 2}, GroupName: config.Conf.DingTalk.Flag + "root", Remark: "钉钉根部门", Creator: "system", GroupType: "ou", - ParentId: 0, + ParentId: 1, SourceDeptId: fmt.Sprintf("%s_%d", config.Conf.DingTalk.Flag, 1), Source: config.Conf.DingTalk.Flag, SourceDeptParentId: fmt.Sprintf("%s_%d", config.Conf.DingTalk.Flag, 0), GroupDN: fmt.Sprintf("ou=%s,%s", config.Conf.DingTalk.Flag+"root", config.Conf.Ldap.BaseDN), }, { - Model: gorm.Model{ID: 2}, + Model: gorm.Model{ID: 3}, GroupName: "wecomroot", Remark: "企业微信根部门", Creator: "system", GroupType: "ou", - ParentId: 0, + ParentId: 1, SourceDeptId: fmt.Sprintf("%s_%d", config.Conf.WeCom.Flag, 1), Source: config.Conf.WeCom.Flag, SourceDeptParentId: fmt.Sprintf("%s_%d", config.Conf.WeCom.Flag, 0), GroupDN: fmt.Sprintf("ou=%s,%s", config.Conf.WeCom.Flag+"root", config.Conf.Ldap.BaseDN), }, { - Model: gorm.Model{ID: 3}, + Model: gorm.Model{ID: 4}, GroupName: config.Conf.FeiShu.Flag + "root", Remark: "飞书根部门", Creator: "system", GroupType: "ou", - ParentId: 0, + ParentId: 1, SourceDeptId: fmt.Sprintf("%s_%d", config.Conf.FeiShu.Flag, 0), Source: config.Conf.FeiShu.Flag, SourceDeptParentId: fmt.Sprintf("%s_%d", config.Conf.FeiShu.Flag, 0),