235 lines
5.6 KiB
Go
235 lines
5.6 KiB
Go
|
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
|
|||
|
}
|