feat: 修复仪表盘数据管线 — 补充应用发布种子数据 + 修复limit参数解析 + LDAP认证集成 + User类型完善
后端改进: - 修复 dashboard/recent-alerts 的 limit 参数解析 (原代码错误地将数字解析为日期) - 为 dashboard/recent-releases 添加 limit 参数解析支持 - 新增 generateAppReleases 种子数据生成函数 (10条应用发布记录) - 修复 AlertEvent 的 rule_name/rule_id/severity 数据一致性 - 添加 go-ldap/ldap/v3 依赖并集成 LDAP 认证处理器 - 添加 seed.go 自动种子数据初始化 (admin用户+LDAP配置) - User model 添加 AuthSource/LDAPConfig 字段 前端改进: - 修复 User 类型定义以匹配后端 API (real_name/is_admin/auth_source等) - 修复 Header.tsx 的 real_name 属性引用导致 TypeScript 编译错误 - 统一 API 服务层、暗色主题样式、组件联调优化 验证: - go build ./... 编译通过 - npm run build 构建通过 - 仪表盘发布历史、告警消息等区域数据正常展示 - 健康检查 /health 正常
This commit is contained in:
1 parent
97c4207ff8
commit
ff0b268984
39 files changed
+4283
-1878
No files matched your search
@@ -46,26 +46,87 @@ func (h *UserHandler) Login(c *gin.Context) {
|
||||
}
|
||||
|
||||
var user models.User
|
||||
if err := h.db.Where("username = ?", req.Username).First(&user).Error; err != nil {
|
||||
c.JSON(http.StatusUnauthorized, models.Response{
|
||||
Code: 401,
|
||||
Message: "用户名或密码错误",
|
||||
})
|
||||
return
|
||||
}
|
||||
err := h.db.Where("username = ?", req.Username).First(&user).Error
|
||||
|
||||
if user.Status != 1 {
|
||||
c.JSON(http.StatusUnauthorized, models.Response{
|
||||
Code: 401,
|
||||
Message: "账号已被禁用",
|
||||
})
|
||||
return
|
||||
}
|
||||
if err == nil {
|
||||
// 本地用户存在
|
||||
if user.Status != 1 {
|
||||
c.JSON(http.StatusUnauthorized, models.Response{
|
||||
Code: 401,
|
||||
Message: "账号已被禁用",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)); err != nil {
|
||||
c.JSON(http.StatusUnauthorized, models.Response{
|
||||
Code: 401,
|
||||
Message: "用户名或密码错误",
|
||||
// 先尝试本地密码验证
|
||||
passOk := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)) == nil
|
||||
|
||||
if !passOk {
|
||||
// 本地密码失败 — LDAP 用户尝试 LDAP 认证
|
||||
if user.AuthSource == "ldap" || user.Password == "-" {
|
||||
ldapInfo, ldapErr := tryLDAPAuth(h.db, req.Username, req.Password)
|
||||
if ldapErr != nil {
|
||||
c.JSON(http.StatusUnauthorized, models.Response{
|
||||
Code: 401,
|
||||
Message: "用户名或密码错误",
|
||||
})
|
||||
return
|
||||
}
|
||||
// LDAP OK — 更新本地信息
|
||||
if ldapInfo != nil {
|
||||
updates := map[string]interface{}{}
|
||||
if ldapInfo.DisplayName != "" && ldapInfo.DisplayName != user.RealName {
|
||||
updates["real_name"] = ldapInfo.DisplayName
|
||||
}
|
||||
if ldapInfo.Email != "" && ldapInfo.Email != user.Email {
|
||||
updates["email"] = ldapInfo.Email
|
||||
}
|
||||
if len(updates) > 0 {
|
||||
h.db.Model(&user).Updates(updates)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
c.JSON(http.StatusUnauthorized, models.Response{
|
||||
Code: 401,
|
||||
Message: "用户名或密码错误",
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
} else if err == gorm.ErrRecordNotFound {
|
||||
// 本地用户不存在 — 尝试 LDAP 认证
|
||||
ldapInfo, ldapErr := tryLDAPAuth(h.db, req.Username, req.Password)
|
||||
if ldapErr != nil {
|
||||
c.JSON(http.StatusUnauthorized, models.Response{
|
||||
Code: 401,
|
||||
Message: "用户名或密码错误",
|
||||
})
|
||||
return
|
||||
}
|
||||
// LDAP 认证成功,自动创建本地用户
|
||||
newUser := models.User{
|
||||
Username: ldapInfo.Username,
|
||||
Password: "-",
|
||||
RealName: ldapInfo.DisplayName,
|
||||
Email: ldapInfo.Email,
|
||||
Status: 1,
|
||||
AuthSource: "ldap",
|
||||
}
|
||||
if newUser.RealName == "" {
|
||||
newUser.RealName = newUser.Username
|
||||
}
|
||||
if err := h.db.Create(&newUser).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, models.Response{
|
||||
Code: 500,
|
||||
Message: "创建LDAP用户失败: " + err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
user = newUser
|
||||
} else {
|
||||
c.JSON(http.StatusInternalServerError, models.Response{
|
||||
Code: 500,
|
||||
Message: "数据库错误",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user