1Panel/backend/middleware/session.go
28597721f2
Some checks failed
Build Test / build-linux-binary (push) Waiting to run
Build / SonarCloud (push) Waiting to run
sync2gitee / repo-sync (push) Waiting to run
Check untimely handle issues / check-untimely-handle-issues (push) Has been cancelled
feat: Add API interface authentication function (#7146)
2024-11-21 22:09:00 +08:00

100 lines
2.6 KiB
Go

package middleware
import (
"crypto/md5"
"encoding/hex"
"net"
"strconv"
"strings"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/repo"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
func SessionAuth() gin.HandlerFunc {
return func(c *gin.Context) {
if method, exist := c.Get("authMethod"); exist && method == constant.AuthMethodJWT {
c.Next()
return
}
panelToken := c.GetHeader("1Panel-Token")
panelTimestamp := c.GetHeader("1Panel-Timestamp")
if panelToken != "" || panelTimestamp != "" {
if global.CONF.System.ApiInterfaceStatus == "enable" {
clientIP := c.ClientIP()
if !isValid1PanelToken(panelToken, panelTimestamp) {
helper.ErrorWithDetail(c, constant.CodeErrUnauthorized, constant.ErrApiConfigKeyInvalid, nil)
return
}
if !isIPInWhiteList(clientIP) {
helper.ErrorWithDetail(c, constant.CodeErrUnauthorized, constant.ErrApiConfigIPInvalid, nil)
return
}
c.Next()
return
} else {
helper.ErrorWithDetail(c, constant.CodeErrUnauthorized, constant.ErrApiConfigStatusInvalid, nil)
return
}
}
sId, err := c.Cookie(constant.SessionName)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrUnauthorized, constant.ErrTypeNotLogin, nil)
return
}
psession, err := global.SESSION.Get(sId)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrUnauthorized, constant.ErrTypeNotLogin, nil)
return
}
settingRepo := repo.NewISettingRepo()
setting, err := settingRepo.Get(settingRepo.WithByKey("SessionTimeout"))
if err != nil {
global.LOG.Errorf("create operation record failed, err: %v", err)
}
lifeTime, _ := strconv.Atoi(setting.Value)
_ = global.SESSION.Set(sId, psession, lifeTime)
c.Next()
}
}
func isValid1PanelToken(panelToken string, panelTimestamp string) bool {
system1PanelToken := global.CONF.System.ApiKey
if GenerateMD5("1panel"+panelToken+panelTimestamp) == GenerateMD5("1panel"+system1PanelToken+panelTimestamp) {
return true
}
return false
}
func isIPInWhiteList(clientIP string) bool {
ipWhiteString := global.CONF.System.IpWhiteList
ipWhiteList := strings.Split(ipWhiteString, "\n")
for _, cidr := range ipWhiteList {
if cidr == "0.0.0.0" {
return true
}
_, ipNet, err := net.ParseCIDR(cidr)
if err != nil {
if cidr == clientIP {
return true
}
continue
}
if ipNet.Contains(net.ParseIP(clientIP)) {
return true
}
}
return false
}
func GenerateMD5(input string) string {
hash := md5.New()
hash.Write([]byte(input))
return hex.EncodeToString(hash.Sum(nil))
}