1Panel/backend/app/service/auth.go

197 lines
5.7 KiB
Go
Raw Normal View History

2022-09-08 18:47:15 +08:00
package service
import (
2024-04-01 15:52:07 +08:00
"crypto/hmac"
2022-09-08 18:47:15 +08:00
"strconv"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
"github.com/1Panel-dev/1Panel/backend/utils/jwt"
2023-03-10 16:47:30 +08:00
"github.com/1Panel-dev/1Panel/backend/utils/mfa"
2022-09-08 18:47:15 +08:00
"github.com/gin-gonic/gin"
2023-03-11 19:55:37 +08:00
"github.com/google/uuid"
2022-09-08 18:47:15 +08:00
"github.com/pkg/errors"
)
type AuthService struct{}
type IAuthService interface {
2024-05-27 18:42:56 +08:00
CheckIsSafety(code string) (string, error)
GetResponsePage() (string, error)
2022-09-15 17:15:03 +08:00
VerifyCode(code string) (bool, error)
Login(c *gin.Context, info dto.Login, entrance string) (*dto.UserLoginInfo, error)
2022-09-08 18:47:15 +08:00
LogOut(c *gin.Context) error
MFALogin(c *gin.Context, info dto.MFALogin, entrance string) (*dto.UserLoginInfo, error)
2022-09-08 18:47:15 +08:00
}
func NewIAuthService() IAuthService {
return &AuthService{}
}
func (u *AuthService) Login(c *gin.Context, info dto.Login, entrance string) (*dto.UserLoginInfo, error) {
2022-09-08 18:47:15 +08:00
nameSetting, err := settingRepo.Get(settingRepo.WithByKey("UserName"))
if err != nil {
return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error())
}
passwordSetting, err := settingRepo.Get(settingRepo.WithByKey("Password"))
2022-09-08 18:47:15 +08:00
if err != nil {
return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error())
}
pass, err := encrypt.StringDecrypt(passwordSetting.Value)
2022-09-08 18:47:15 +08:00
if err != nil {
2022-12-02 18:52:43 +08:00
return nil, constant.ErrAuth
2022-09-08 18:47:15 +08:00
}
2024-04-01 15:52:07 +08:00
if !hmac.Equal([]byte(info.Password), []byte(pass)) || nameSetting.Value != info.Name {
2022-12-02 18:52:43 +08:00
return nil, constant.ErrAuth
2022-09-08 18:47:15 +08:00
}
entranceSetting, err := settingRepo.Get(settingRepo.WithByKey("SecurityEntrance"))
if err != nil {
return nil, err
}
if len(entranceSetting.Value) != 0 && entranceSetting.Value != entrance {
return nil, buserr.New(constant.ErrEntrance)
}
2022-09-15 18:43:41 +08:00
mfa, err := settingRepo.Get(settingRepo.WithByKey("MFAStatus"))
if err != nil {
return nil, err
}
if err = settingRepo.Update("Language", info.Language); err != nil {
return nil, err
}
2022-09-15 18:43:41 +08:00
if mfa.Value == "enable" {
2023-03-10 16:47:30 +08:00
return &dto.UserLoginInfo{Name: nameSetting.Value, MfaStatus: mfa.Value}, nil
2022-09-15 18:43:41 +08:00
}
return u.generateSession(c, info.Name, info.AuthMethod)
}
func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin, entrance string) (*dto.UserLoginInfo, error) {
2022-09-15 18:43:41 +08:00
nameSetting, err := settingRepo.Get(settingRepo.WithByKey("UserName"))
if err != nil {
return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error())
}
passwordSetting, err := settingRepo.Get(settingRepo.WithByKey("Password"))
2022-09-15 18:43:41 +08:00
if err != nil {
return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error())
}
pass, err := encrypt.StringDecrypt(passwordSetting.Value)
2022-09-15 18:43:41 +08:00
if err != nil {
return nil, err
2022-09-15 18:43:41 +08:00
}
2024-04-01 15:52:07 +08:00
if !hmac.Equal([]byte(info.Password), []byte(pass)) || nameSetting.Value != info.Name {
2023-03-10 16:47:30 +08:00
return nil, constant.ErrAuth
}
entranceSetting, err := settingRepo.Get(settingRepo.WithByKey("SecurityEntrance"))
if err != nil {
return nil, err
}
if len(entranceSetting.Value) != 0 && entranceSetting.Value != entrance {
return nil, buserr.New(constant.ErrEntrance)
}
2023-03-10 16:47:30 +08:00
mfaSecret, err := settingRepo.Get(settingRepo.WithByKey("MFASecret"))
if err != nil {
return nil, err
}
mfaInterval, err := settingRepo.Get(settingRepo.WithByKey("MFAInterval"))
if err != nil {
return nil, err
}
success := mfa.ValidCode(info.Code, mfaInterval.Value, mfaSecret.Value)
2023-03-10 16:47:30 +08:00
if !success {
2022-12-02 18:52:43 +08:00
return nil, constant.ErrAuth
2022-09-15 18:43:41 +08:00
}
return u.generateSession(c, info.Name, info.AuthMethod)
}
func (u *AuthService) generateSession(c *gin.Context, name, authMethod string) (*dto.UserLoginInfo, error) {
2022-09-08 18:47:15 +08:00
setting, err := settingRepo.Get(settingRepo.WithByKey("SessionTimeout"))
if err != nil {
return nil, err
}
httpsSetting, err := settingRepo.Get(settingRepo.WithByKey("SSL"))
if err != nil {
return nil, err
}
2022-09-08 18:47:15 +08:00
lifeTime, err := strconv.Atoi(setting.Value)
if err != nil {
return nil, err
}
2022-09-15 18:43:41 +08:00
if authMethod == constant.AuthMethodJWT {
2022-09-08 18:47:15 +08:00
j := jwt.NewJWT()
claims := j.CreateClaims(jwt.BaseClaims{
2022-09-15 18:43:41 +08:00
Name: name,
})
2022-09-08 18:47:15 +08:00
token, err := j.CreateToken(claims)
if err != nil {
return nil, err
}
2022-09-15 18:43:41 +08:00
return &dto.UserLoginInfo{Name: name, Token: token}, nil
2022-09-08 18:47:15 +08:00
}
sID, _ := c.Cookie(constant.SessionName)
sessionUser, err := global.SESSION.Get(sID)
if err != nil {
2023-03-11 19:55:37 +08:00
sID = uuid.New().String()
2024-02-21 19:06:28 +08:00
c.SetCookie(constant.SessionName, sID, 0, "", "", httpsSetting.Value == "enable", true)
2022-09-08 18:47:15 +08:00
err := global.SESSION.Set(sID, sessionUser, lifeTime)
if err != nil {
return nil, err
}
2022-09-15 18:43:41 +08:00
return &dto.UserLoginInfo{Name: name}, nil
2022-09-08 18:47:15 +08:00
}
if err := global.SESSION.Set(sID, sessionUser, lifeTime); err != nil {
return nil, err
}
2022-09-15 18:43:41 +08:00
return &dto.UserLoginInfo{Name: name}, nil
2022-09-08 18:47:15 +08:00
}
func (u *AuthService) LogOut(c *gin.Context) error {
httpsSetting, err := settingRepo.Get(settingRepo.WithByKey("SSL"))
if err != nil {
return err
}
2022-09-08 18:47:15 +08:00
sID, _ := c.Cookie(constant.SessionName)
if sID != "" {
2024-02-21 19:06:28 +08:00
c.SetCookie(constant.SessionName, sID, -1, "", "", httpsSetting.Value == "enable", true)
2022-09-08 18:47:15 +08:00
err := global.SESSION.Delete(sID)
if err != nil {
return err
}
}
return nil
}
2022-09-15 17:15:03 +08:00
func (u *AuthService) VerifyCode(code string) (bool, error) {
setting, err := settingRepo.Get(settingRepo.WithByKey("SecurityEntrance"))
if err != nil {
return false, err
}
2024-04-01 15:52:07 +08:00
return hmac.Equal([]byte(setting.Value), []byte(code)), nil
2022-09-15 17:15:03 +08:00
}
2024-05-27 18:42:56 +08:00
func (u *AuthService) CheckIsSafety(code string) (string, error) {
2023-04-27 22:44:16 +08:00
status, err := settingRepo.Get(settingRepo.WithByKey("SecurityEntrance"))
2022-09-15 17:15:03 +08:00
if err != nil {
2024-05-27 18:42:56 +08:00
return "", err
2022-09-15 17:15:03 +08:00
}
2023-04-27 22:44:16 +08:00
if len(status.Value) == 0 {
2024-05-27 18:42:56 +08:00
return "disable", nil
2022-09-15 17:15:03 +08:00
}
if status.Value == code {
2024-05-27 18:42:56 +08:00
return "pass", nil
}
2024-05-27 18:42:56 +08:00
return "unpass", nil
}
func (u *AuthService) GetResponsePage() (string, error) {
pageCode, err := settingRepo.Get(settingRepo.WithByKey("NoAuthSetting"))
if err != nil {
return "", err
}
return pageCode.Value, nil
}