feat : 修改LDAP测试登录和同步用户属性

This commit is contained in:
wangzhengkun
2022-06-15 16:10:28 +08:00
parent cc4351a287
commit b3aff25c6b
7 changed files with 62 additions and 57 deletions

View File

@@ -82,14 +82,13 @@ func (h *Handler) TestConnect() iris.Handler {
func (h *Handler) SyncLdapUser() iris.Handler { func (h *Handler) SyncLdapUser() iris.Handler {
return func(ctx *context.Context) { return func(ctx *context.Context) {
uuid := ctx.Params().Get("id") users, err := h.ldapService.GetLdapUser()
err := h.ldapService.Sync(uuid, common.DBOptions{})
if err != nil { if err != nil {
ctx.StatusCode(iris.StatusInternalServerError) ctx.StatusCode(iris.StatusInternalServerError)
ctx.Values().Set("message", err.Error()) ctx.Values().Set("message", err.Error())
return return
} }
ctx.Values().Set("data", "") ctx.Values().Set("data", users)
} }
} }
@@ -132,7 +131,7 @@ func Install(parent iris.Party) {
sp.Get("/", handler.ListLdap()) sp.Get("/", handler.ListLdap())
sp.Post("/", handler.AddLdap()) sp.Post("/", handler.AddLdap())
sp.Put("/", handler.UpdateLdap()) sp.Put("/", handler.UpdateLdap())
sp.Post("/sync/:id", handler.SyncLdapUser()) sp.Post("/sync", handler.SyncLdapUser())
sp.Post("/test/connect", handler.TestConnect()) sp.Post("/test/connect", handler.TestConnect())
sp.Post("/test/login", handler.TestLogin()) sp.Post("/test/login", handler.TestLogin())
sp.Post("/import", handler.ImportUser()) sp.Post("/import", handler.ImportUser())

View File

@@ -30,10 +30,11 @@ type Service interface {
Delete(id string, options common.DBOptions) error Delete(id string, options common.DBOptions) error
Sync(id string, options common.DBOptions) error Sync(id string, options common.DBOptions) error
Login(user v1User.User, password string, options common.DBOptions) error Login(user v1User.User, password string, options common.DBOptions) error
TestConnect(ldap *v1Ldap.Ldap) ([]v1User.ImportUser, error) TestConnect(ldap *v1Ldap.Ldap) (int, error)
TestLogin(username string, password string) error TestLogin(username string, password string) error
ImportUsers(users []v1User.ImportUser) (v1User.ImportResult, error) ImportUsers(users []v1User.ImportUser) (v1User.ImportResult, error)
CheckStatus() bool CheckStatus() bool
GetLdapUser() ([]v1User.ImportUser, error)
} }
func NewService() Service { func NewService() Service {
@@ -128,17 +129,19 @@ func (l *service) Delete(id string, options common.DBOptions) error {
return db.DeleteStruct(ldap) return db.DeleteStruct(ldap)
} }
//func (l *service) GetLdapUser() ([]v1User.ImportUser, error) { func (l *service) GetLdapUser() ([]v1User.ImportUser, error) {
// users := []v1User.ImportUser{}
//
//}
func (l *service) TestConnect(ldap *v1Ldap.Ldap) ([]v1User.ImportUser, error) {
users := []v1User.ImportUser{} users := []v1User.ImportUser{}
ldaps, err := l.List(common.DBOptions{})
if err != nil {
return users, err
}
if len(ldaps) == 0 {
return users, errors.New("请先保存LDAP配置")
}
ldap := ldaps[0]
if !ldap.Enable { if !ldap.Enable {
return users, errors.New("请先启用LDAP") return users, errors.New("请先启用LDAP")
} }
lc := ldapClient.NewLdapClient(ldap.Address, ldap.Port, ldap.Username, ldap.Password, ldap.TLS) lc := ldapClient.NewLdapClient(ldap.Address, ldap.Port, ldap.Username, ldap.Password, ldap.TLS)
if err := lc.Connect(); err != nil { if err := lc.Connect(); err != nil {
return users, err return users, err
@@ -162,7 +165,6 @@ func (l *service) TestConnect(ldap *v1Ldap.Ldap) ([]v1User.ImportUser, error) {
us := new(v1User.ImportUser) us := new(v1User.ImportUser)
us.Available = true us.Available = true
rv := reflect.ValueOf(&us).Elem().Elem() rv := reflect.ValueOf(&us).Elem().Elem()
for _, at := range entry.Attributes { for _, at := range entry.Attributes {
for k, v := range mappings { for k, v := range mappings {
if v == at.Name && len(at.Values) > 0 { if v == at.Name && len(at.Values) > 0 {
@@ -173,25 +175,43 @@ func (l *service) TestConnect(ldap *v1Ldap.Ldap) ([]v1User.ImportUser, error) {
} }
} }
} }
if us.Email == "" || us.Name == "" { if us.Name == "" {
continue continue
} }
if us.NickName == "" {
us.NickName = us.Name
}
_, err = l.userService.GetByNameOrEmail(us.Name, common.DBOptions{}) _, err = l.userService.GetByNameOrEmail(us.Name, common.DBOptions{})
if err == nil { if err == nil {
us.Available = false us.Available = false
} }
users = append(users, *us) users = append(users, *us)
} }
if len(users) == 0 && len(entries) > 0 { return users, nil
return users, errors.New("Mapping 映射失败!")
} }
func (l *service) TestConnect(ldap *v1Ldap.Ldap) (int, error) {
users := 0
if !ldap.Enable {
return users, errors.New("请先启用LDAP")
}
lc := ldapClient.NewLdapClient(ldap.Address, ldap.Port, ldap.Username, ldap.Password, ldap.TLS)
if err := lc.Connect(); err != nil {
return users, err
}
attributes, err := ldap.GetAttributes()
if err != nil {
return users, err
}
entries, err := lc.Search(ldap.Dn, ldap.Filter, ldap.SizeLimit, ldap.TimeLimit, attributes)
if err != nil {
return users, err
}
if len(entries) == 0 {
return users, nil return users, nil
} }
return len(entries), nil
}
func (l *service) CheckStatus() bool { func (l *service) CheckStatus() bool {
ldaps, err := l.List(common.DBOptions{}) ldaps, err := l.List(common.DBOptions{})
if err != nil || len(ldaps) == 0 { if err != nil || len(ldaps) == 0 {
@@ -263,6 +283,13 @@ func (l *service) ImportUsers(users []v1User.ImportUser) (v1User.ImportResult, e
Type: v1User.LDAP, Type: v1User.LDAP,
Email: imp.Email, Email: imp.Email,
} }
if us.Email == "" {
us.Email = us.Name + "@example.com"
}
if us.NickName == "" {
us.NickName = us.Name
}
result.Failures = append(result.Failures, us.Name) result.Failures = append(result.Failures, us.Name)
tx, err := server.DB().Begin(true) tx, err := server.DB().Begin(true)
if err != nil { if err != nil {

View File

@@ -47,7 +47,7 @@ func (l *Ldap) Connect() error {
func (l *Ldap) Search(dn, filter string, sizeLimit, timeLimit int, attributes []string) ([]*ldap.Entry, error) { func (l *Ldap) Search(dn, filter string, sizeLimit, timeLimit int, attributes []string) ([]*ldap.Entry, error) {
searchRequest := ldap.NewSearchRequest(dn, searchRequest := ldap.NewSearchRequest(dn,
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, timeLimit, false, ldap.ScopeWholeSubtree, ldap.DerefAlways, 0, timeLimit, false,
filter, filter,
attributes, attributes,
nil) nil)

View File

@@ -14,8 +14,8 @@ export function updateLdap(data){
return put(`${baseUrl}`, data) return put(`${baseUrl}`, data)
} }
export function syncLdap(id,data) { export function syncLdap(data) {
return post(`${baseUrl}/sync/${id}`, data) return post(`${baseUrl}/sync`, data)
} }
export function testConnect(data) { export function testConnect(data) {

View File

@@ -67,10 +67,6 @@
$t("business.user.ldap_remake") $t("business.user.ldap_remake")
}} }}
</el-button> </el-button>
<!-- <el-button @click="sync" :disabled="isSubmitGoing" v-has-permissions="{resource:'ldap',verb:'create'}">{{-->
<!-- $t("commons.button.sync")-->
<!-- }}-->
<!-- </el-button>-->
<el-button type="primary" @click="onSubmit" :disabled="isSubmitGoing" <el-button type="primary" @click="onSubmit" :disabled="isSubmitGoing"
v-has-permissions="{resource:'ldap',verb:'create'}">{{ $t("commons.button.confirm") }} v-has-permissions="{resource:'ldap',verb:'create'}">{{ $t("commons.button.confirm") }}
</el-button> </el-button>
@@ -104,6 +100,7 @@
</el-form> </el-form>
</el-dialog> </el-dialog>
<el-dialog :visible.sync="importUserPageOpen" :title="$t('business.user.import_user')" style="height: 900px"> <el-dialog :visible.sync="importUserPageOpen" :title="$t('business.user.import_user')" style="height: 900px">
<span>{{ $t("business.user.ldap_helper") }}</span>
<div style="text-align: right;margin-bottom: 10px"> <div style="text-align: right;margin-bottom: 10px">
<el-input v-model="searchName" suffix-icon="el-icon-search" style="width: 30%" size="mini" clearable @change="handleSearch" /> <el-input v-model="searchName" suffix-icon="el-icon-search" style="width: 30%" size="mini" clearable @change="handleSearch" />
</div> </div>
@@ -159,7 +156,7 @@ export default {
return { return {
form: { form: {
mapping: "{\n" + mapping: "{\n" +
" \"Name\":\"sAMAccountName\",\n" + " \"Name\":\"cn\",\n" +
" \"NickName\":\"cn\",\n" + " \"NickName\":\"cn\",\n" +
" \"Email\":\"mail\"\n" + " \"Email\":\"mail\"\n" +
"}", "}",
@@ -206,24 +203,6 @@ export default {
} }
}, },
methods: { methods: {
sync () {
if (this.form.uuid === undefined || this.form.uuid === "") {
this.$message({
type: "warning",
message: this.$t("business.user.ldap_sync_error")
})
return
}
this.isSubmitGoing = true
syncLdap(this.form.uuid, {}).then(() => {
this.$message({
type: "success",
message: this.$t("business.user.ldap_sync")
})
}).finally(() => {
this.isSubmitGoing = false
})
},
connectTest () { connectTest () {
let isFormReady = false let isFormReady = false
this.$refs["form"].validate((valid) => { this.$refs["form"].validate((valid) => {
@@ -234,15 +213,12 @@ export default {
if (!isFormReady) { if (!isFormReady) {
return return
} }
this.tableUsers = []
this.loading = true this.loading = true
this.connectLoading = true this.connectLoading = true
testConnect(this.form).then(res => { testConnect(this.form).then(res => {
this.users = res.data
this.tableUsers = this.users
this.$message({ this.$message({
type: "success", type: "success",
message: this.$t("business.user.test_result", { count: res.data.length }) message: this.$t("business.user.test_result", { count: res.data })
}) })
}).finally(() => { }).finally(() => {
this.loading = false this.loading = false
@@ -254,12 +230,15 @@ export default {
this.loginForm = {} this.loginForm = {}
}, },
openImportPage () { openImportPage () {
this.importUserPageOpen = true
this.searchName = "" this.searchName = ""
if (this.users.length === 0) { this.loading = true
this.connectTest() syncLdap({}).then(res => {
} this.users = res.data
this.tableUsers = this.users this.tableUsers = this.users
this.importUserPageOpen = true
}).finally(() => {
this.loading = false
})
}, },
importAvailable (row) { importAvailable (row) {
return row.available return row.available

View File

@@ -189,7 +189,7 @@ const message = {
ldap_password: "Password", ldap_password: "Password",
ldap_filter_dn: "User Filtering DN", ldap_filter_dn: "User Filtering DN",
ldap_filter_rule: "User Filtering Rules", ldap_filter_rule: "User Filtering Rules",
ldap_helper: "Note: Users without mailboxes will not be synchronized, and those with the same login name as local users will not be synchronized!", ldap_helper: "Note: Users who cannot get the Name mapping attribute will not be matched",
ldap_sync: "Start syncing, please check the user list later", ldap_sync: "Start syncing, please check the user list later",
ldap_sync_error: "Please save first", ldap_sync_error: "Please save first",
type: "Type", type: "Type",

View File

@@ -189,7 +189,7 @@ const message = {
ldap_password: "密码", ldap_password: "密码",
ldap_filter_dn: "用户过滤 OU", ldap_filter_dn: "用户过滤 OU",
ldap_filter_rule: "用户过滤规则", ldap_filter_rule: "用户过滤规则",
ldap_helper: "注意:没有邮箱的用户不会被同步,与本地用户登录名重复的也不会被同步!", ldap_helper: "注意:无法获取到 Name 映射属性的用户不会匹配",
ldap_sync: "开始同步,稍后请查看用户列表", ldap_sync: "开始同步,稍后请查看用户列表",
ldap_sync_error: "请先保存", ldap_sync_error: "请先保存",
type: "类型", type: "类型",