feat: 实现LDAP创建OU和用户(LDAP Add)+弹框风格统一
This commit is contained in:
1 parent
7b5f95e702
commit
c51f619a7d
2 files changed
+167
-49
No files matched your search
@@ -361,12 +361,125 @@ func ListLDAPUsers(c *gin.Context) {
|
||||
|
||||
// POST /api/v1/ldap-config/create-ou
|
||||
func CreateLDAPOU(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"message": "OU created (placeholder)"})
|
||||
var req struct {
|
||||
OuName string `json:"ou_name"`
|
||||
ParentDN string `json:"parent_dn"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil || req.OuName == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"detail": "缺少 ou_name 参数"})
|
||||
return
|
||||
}
|
||||
|
||||
var cfg model.LDAPConfig
|
||||
if err := model.DB.Order("id").First(&cfg).Error; err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"detail": "LDAP 配置不存在"})
|
||||
return
|
||||
}
|
||||
|
||||
conn, err := dialLDAP(&cfg)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"detail": "LDAP 连接失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
adminPw, _ := decryptPassword(cfg.AdminPassword)
|
||||
if err := conn.Bind(cfg.AdminDN, adminPw); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"detail": "LDAP 管理员绑定失败"})
|
||||
return
|
||||
}
|
||||
|
||||
ouDN := fmt.Sprintf("ou=%s,%s", ldap.EscapeFilter(req.OuName), req.ParentDN)
|
||||
addReq := ldap.NewAddRequest(ouDN, nil)
|
||||
addReq.Attribute("objectClass", []string{"organizationalUnit", "top"})
|
||||
addReq.Attribute("ou", []string{req.OuName})
|
||||
if req.Description != "" {
|
||||
addReq.Attribute("description", []string{req.Description})
|
||||
}
|
||||
|
||||
if err := conn.Add(addReq); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"detail": "创建 OU 失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("OU %s 创建成功", req.OuName), "dn": ouDN})
|
||||
}
|
||||
|
||||
// POST /api/v1/ldap-config/create-user
|
||||
func CreateLDAPUser(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"message": "User created (placeholder)"})
|
||||
var req struct {
|
||||
Username string `json:"username"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
OuDn string `json:"ou_dn"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil || req.Username == "" || req.Password == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"detail": "缺少 username 或 password 参数"})
|
||||
return
|
||||
}
|
||||
|
||||
var cfg model.LDAPConfig
|
||||
if err := model.DB.Order("id").First(&cfg).Error; err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"detail": "LDAP 配置不存在"})
|
||||
return
|
||||
}
|
||||
|
||||
// Parse user_mapping for attribute names
|
||||
userMapping := map[string]string{"username": "uid", "email": "mail", "display_name": "cn"}
|
||||
if cfg.UserMapping != nil && *cfg.UserMapping != "" {
|
||||
json.Unmarshal([]byte(*cfg.UserMapping), &userMapping)
|
||||
}
|
||||
|
||||
conn, err := dialLDAP(&cfg)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"detail": "LDAP 连接失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
adminPw, _ := decryptPassword(cfg.AdminPassword)
|
||||
if err := conn.Bind(cfg.AdminDN, adminPw); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"detail": "LDAP 管理员绑定失败"})
|
||||
return
|
||||
}
|
||||
|
||||
uidAttr := userMapping["username"]
|
||||
if uidAttr == "" {
|
||||
uidAttr = "uid"
|
||||
}
|
||||
cnAttr := userMapping["display_name"]
|
||||
if cnAttr == "" {
|
||||
cnAttr = "cn"
|
||||
}
|
||||
mailAttr := userMapping["email"]
|
||||
if mailAttr == "" {
|
||||
mailAttr = "mail"
|
||||
}
|
||||
|
||||
userDN := fmt.Sprintf("%s=%s,%s", uidAttr, ldap.EscapeFilter(req.Username), req.OuDn)
|
||||
displayName := req.DisplayName
|
||||
if displayName == "" {
|
||||
displayName = req.Username
|
||||
}
|
||||
|
||||
addReq := ldap.NewAddRequest(userDN, nil)
|
||||
addReq.Attribute("objectClass", []string{"inetOrgPerson", "organizationalPerson", "person", "top"})
|
||||
addReq.Attribute(uidAttr, []string{req.Username})
|
||||
addReq.Attribute(cnAttr, []string{displayName})
|
||||
addReq.Attribute("sn", []string{displayName})
|
||||
addReq.Attribute("userPassword", []string{req.Password})
|
||||
if req.Email != "" {
|
||||
addReq.Attribute(mailAttr, []string{req.Email})
|
||||
}
|
||||
|
||||
if err := conn.Add(addReq); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"detail": "创建用户失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("用户 %s 创建成功", req.Username), "dn": userDN})
|
||||
}
|
||||
|
||||
// POST /api/v1/ldap-config/batch-import-ldap
|
||||
|
||||
Reference in new issue
Block a user