123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- package ldap
- import (
- "crypto/md5"
- "encoding/hex"
- "errors"
- "fmt"
- "github.com/astaxie/beego/logs"
- "github.com/astaxie/beego/orm"
- "nginx-ui/server/config"
- "nginx-ui/server/models"
- "nginx-ui/server/vo"
- )
- type Service struct {
- }
- // 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服务!")
- }
- client, err := GetActiveClient(&server)
- if err != nil {
- return nil, err
- }
- ldapUser, err := client.Authentication(req.Account, req.Password)
- if err != nil {
- return nil, err
- }
- ldapUser.Uid = server.Uid
- ldapUser.ServerKey = server.Key
- _, err = o.InsertOrUpdate(ldapUser, "DN")
- if err != nil {
- return nil, err
- }
- var user = models.User{
- Account: ldapUser.Account,
- }
- err = o.Read(&user, "Account")
- if err != nil {
- if !errors.Is(err, orm.ErrNoRows) {
- return nil, err
- }
- user.Password = ldapUser.Password
- user.Account = ldapUser.Account
- user.Nickname = ldapUser.UserName
- user.Source = "LDAP"
- _, err := o.Insert(&user)
- if err != nil {
- return nil, err
- }
- } else if user.Source == "LDAP" {
- // 更新用户
- user.Password = ldapUser.Password
- user.Nickname = ldapUser.UserName
- _, err = o.Update(&user, "Password", "Nickname")
- 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
- }
- // SyncUsers 同步用户信息
- // post /ldap/user/sync
- func (c *Service) SyncUsers(current *models.User, req *LDAPUserSyncReq) (int, error) {
- server := models.LdapServer{Key: req.ServerKey}
- o := orm.NewOrm()
- err := o.Read(&server, "Key")
- if err != nil {
- return 0, err
- }
- client, err := GetActiveClient(&server)
- if err != nil {
- return 0, err
- }
- users, err := client.Search(req.Filter)
- if err != nil {
- return 0, err
- }
- for _, user := range users {
- user.ServerKey = server.Key
- user.Uid = string(rune(current.Id))
- _, err := o.InsertOrUpdate(&user, "DN")
- if err != nil {
- logs.Error("save user fail: %v", err)
- }
- }
- return len(users), nil
- }
- // SyncUser SyncUsers 同步用户信息
- // post /ldap/user/sync
- func (c *Service) SyncUser(server *models.LdapServer, current *models.LdapUser) error {
- o := orm.NewOrm()
- if server == nil {
- server := &models.LdapServer{Key: current.ServerKey}
- err := o.Read(server, "Key")
- if err != nil {
- return err
- }
- }
- client, err := GetActiveClient(server)
- if err != nil {
- return err
- }
- users, err := client.Search(fmt.Sprintf("(&(objectClass=*)(uid=%s))", current.Account))
- if err != nil {
- return err
- }
- if len(users) != 1 {
- return errors.New("账号不存在或者账号重复!")
- }
- user := users[0]
- user.Id = current.Id
- user.ServerKey = current.ServerKey
- user.Uid = current.Uid
- user.Remark = current.Remark
- _, err = o.Update(&user)
- if err != nil {
- return err
- }
- return nil
- }
- // Update 保存或者修改
- // post /ldap/server
- func (c *Service) Update(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
- }
- client, err := GetActiveClient(server)
- if err != nil {
- return nil, err
- }
- if req.Filter == "" && req.Username != "" {
- req.Filter = fmt.Sprintf("(&(objectClass=*)(uid=%s))", req.Username)
- }
- if req.Filter != "" {
- users, err := client.Search(req.Filter)
- if err != nil {
- return nil, err
- }
- return users, nil
- }
- return make([]models.LdapUser, 0), nil
- }
- // UpdateUserPassword 更新用户密码
- // post /ldap/user/modifyPassword
- func (c *Service) UpdateUserPassword(req *UpdatePasswordReq, byAdmin bool) error {
- o := orm.NewOrm()
- user := models.LdapUser{
- Account: req.Account,
- }
- err := o.Read(&user, "Account")
- if err != nil {
- if errors.Is(err, orm.ErrNoRows) {
- return nil
- }
- logs.Error("read user fail: %v", err)
- return err
- }
- server := models.LdapServer{
- Key: user.ServerKey,
- }
- err = o.Read(&server, "Key")
- if err != nil {
- return err
- }
- client, err := GetActiveClient(&server)
- if err != nil {
- return err
- }
- if byAdmin {
- err = client.ModifyPasswordByAdmin(user.DN, req.Password)
- } else {
- err = client.ModifyPassword(user.DN, req.OldPassword, req.Password)
- }
- if err != nil {
- return err
- }
- err = c.SyncUser(&server, &user)
- if err != nil {
- return errors.New("密码更新成功,但更新用户信息失败:" + err.Error())
- }
- return 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
- }
|