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

235 lines
5.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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
}