package user import ( "encoding/json" "errors" "github.com/astaxie/beego/logs" "github.com/astaxie/beego/orm" "github.com/hashicorp/go-uuid" "nginx-ui/server/config" "nginx-ui/server/models" "nginx-ui/server/modules/ldap" "nginx-ui/server/utils" "nginx-ui/server/vo" "strings" ) type Service struct { } func NewUserService() *Service { return &Service{} } func (u *Service) Login(user *models.User) *models.RespData { cipherPassword := user.Password o := orm.NewOrm() err := o.Read(user, "Account") if err != nil { return models.NewErrorResp(err) } encryptPassword := utils.GetSHA256HashCode(cipherPassword) if encryptPassword != user.Password { return models.ErrorResp("用户名或者密码不正确!") } user.Password = "" return models.SuccessResp(user) } func (u *Service) SignUp(req []byte) *models.RespData { var user models.User err := json.Unmarshal(req, &user) if err != nil { logs.Error(err, req) return models.NewErrorResp(err) } if len(user.Account) == 0 || len(user.Password) == 0 { return models.ErrorResp("账号或者密码不能为空!") } if len(user.Nickname) == 0 { user.Nickname = user.Account } user.Password = utils.GetSHA256HashCode(user.Password) o := orm.NewOrm() _, err = o.Insert(&user) if err != nil { return models.NewErrorResp(err) } return models.SuccessResp(user).SetMsg("注册成功!") } func (u *Service) Users(req *vo.PageReq) (*vo.PageResp, error) { req.Ensure() qs := orm.NewOrm().QueryTable(new(models.User)) qs = qs.Offset(req.Offset).Limit(req.PageSize).OrderBy("-Id") var list []models.User _, err := qs.All(&list) if err != nil { return nil, err } count, err := qs.Count() if err != nil { return nil, err } var resList []models.User for _, user := range list { user.Password = config.ReplacePassword resList = append(resList, user) } resp := vo.PageResp{ PageSize: req.PageSize, Current: req.Current, Total: count, List: resList, } return &resp, err } func (u *Service) Update(req *models.User) (*models.User, error) { o := orm.NewOrm() exist := models.User{Id: req.Id} err := o.Read(&exist) if err != nil && !errors.Is(err, orm.ErrNoRows) { return nil, err } else if err != nil { req.Password = utils.GetSHA256HashCode(req.Password) _, err = o.Insert(req) if err != nil { return nil, err } return req, nil } if req.Password == "" || req.Password == config.ReplacePassword { req.Password = exist.Password } else { req.Password = utils.GetSHA256HashCode(req.Password) } _, err = o.Update(req) if err != nil { return nil, errors.New("更新失败,请重试!") } return req, nil } func (u *Service) GetDetail(id int) (*models.User, error) { o := orm.NewOrm() exist := models.User{Id: id} err := o.Read(&exist) if err != nil { return nil, errors.New("该用户不存在或者已被删除!") } exist.Password = config.ReplacePassword return &exist, nil } // UserUpdatePassword 更新用户密码,如果存在LDAP账号,则更新下, force: 强制更改,不需要确认原密码 func (u *Service) UserUpdatePassword(req *vo.UserUpdatePassword, force bool) error { o := orm.NewOrm() user := models.User{Id: req.Id} err := o.Read(&user) if err != nil { return errors.New("该用户不存在或者已被删除!") } if user.Source == "LDAP" { err = ldap.UserIns.UpdateUserPassword(&ldap.UpdatePasswordReq{ Password: req.NewPassword, Account: user.Account, OldPassword: req.OldPassword, }, force) if err != nil { return err } user.Password = utils.GetSHA256HashCode(req.NewPassword) _, err = o.Update(&user) if err != nil { logs.Error("update password error: %v", err) } } else { if !force && utils.GetSHA256HashCode(req.OldPassword) != user.Password { return errors.New("当前密码不正确!") } user.Password = utils.GetSHA256HashCode(req.NewPassword) _, err = o.Update(&user) if err != nil { return err } err = ldap.UserIns.UpdateUserPassword(&ldap.UpdatePasswordReq{ Password: req.NewPassword, Account: user.Account, }, true) if err != nil { logs.Error("LDAP updatePassword fail: %v", err) return errors.New("密码更新成功,但同步LDAP失败:" + err.Error()) } } return nil } // UpdatePassword 更新用户密码,如果存在LDAP账号,则更新下 func (u *Service) UpdatePassword(req *vo.UserUpdatePassword) error { return u.UserUpdatePassword(req, false) } // ResetPassword 用户忘记密码,重置密码 func (u *Service) ResetPassword(req *ResetPasswordReq) error { o := orm.NewOrm() user := models.User{ Account: req.Account, } err := o.Read(&user, "Account") if err != nil && errors.Is(err, orm.ErrNoRows) { ldapUser, err := ldap.UserIns.GetByAccount(req.Account) if err != nil { return errors.New("你输入的账号不正确!") } ldap.CreateLocalUser(&user, ldapUser) _, err = o.Insert(&user) if err != nil { return errors.New("你输入的账号不正确!") } } else if err != nil { logs.Error("read user fail: %v", err) return errors.New("你输入的账号不正确!") } if user.Email == "" && user.Source == "LDAP" { ldapUser, err := ldap.UserIns.GetByAccount(req.Account) if err != nil { logs.Error("get user fail: %v", err) return errors.New("你输入账号不正确或者未绑定邮箱!") } user.Email = ldapUser.Mail } if user.Email == "" { return errors.New("你输入账号不正确或者未绑定邮箱!") } if req.AuthCode != "" { if req.Password == "" { return errors.New("密码不能为空!") } if req.AuthCode == user.TempCode { // 重置密码 err = u.UserUpdatePassword(&vo.UserUpdatePassword{ Id: user.Id, NewPassword: req.Password, OldPassword: req.Password, }, true) if err == nil { user.TempCode = "" } } else { return errors.New("密码重置链接已过期,请重试!") } } else { authCode, _ := uuid.GenerateUUID() authCode = strings.ReplaceAll(authCode, "-", "") user.TempCode = authCode err = SendUserResetPassEmail(&user, authCode) } if err != nil { return err } _, _ = o.Update(&user) return nil }