Files
polaris/server/auth.go
Simon Ding ca414a73ff fix: logout
2024-09-02 14:07:47 +08:00

149 lines
3.6 KiB
Go

package server
import (
"net/http"
"polaris/db"
"polaris/log"
"polaris/pkg/utils"
"time"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
"github.com/pkg/errors"
)
func (s *Server) isAuthEnabled() bool {
authEnabled := s.db.GetSetting(db.SettingAuthEnabled)
return authEnabled == "true"
}
func (s *Server) authModdleware(c *gin.Context) {
if !s.isAuthEnabled() {
c.Next()
return
}
token, err := c.Cookie("polaris_token")
if err != nil {
log.Errorf("token error: %v", err)
c.AbortWithStatus(http.StatusForbidden)
return
}
//log.Debugf("current token: %v", auth)
tokenParsed, err := jwt.ParseWithClaims(token, &jwt.RegisteredClaims{}, func(t *jwt.Token) (interface{}, error) {
return []byte(s.jwtSerect), nil
})
if err != nil {
log.Errorf("parse token error: %v", err)
c.AbortWithStatus(http.StatusForbidden)
return
}
if !tokenParsed.Valid {
log.Errorf("token is not valid: %v", token)
c.AbortWithStatus(http.StatusForbidden)
return
}
claim := tokenParsed.Claims.(*jwt.RegisteredClaims)
if time.Until(claim.ExpiresAt.Time) <= 0 {
log.Infof("token is no longer valid: %s", token)
c.AbortWithStatus(http.StatusForbidden)
return
}
c.Next()
}
type LoginIn struct {
User string `json:"user"`
Password string `json:"password"`
}
func (s *Server) Login(c *gin.Context) (interface{}, error) {
var in LoginIn
if err := c.ShouldBindJSON(&in); err != nil {
return nil, errors.Wrap(err, "bind json")
}
if !s.isAuthEnabled() {
return nil, nil
}
user := s.db.GetSetting(db.SettingUsername)
if user != in.User {
return nil, errors.New("login fail")
}
password := s.db.GetSetting(db.SettingPassword)
if !utils.VerifyPassword(in.Password, password) {
return nil, errors.New("login fail")
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.RegisteredClaims{
Issuer: "system",
Subject: in.User,
ExpiresAt: jwt.NewNumericDate(time.Now().Add(7 * 24 * time.Hour)),
IssuedAt: jwt.NewNumericDate(time.Now()),
NotBefore: jwt.NewNumericDate(time.Now()),
})
sig, err := token.SignedString([]byte(s.jwtSerect))
if err != nil {
return nil, errors.Wrap(err, "sign")
}
c.SetSameSite(http.SameSiteLaxMode)
c.SetCookie("polaris_token", sig, 0, "/", "", false, false)
return "success", nil
}
func (s *Server) Logout(c *gin.Context) (interface{}, error) {
if !s.isAuthEnabled() {
return nil, errors.New( "auth is not enabled")
}
c.SetSameSite(http.SameSiteLaxMode)
c.SetCookie("polaris_token", "", -1, "/", "", false, false)
return nil, nil
}
type EnableAuthIn struct {
Enable bool `json:"enable"`
User string `json:"user"`
Password string `json:"password"`
}
func (s *Server) EnableAuth(c *gin.Context) (interface{}, error) {
var in EnableAuthIn
if err := c.ShouldBindJSON(&in); err != nil {
return nil, errors.Wrap(err, "bind json")
}
if in.Enable && (in.User == "" || in.Password == "") {
return nil, errors.New("user password should not empty")
}
if !in.Enable {
log.Infof("disable auth")
s.db.SetSetting(db.SettingAuthEnabled, "false")
} else {
log.Info("enable auth")
s.db.SetSetting(db.SettingAuthEnabled, "true")
s.db.SetSetting(db.SettingUsername, in.User)
hash, err := utils.HashPassword(in.Password)
if err != nil {
return nil, errors.Wrap(err, "hash password")
}
s.db.SetSetting(db.SettingPassword, hash)
}
return "success", nil
}
func (s *Server) GetAuthSetting(c *gin.Context) (interface{}, error) {
enabled := s.db.GetSetting(db.SettingAuthEnabled)
user := s.db.GetSetting(db.SettingUsername)
return EnableAuthIn{
Enable: enabled == "true",
User: user,
}, nil
}