package ldap import ( "crypto/md5" "encoding/hex" "errors" "fmt" "github.com/astaxie/beego/orm" "nginx-ui/server/config" "nginx-ui/server/models" "nginx-ui/server/vo" ) type Service struct { } var ServiceInstance = new(Service) var UserIns = new(UserService) // GetServer 获取一个可用的LDAP 连接, 用于登录时获取服务信息 func (c *Service) GetServer() (*models.LdapServer, error) { o := orm.NewOrm() server := models.LdapServer{ Active: true, } err := o.Read(&server, "Active") if err != nil { return nil, err } return &server, nil } func (c *Service) Login(req *LDAPLoginReq) (*models.User, error) { server := models.LdapServer{Key: req.ServerKey} o := orm.NewOrm() err := o.Read(&server, "Key") if err != nil { return nil, errors.New("未找到对应的LDAP服务!") } user, err := UserIns.Authentication(&server, req.Account, req.Password) if err != nil { return nil, err } user.Password = "" return user, nil } // GetServers 获取用户所有的LDAP连接 // get /ldap/server func (c *Service) GetServers(current *models.User, req *vo.PageReq) (*vo.PageResp, error) { o := orm.NewOrm() req.Ensure() qs := o.QueryTable(&models.LdapServer{}) if !current.IsAdmin() { qs = qs.Filter("Uid", current.Account) } total, err := qs.Count() if err != nil { return nil, err } qs.OrderBy("Id") qs.Offset(req.Offset) qs.Limit(req.PageSize) var list []*models.LdapServer _, err = qs.All(&list) for _, v := range list { v.Password = config.ReplacePassword } if err != nil { return nil, err } resp := vo.PageResp{ Current: req.Current, PageSize: req.PageSize, Total: total, List: list, } return &resp, err } // Update 保存或者修改 // post /ldap/server func (c *Service) Update(current *models.User, body *models.LdapServer) (*models.LdapServer, error) { body.Uid = string(rune(current.Id)) if body.Url == "" { return nil, errors.New("请完成服务配置,缺少Url!") } if body.Key == "" { key := md5.Sum([]byte(body.Url)) body.Key = hex.EncodeToString(key[:]) } o := orm.NewOrm() if body.Id == 0 { exist := models.LdapServer{Key: body.Key} err := o.Read(&exist, "Key") if err != nil && !errors.Is(err, orm.ErrNoRows) { return nil, err } if exist.Id > 0 { return nil, errors.New("该服务Url已存在!") } } if body.Id > 0 { exist := models.LdapServer{Id: body.Id} err := o.Read(&exist, "Id") if err != nil { return nil, err } if config.ReplacePassword == body.Password { body.Password = exist.Password } _, err = o.Update(body) if err != nil { return nil, err } } else { id, err := o.Insert(body) if err != nil { return nil, err } body.Id = int(id) } CloseActiveClient(body) return body, nil } // Add Update 保存或者修改 func (c *Service) Add(current *models.User, body *models.LdapServer) (*models.LdapServer, error) { if body.Url == "" { return nil, errors.New("请完成服务配置,缺少Url!") } if body.Key == "" { key := md5.Sum([]byte(body.Url)) body.Key = hex.EncodeToString(key[:]) } o := orm.NewOrm() if body.Id == 0 { exist := models.LdapServer{Key: body.Key} err := o.Read(&exist, "Key") if err != nil && !errors.Is(err, orm.ErrNoRows) { return nil, err } if exist.Id > 0 { return nil, errors.New("该服务Url已存在!") } } if body.Id > 0 { exist := models.LdapServer{Id: body.Id} err := o.Read(&exist, "Id") if err != nil { return nil, err } if config.ReplacePassword == body.Password { body.Password = exist.Password } _, err = o.Update(body) if err != nil { return nil, err } } else { id, err := o.Insert(body) if err != nil { return nil, err } body.Id = int(id) } return body, nil } // VerifyServer 验证服务 func (c *Service) VerifyServer(req *VerifyReq) ([]*models.LdapUser, error) { var server = &models.LdapServer{ Id: req.Id, } o := orm.NewOrm() err := o.Read(server, "Id") if err != nil { return nil, err } if req.Filter == "" && req.Username != "" { req.Filter = fmt.Sprintf("(&(objectClass=*)(uid=%s))", req.Username) } users, _, err := UserIns.Search(server, req.Filter) if err != nil { return nil, err } return users, nil } // GetUsers 获取全部用户 // get /ldap/users func (c *Service) GetUsers(current *models.User, req *UserListReq) (*vo.PageResp, error) { req.Ensure() o := orm.NewOrm() qs := o.QueryTable(&models.LdapUser{}) if !current.IsAdmin() { qs = qs.Filter("Uid", current.Account) } qs.Filter("ServerKey", req.ServerKey) total, err := qs.Count() if err != nil { return nil, err } qs.OrderBy("Id") qs.Offset(req.Offset) qs.Limit(req.PageSize) var list []*models.LdapUser _, err = qs.All(&list) if err != nil { return nil, err } resp := vo.PageResp{ Current: req.Current, PageSize: req.PageSize, Total: total, List: list, } return &resp, nil }