finclip-app-manager/router/middleware/licenseCheck.go

235 lines
5.6 KiB
Go
Raw Normal View History

2023-10-31 14:07:26 +08:00
package middleware
import (
"encoding/json"
"errors"
"finclip-app-manager/infrastructure/client/httpcall"
"fmt"
"github.com/patrickmn/go-cache"
"net/http"
"strings"
//"sync"
"time"
"gitlab.finogeeks.club/finclip-backend/apm"
"github.com/gin-gonic/gin"
"github.com/zzfup/go-fetch"
)
var (
commonRsp CommonRspData
commonConfig CommonConfigData
//需要模糊匹配的url
needSkipUrlList = []string{"/api/v1/mop/finstore/ruleEngine/app"}
//确定的url
needSkipUrlMap = map[string]bool{
"/ready": true,
"/down": true,
"/test": true,
}
)
type CommonConfigData struct {
Error string `json:"error"`
Errcode string `json:"errcode"`
Data struct {
OrganName string `json:"organName"`
} `json:"data"`
}
type CommonRspData struct {
Error string `json:"error"`
Errcode string `json:"errcode"`
}
func getCommonConfig(c *gin.Context) error {
var headers = map[string]string{
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json",
"Connection": "close",
}
options := fetch.Options{
Method: "GET",
Header: headers,
}
url := "http://mop-private-init-server:8080/api/v1/mop/mop-private-init-server/common/config"
spanId := c.Request.Header.Get("Zipkin-Span-Id")
value := c.GetString("zipkin_trace_span_id_" + spanId)
options.Header["Zipkin-Span-Context"] = value
rsp, err := fetch.Fetch(url, options)
if err != nil || rsp.StatusCode != 200 {
return errors.New("mop-private-init-server err")
}
rsp.BindJSON(&commonConfig)
return nil
}
var licenseCache = cache.New(time.Hour, time.Minute)
//var licenseUrlMutex sync.Mutex
//var licenseMutex sync.Mutex
func CheckLicenseUrl(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
reqUrl := c.Request.URL.Path
if isNotNeedCheckLicenseConfUrl(reqUrl) {
c.Next()
return
}
type CheckUrlReq struct {
Url string `json:"url"`
Method string `json:"method"`
}
//文件名只拉取一次
if commonConfig.Data.OrganName == "" {
getCommonConfig(c)
}
var req CheckUrlReq
req.Url = reqUrl
req.Method = c.Request.Method
licenseCacheKey := "license_url_status_" + reqUrl
if code, ok := licenseCache.Get(licenseCacheKey); ok {
if code.(int) != 200 {
rspJson := gin.H{
"error": "license检测失败",
"errcode": "MOP_LICENSE_FORBINDDEN",
"data": nil,
}
c.AbortWithStatusJSON(http.StatusForbidden, rspJson)
return
}
c.Next()
return
}
//licenseUrlMutex.Lock()
//defer licenseUrlMutex.Unlock()
if code, ok := licenseCache.Get(licenseCacheKey); ok {
if code.(int) != 200 {
rspJson := gin.H{
"error": "license检测失败",
"errcode": "MOP_LICENSE_FORBINDDEN",
"data": nil,
}
c.AbortWithStatusJSON(http.StatusForbidden, rspJson)
return
}
c.Next()
return
}
var headers = map[string]string{
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json",
"Organ-Name": commonConfig.Data.OrganName, //私有化部署的时候,需要修改机构名称
"Connection": "close",
}
url := "http://mop-license-checker:8080/api/v1/mop/mop-license-checker/check/url"
rsp, err := httpcall.NewClient().Request(traceCtx).SetHeaders(headers).SetBody(req).Post(url)
if err != nil || rsp.StatusCode() != 200 {
if err != nil {
log.Errorf("check license url err:%+v", err)
rspJson := gin.H{
"error": "license检测失败",
"errcode": "MOP_LICENSE_FORBINDDEN",
"data": nil,
}
c.AbortWithStatusJSON(http.StatusForbidden, rspJson)
return
} else {
licenseCache.Set(licenseCacheKey, rsp.StatusCode(), 5*time.Minute)
}
json.Unmarshal(rsp.Body(), &commonRsp)
fmt.Printf("license code no 200 code=%d,rsp=%+v\n", rsp.StatusCode, rsp)
rspJson := gin.H{
"error": commonRsp.Error,
"errcode": commonRsp.Errcode,
"data": nil,
}
c.AbortWithStatusJSON(http.StatusForbidden, rspJson)
return
}
licenseCache.Set(licenseCacheKey, rsp.StatusCode(), 5*time.Minute)
c.Next()
}
func CheckLicenseConf(c *gin.Context) {
url := c.Request.URL.Path
if isNotNeedCheckLicenseConfUrl(url) {
c.Next()
return
}
licenseCacheKey := "license_exp"
if code, ok := licenseCache.Get(licenseCacheKey); ok {
if code.(int) != 1 {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
"error": "操作失败当前环境license已过期",
"errcode": "MOP_LICENSE_EXPIRED",
"data": make(map[string]interface{}),
})
return
}
c.Next()
return
}
//licenseMutex.Lock()
//defer licenseMutex.Unlock()
if code, ok := licenseCache.Get(licenseCacheKey); ok {
if code.(int) != 1 {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
"error": "操作失败当前环境license已过期",
"errcode": "MOP_LICENSE_EXPIRED",
"data": make(map[string]interface{}),
})
return
}
c.Next()
return
}
traceCtx := apm.ApmClient().TraceContextFromGin(c)
licenseInfo, err := hcaller.GetLicense(traceCtx)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"error": "license 请求错误",
"errcode": "NET_ERROR",
"data": make(map[string]interface{}),
})
return
}
if licenseInfo.ExpireTime < time.Now().UnixNano()/1e6 {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
"error": "操作失败当前环境license已过期",
"errcode": "MOP_LICENSE_EXPIRED",
"data": make(map[string]interface{}),
})
licenseCache.Set(licenseCacheKey, 0, 5*time.Minute)
return
}
licenseCache.Set(licenseCacheKey, 1, 5*time.Minute)
}
func isNotNeedCheckLicenseConfUrl(path string) bool {
if _, ok := needSkipUrlMap[path]; ok {
return true
}
for _, v := range needSkipUrlList {
if strings.Contains(path, v) {
return true
}
}
return false
}