diff --git a/.github/pull-request-template.md b/.github/pull-request-template.md
index 6ed8154..6f52f56 100644
--- a/.github/pull-request-template.md
+++ b/.github/pull-request-template.md
@@ -2,12 +2,12 @@
**在提出此拉取请求时,我确认了以下几点(请复选框):**
-- [ ] 我已阅读并理解[贡献者指南]()。
+- [ ] 我已阅读并理解[贡献者指南](https://github.com/eryajf/go-ldap-admin/blob/main/CONTRIBUTING.md)。
- [ ] 我已检查没有与此请求重复的拉取请求。
- [ ] 我已经考虑过,并确认这份呈件对其他人很有价值。
- [ ] 我接受此提交可能不会被使用,并根据维护人员的意愿关闭拉取请求。
-**填写PR内容:**
+**填写 PR 内容:**
-
--
\ No newline at end of file
+-
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..e31f79a
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,11 @@
+# 贡献者指南
+
+欢迎反馈、bug 报告和拉取请求,可点击[issue](https://github.com/eryajf/go-ldap-admin/issues) 提交.
+
+如果你是第一次进行 GitHub 协作,可参阅: [协同开发流程](https://howtosos.eryajf.net/HowToStartOpenSource/01-basic-content/03-collaborative-development-process.html)
+
+1. 项目使用`golangci-lint`进行检测,提交 pr 之前请在本地执行 `make lint` 并通过。
+
+2. 如非必要,尽可能谨慎新增配置文件,以免造成升级时产生意料之外的问题。
+
+3. 注意一些功能调整,如何涉及到前端页面调整,尽可能两个 pr 有所关联,否则不好合并。
diff --git a/README.md b/README.md
index a11b141..22db9ff 100644
--- a/README.md
+++ b/README.md
@@ -15,10 +15,9 @@
-
-
+
@@ -42,31 +41,31 @@
`go-ldap-admin`旨在为`OpenLDAP`服务端提供一个简单易用,清晰美观的现代化管理后台。
-> 在完成针对`OpenLDAP`的管理能力之下,支持对`钉钉`,`企业微信`,`飞书`的集成,用户可以选择手动或者自动同步组织架构以及员工信息到平台中,让`go-ldap-admin`项目成为打通企业IM与企业内网应用之间的桥梁。
+> 在完成针对`OpenLDAP`的管理能力之下,支持对`钉钉`,`企业微信`,`飞书`的集成,用户可以选择手动或者自动同步组织架构以及员工信息到平台中,让`go-ldap-admin`项目成为打通企业 IM 与企业内网应用之间的桥梁。
## 🏊 在线体验
提供在线体验地址如下:
-| 分类 | 地址 | 用户名 | 密码 |
-| :-----------: | :----------------------------------------------------------: | :-----------------------: | ------ |
-| go-ldap-admin | [http://demo-go-ldap-admin.eryajf.net](http://demo-go-ldap-admin.eryajf.net) | admin | 123456 |
+| 分类 | 地址 | 用户名 | 密码 |
+| :-----------: | :--------------------------------------------------------------------------------------: | :-----------------------: | ------ |
+| go-ldap-admin | [http://demo-go-ldap-admin.eryajf.net](http://demo-go-ldap-admin.eryajf.net) | admin | 123456 |
| phpLdapAdmin | [http://demo-go-ldap-admin.eryajf.net:8091/](http://demo-go-ldap-admin.eryajf.net:8091/) | cn=admin,dc=eryajf,dc=net | 123456 |
在线环境可能不稳,如果遇到访问异常,或者数据错乱,请联系我进行修复。
**页面功能概览:**
-|  |  |
-| :----------------------------------------------------------: | ------------------------------------------------------------ |
-|  |  |
-|  |  |
-|  |  |
+|  |  |
+| :----------------------------------------------------------------------------------: | -------------------------------------------------------------------------------- |
+|  |  |
+|  |  |
+|  |  |
## 👨💻 项目地址
-| 分类 | GitHub | Gitee |
-| :--: | :--------------------------------------------------: | :-------------------------------------------------: |
+| 分类 | GitHub | Gitee |
+| :--: | :--------------------------------------------: | :-------------------------------------------------: |
| 后端 | https://github.com/eryajf/go-ldap-admin.git | https://gitee.com/eryajf-world/go-ldap-admin.git |
| 前端 | https://github.com/eryajf/go-ldap-admin-ui.git | https://gitee.com/eryajf-world/go-ldap-admin-ui.git |
@@ -83,7 +82,7 @@
## 🥰 感谢
-感谢如下优秀的项目,没有这些项目,不可能会有go-ldap-admin:
+感谢如下优秀的项目,没有这些项目,不可能会有 go-ldap-admin:
- 后端技术栈
- [Gin-v1.6.3](https://github.com/gin-gonic/gin)
@@ -92,6 +91,7 @@
- [Go-ldap-v3.4.2](https://github.com/go-ldap/ldap)
- [Casbin-v2.22.0](https://github.com/casbin/casbin)
- 前端技术栈
+
- [axios](https://github.com/axios/axios)
- [element-ui](https://github.com/ElemeFE/element)
@@ -100,8 +100,8 @@
## 🤗 另外
-- 如果觉得项目不错,麻烦动动小手点个⭐️star⭐️!
-- 如果你还有其他想法或者需求,欢迎在issue中交流!
+- 如果觉得项目不错,麻烦动动小手点个 ⭐️star⭐️!
+- 如果你还有其他想法或者需求,欢迎在 issue 中交流!
## 🤑 捐赠
@@ -109,11 +109,11 @@
## 📝 使用登记
-如果你所在公司使用了该项目,烦请在这里留下脚印,感谢支持🥳 [点我](https://github.com/eryajf/go-ldap-admin/issues/18)
+如果你所在公司使用了该项目,烦请在这里留下脚印,感谢支持 🥳 [点我](https://github.com/eryajf/go-ldap-admin/issues/18)
## 💎 优秀软件推荐
-- [🦄 ConsulManager:高效易用的Consul Web运维平台](https://github.com/starsliao/ConsulManager)
+- [🦄 ConsulManager:高效易用的 Consul Web 运维平台](https://github.com/starsliao/ConsulManager)
## 🤝 贡献者
@@ -185,4 +185,4 @@
-
\ No newline at end of file
+
diff --git a/config.yml b/config.yml
index 017c9a9..cea701b 100644
--- a/config.yml
+++ b/config.yml
@@ -41,9 +41,9 @@ mysql:
# 数据库名
database: go_ldap_admin
# 主机地址
- host: localhost
+ host: kaiyuan
# 端口
- port: 3306
+ port: 3307
# 连接字符串参数
query: parseTime=True&loc=Local&timeout=10000ms
# 是否打印日志
@@ -117,10 +117,10 @@ dingtalk:
enable-sync: false # 是否开启定时同步钉钉的任务
dept-sync-time: "0 30 2 * * *" # 部门同步任务的时间点 * * * * * * 秒 分 时 日 月 周, 请把时间设置在凌晨 1 ~ 5 点
user-sync-time: "0 30 3 * * *" # 用户同步任务的时间点 * * * * * * 秒 分 时 日 月 周, 请把时间设置在凌晨 1 ~ 5 点,注意请把用户同步的任务滞后于部门同步时间,比如部门为2点,则用户为3点
- dept-list: #部门列表,不设置则使用公司根部门,在开头加^表示不同步此部门,只需配置需要同步的部门ID
- #- "1" #根组织ID
- - "48456726" #需要同步的部门ID
- #- "^61213417" #不同步的ID,不配置即只同步上一ID
+ dept-list: # 配置要同步的部门列表,配置留空则同步所有部门,在开头加^表示不同步此部门
+ #- "48456726" # 需要同步的部门ID
+ #- "^61213417" # 不需要同步的部门ID
+ is-update-syncd: false # 当钉钉用户的邮箱,手机号,部门等信息更新之后,是否同步更新,默认为false,如果你不了解这个字段的含义,则不建议开启
wecom:
# 配置获取详细文档参考:http://ldapdoc.eryajf.net/pages/cf1698/
flag: "wecom" # 作为微信在平台的标识
@@ -130,6 +130,7 @@ wecom:
enable-sync: false # 是否开启定时同步企业微信的任务
dept-sync-time: "0 30 2 * * *" # 部门同步任务的时间点 * * * * * * 秒 分 时 日 月 周, 请把时间设置在凌晨 1 ~ 5 点
user-sync-time: "0 30 3 * * *" # 用户同步任务的时间点 * * * * * * 秒 分 时 日 月 周, 请把时间设置在凌晨 1 ~ 5 点,注意请把用户同步的任务滞后于部门同步时间,比如部门为2点,则用户为3点
+ is-update-syncd: false # 当企微用户的邮箱,手机号,部门等信息更新之后,是否同步更新,默认为false,如果你不了解这个字段的含义,则不建议开启
feishu:
# 配置获取详细文档参考:http://ldapdoc.eryajf.net/pages/83c90b/
flag: "feishu" # 作为飞书在平台的标识
@@ -138,7 +139,7 @@ feishu:
enable-sync: false # 是否开启定时同步飞书的任务
dept-sync-time: "0 20 0 * * *" # 部门同步任务的时间点 * * * * * * 秒 分 时 日 月 周, 请把时间设置在凌晨 1 ~ 5 点
user-sync-time: "0 40 0 * * *" # 用户同步任务的时间点 * * * * * * 秒 分 时 日 月 周, 请把时间设置在凌晨 1 ~ 5 点,注意请把用户同步的任务滞后于部门同步时间,比如部门为2点,则用户为3点
- dept-list: #部门列表,不设置则使用公司根部门,如果不希望添加子部门,在开头加上^
- # - "^od-xxx"
- # - "od-xxx"
- enable-bot-inform: false
+ dept-list: # 配置要同步的部门列表,配置留空则同步所有部门,在开头加^表示不同步此部门
+ #- "48456726" # 需要同步的部门ID
+ #- "^61213417" # 不需要同步的部门ID
+ is-update-syncd: false # 当飞书用户的邮箱,手机号,部门等信息更新之后,是否同步更新,默认为false,如果你不了解这个字段的含义,则不建议开启
\ No newline at end of file
diff --git a/config/config.go b/config/config.go
index e918858..03df010 100644
--- a/config/config.go
+++ b/config/config.go
@@ -159,33 +159,36 @@ type EmailConfig struct {
}
type DingTalkConfig struct {
- AppKey string `mapstructure:"app-key" json:"appKey"`
- AppSecret string `mapstructure:"app-secret" json:"appSecret"`
- AgentId string `mapstructure:"agent-id" json:"agentId"`
- RootOuName string `mapstructure:"root-ou-name" json:"rootOuName"`
- Flag string `mapstructure:"flag" json:"flag"`
- EnableSync bool `mapstructure:"enable-sync" json:"enableSync"`
- DeptSyncTime string `mapstructure:"dept-sync-time" json:"deptSyncTime"`
- UserSyncTime string `mapstructure:"user-sync-time" json:"userSyncTime"`
- DeptList []string `mapstructure:"dept-list" json:"deptList"`
+ AppKey string `mapstructure:"app-key" json:"appKey"`
+ AppSecret string `mapstructure:"app-secret" json:"appSecret"`
+ AgentId string `mapstructure:"agent-id" json:"agentId"`
+ RootOuName string `mapstructure:"root-ou-name" json:"rootOuName"`
+ Flag string `mapstructure:"flag" json:"flag"`
+ EnableSync bool `mapstructure:"enable-sync" json:"enableSync"`
+ DeptSyncTime string `mapstructure:"dept-sync-time" json:"deptSyncTime"`
+ UserSyncTime string `mapstructure:"user-sync-time" json:"userSyncTime"`
+ DeptList []string `mapstructure:"dept-list" json:"deptList"`
+ IsUpdateSyncd bool `mapstructure:"is-update-syncd" json:"isUpdateSyncd"`
}
type WeComConfig struct {
- Flag string `mapstructure:"flag" json:"flag"`
- CorpID string `mapstructure:"corp-id" json:"corpId"`
- AgentID int `mapstructure:"agent-id" json:"agentId"`
- CorpSecret string `mapstructure:"corp-secret" json:"corpSecret"`
- EnableSync bool `mapstructure:"enable-sync" json:"enableSync"`
- DeptSyncTime string `mapstructure:"dept-sync-time" json:"deptSyncTime"`
- UserSyncTime string `mapstructure:"user-sync-time" json:"userSyncTime"`
+ Flag string `mapstructure:"flag" json:"flag"`
+ CorpID string `mapstructure:"corp-id" json:"corpId"`
+ AgentID int `mapstructure:"agent-id" json:"agentId"`
+ CorpSecret string `mapstructure:"corp-secret" json:"corpSecret"`
+ EnableSync bool `mapstructure:"enable-sync" json:"enableSync"`
+ DeptSyncTime string `mapstructure:"dept-sync-time" json:"deptSyncTime"`
+ UserSyncTime string `mapstructure:"user-sync-time" json:"userSyncTime"`
+ IsUpdateSyncd bool `mapstructure:"is-update-syncd" json:"isUpdateSyncd"`
}
type FeiShuConfig struct {
- Flag string `mapstructure:"flag" json:"flag"`
- AppID string `mapstructure:"app-id" json:"appId"`
- AppSecret string `mapstructure:"app-secret" json:"appSecret"`
- EnableSync bool `mapstructure:"enable-sync" json:"enableSync"`
- DeptSyncTime string `mapstructure:"dept-sync-time" json:"deptSyncTime"`
- UserSyncTime string `mapstructure:"user-sync-time" json:"userSyncTime"`
- DeptList []string `mapstructure:"dept-list" json:"deptList"`
+ Flag string `mapstructure:"flag" json:"flag"`
+ AppID string `mapstructure:"app-id" json:"appId"`
+ AppSecret string `mapstructure:"app-secret" json:"appSecret"`
+ EnableSync bool `mapstructure:"enable-sync" json:"enableSync"`
+ DeptSyncTime string `mapstructure:"dept-sync-time" json:"deptSyncTime"`
+ UserSyncTime string `mapstructure:"user-sync-time" json:"userSyncTime"`
+ DeptList []string `mapstructure:"dept-list" json:"deptList"`
+ IsUpdateSyncd bool `mapstructure:"is-update-syncd" json:"isUpdateSyncd"`
}
diff --git a/logic/dingtalk_logic.go b/logic/dingtalk_logic.go
index 435eb45..083279a 100644
--- a/logic/dingtalk_logic.go
+++ b/logic/dingtalk_logic.go
@@ -158,6 +158,63 @@ func (d DingTalkLogic) AddUsers(user *model.User) error {
if err != nil {
return tools.NewOperationError(fmt.Errorf("添加用户: %s, 失败: %s", user.Username, err.Error()))
}
+ } else {
+ if config.Conf.DingTalk.IsUpdateSyncd {
+ // 先获取用户信息
+ oldData := new(model.User)
+ err = isql.User.Find(tools.H{"user_dn": user.UserDN}, oldData)
+ if err != nil {
+ return err
+ }
+ // 获取用户将要添加的分组
+ groups, err := isql.Group.GetGroupByIds(tools.StringToSlice(user.DepartmentId, ","))
+ if err != nil {
+ return tools.NewMySqlError(fmt.Errorf("根据部门ID获取部门信息失败" + err.Error()))
+ }
+ var deptTmp string
+ for _, group := range groups {
+ deptTmp = deptTmp + group.GroupName + ","
+ }
+ user.Model = oldData.Model
+ user.Roles = oldData.Roles
+ user.Creator = oldData.Creator
+ user.Source = oldData.Source
+ user.Password = oldData.Password
+ user.UserDN = oldData.UserDN
+ user.Departments = strings.TrimRight(deptTmp, ",")
+
+ // 用户信息的预置处理
+ if user.Nickname == "" {
+ user.Nickname = oldData.Nickname
+ }
+ if user.GivenName == "" {
+ user.GivenName = user.Nickname
+ }
+ if user.Introduction == "" {
+ user.Introduction = user.Nickname
+ }
+ if user.Mail == "" {
+ user.Mail = oldData.Mail
+ }
+ if user.JobNumber == "" {
+ user.JobNumber = oldData.JobNumber
+ }
+ if user.Departments == "" {
+ user.Departments = oldData.Departments
+ }
+ if user.Position == "" {
+ user.Position = oldData.Position
+ }
+ if user.PostalAddress == "" {
+ user.PostalAddress = oldData.PostalAddress
+ }
+ if user.Mobile == "" {
+ user.Mobile = oldData.Mobile
+ }
+ if err = CommonUpdateUser(oldData, user, tools.StringToSlice(user.DepartmentId, ",")); err != nil {
+ return err
+ }
+ }
}
return nil
}
diff --git a/logic/feishu_logic.go b/logic/feishu_logic.go
index 9ee2a81..0dbf79a 100644
--- a/logic/feishu_logic.go
+++ b/logic/feishu_logic.go
@@ -160,6 +160,64 @@ func (d FeiShuLogic) AddUsers(user *model.User) error {
if err != nil {
return tools.NewOperationError(fmt.Errorf("添加用户: %s, 失败: %s", user.Username, err.Error()))
}
+ } else {
+ // 此处逻辑未经实际验证,如在使用中有问题,请反馈
+ if config.Conf.FeiShu.IsUpdateSyncd {
+ // 先获取用户信息
+ oldData := new(model.User)
+ err = isql.User.Find(tools.H{"user_dn": user.UserDN}, oldData)
+ if err != nil {
+ return err
+ }
+ // 获取用户将要添加的分组
+ groups, err := isql.Group.GetGroupByIds(tools.StringToSlice(user.DepartmentId, ","))
+ if err != nil {
+ return tools.NewMySqlError(fmt.Errorf("根据部门ID获取部门信息失败" + err.Error()))
+ }
+ var deptTmp string
+ for _, group := range groups {
+ deptTmp = deptTmp + group.GroupName + ","
+ }
+ user.Model = oldData.Model
+ user.Roles = oldData.Roles
+ user.Creator = oldData.Creator
+ user.Source = oldData.Source
+ user.Password = oldData.Password
+ user.UserDN = oldData.UserDN
+ user.Departments = strings.TrimRight(deptTmp, ",")
+
+ // 用户信息的预置处理
+ if user.Nickname == "" {
+ user.Nickname = oldData.Nickname
+ }
+ if user.GivenName == "" {
+ user.GivenName = user.Nickname
+ }
+ if user.Introduction == "" {
+ user.Introduction = user.Nickname
+ }
+ if user.Mail == "" {
+ user.Mail = oldData.Mail
+ }
+ if user.JobNumber == "" {
+ user.JobNumber = oldData.JobNumber
+ }
+ if user.Departments == "" {
+ user.Departments = oldData.Departments
+ }
+ if user.Position == "" {
+ user.Position = oldData.Position
+ }
+ if user.PostalAddress == "" {
+ user.PostalAddress = oldData.PostalAddress
+ }
+ if user.Mobile == "" {
+ user.Mobile = oldData.Mobile
+ }
+ if err = CommonUpdateUser(oldData, user, tools.StringToSlice(user.DepartmentId, ",")); err != nil {
+ return err
+ }
+ }
}
return nil
}
diff --git a/logic/wecom_logic.go b/logic/wecom_logic.go
index ec0d3cb..51640d5 100644
--- a/logic/wecom_logic.go
+++ b/logic/wecom_logic.go
@@ -175,6 +175,64 @@ func (d WeComLogic) AddUsers(user *model.User) error {
if err != nil {
return tools.NewOperationError(fmt.Errorf("添加用户: %s, 失败: %s", user.Username, err.Error()))
}
+ } else {
+ // 此处逻辑未经实际验证,如在使用中有问题,请反馈
+ if config.Conf.WeCom.IsUpdateSyncd {
+ // 先获取用户信息
+ oldData := new(model.User)
+ err = isql.User.Find(tools.H{"user_dn": user.UserDN}, oldData)
+ if err != nil {
+ return err
+ }
+ // 获取用户将要添加的分组
+ groups, err := isql.Group.GetGroupByIds(tools.StringToSlice(user.DepartmentId, ","))
+ if err != nil {
+ return tools.NewMySqlError(fmt.Errorf("根据部门ID获取部门信息失败" + err.Error()))
+ }
+ var deptTmp string
+ for _, group := range groups {
+ deptTmp = deptTmp + group.GroupName + ","
+ }
+ user.Model = oldData.Model
+ user.Roles = oldData.Roles
+ user.Creator = oldData.Creator
+ user.Source = oldData.Source
+ user.Password = oldData.Password
+ user.UserDN = oldData.UserDN
+ user.Departments = strings.TrimRight(deptTmp, ",")
+
+ // 用户信息的预置处理
+ if user.Nickname == "" {
+ user.Nickname = oldData.Nickname
+ }
+ if user.GivenName == "" {
+ user.GivenName = user.Nickname
+ }
+ if user.Introduction == "" {
+ user.Introduction = user.Nickname
+ }
+ if user.Mail == "" {
+ user.Mail = oldData.Mail
+ }
+ if user.JobNumber == "" {
+ user.JobNumber = oldData.JobNumber
+ }
+ if user.Departments == "" {
+ user.Departments = oldData.Departments
+ }
+ if user.Position == "" {
+ user.Position = oldData.Position
+ }
+ if user.PostalAddress == "" {
+ user.PostalAddress = oldData.PostalAddress
+ }
+ if user.Mobile == "" {
+ user.Mobile = oldData.Mobile
+ }
+ if err = CommonUpdateUser(oldData, user, tools.StringToSlice(user.DepartmentId, ",")); err != nil {
+ return err
+ }
+ }
}
return nil
}