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