中间件

This commit is contained in:
Rzy 2024-08-02 18:25:28 +08:00
parent 28bd78ab7f
commit 6e6e01a823
17 changed files with 208 additions and 16 deletions

View File

@ -19,11 +19,19 @@ const (
//系统错误
SystemError = 500
//请求超时
RequestTimeOut = 600
//未登录
NotLogin = 1000
// 商户
MerchantNotFound = 1100
// app
AppNotFound = 1200
AppDisabled = 1201
AppIpNotAllow = 1202
)
var MsgEN = map[int]string{
@ -36,13 +44,16 @@ var MsgEN = map[int]string{
}
var MsgZH = map[int]string{
Success: "请求成功",
ParamError: "参数错误",
NotFound: "数据不存在",
NotAuth: "未经授权",
NotLogin: "未登录",
Success: "请求成功",
ParamError: "参数错误",
NotFound: "数据不存在",
NotAuth: "未经授权",
NotLogin: "未登录",
RequestTimeOut: "请求超时",
MerchantNotFound: "商户不存在",
AppNotFound: "app_id未找到",
AppDisabled: "app通道关闭",
AppIpNotAllow: "ip不在白名单内",
}
var MsgMap map[string]map[int]string = map[string]map[int]string{"en": MsgZH}

View File

@ -0,0 +1,7 @@
package pojo
const (
Rsa int32 = iota + 1
Sm2
Sm4
)

View File

@ -0,0 +1,6 @@
package pojo
const (
STATUS_ENABLE int32 = 1
STATUS_DISABLED int32 = 2
)

View File

@ -3,6 +3,7 @@ package data
import (
"PaymentCenter/app/http/entities"
"PaymentCenter/app/models/appmodel"
"database/sql"
"xorm.io/builder"
"xorm.io/xorm"
)
@ -37,3 +38,12 @@ func (m *AppRepo) AppDelete(app *appmodel.App, conn builder.Cond) (int64, error)
func (m *AppRepo) AppUpdate(app *appmodel.App, conn builder.Cond, columns ...string) (int64, error) {
return m.repo.Where(conn).MustCols(columns...).Update(app)
}
func (m *AppRepo) AppFindOne(app *appmodel.App, conn builder.Cond, columns ...string) (*appmodel.App, error) {
has, err := m.repo.Where(conn).Get(app)
if !has {
return nil, sql.ErrNoRows
}
return app, err
}

View File

@ -207,3 +207,7 @@ func phoneValidation(fl validator.FieldLevel) bool {
reg := regexp.MustCompile(phoneRegex)
return reg.MatchString(phone)
}
func ErrWithCode(c *gin.Context, code int) {
Error(c, code, errorcode.GetMsg(code, c.GetHeader("local")))
}

View File

@ -1,8 +1,8 @@
package front
type PayCommonBody struct {
AppId string `json:"app_id" validate:"required"`
Timestamp int64 `json:"timestamp" validate:"required"`
AppId int64 `json:"app_id" validate:"required"`
Timestamp int64 `json:"timestamp" validate:"required"`
}
type PayWeb struct {

View File

@ -4,8 +4,10 @@ import (
"PaymentCenter/app/constants/common"
"PaymentCenter/app/constants/errorcode"
"PaymentCenter/app/http/controllers"
"PaymentCenter/app/http/entities"
"PaymentCenter/app/http/entities/front"
"PaymentCenter/app/http/requestmapping"
"PaymentCenter/app/services"
"PaymentCenter/app/utils"
"context"
"errors"
@ -109,9 +111,32 @@ func ValidatePayRequest() gin.HandlerFunc {
return func(c *gin.Context) {
com, err := utils.SonicApiDataToStruct(controllers.GetRequest(c), &front.PayCommonBody{})
if err != nil {
controllers.Error(c, errorcode.ParamError, err.Error())
controllers.ErrWithCode(c, errorcode.ParamError)
}
comStruct := com.(*front.PayCommonBody)
//判断时间
//now := time.Now().UnixNano() / 1000000
//if comStruct.Timestamp > now || (config.GetConf().TimeOut != 0 && (now-comStruct.Timestamp) > config.GetConf().TimeOut) {
// controllers.ErrWithCode(c, errorcode.RequestTimeOut)
// return
//}
//获取app信息
app, errCode := services.AppFindOne(entities.IdRequest{Id: comStruct.AppId})
if errCode != errorcode.Success {
controllers.ErrWithCode(c, errCode)
return
}
//检查app可用性
appCheck := services.NewAppCheck(app).Check()
if appCheck.GetCode() != errorcode.Success {
controllers.ErrWithCode(c, appCheck.GetCode())
return
}
//检查白名单
if !appCheck.IpCheck(c.ClientIP()) {
controllers.ErrWithCode(c, appCheck.GetCode())
return
}
com = com.(*front.PayCommonBody)
c.Next()
}

View File

@ -15,10 +15,10 @@ var (
type App struct {
Id int64
MerchantId int64 `xorm:"'merchant_id' bigint(20)"`
AppName string `xorm:"'app_name' varchar(128)"`
AppRemark string `xorm:"'app_remark' varchar(255)"`
Status int `xorm:"'status' int(11)"`
KeyType int `xorm:"'key_type' int(11)"`
AppName string `xorm:"'app_name' varchar(20)"`
AppRemark string `xorm:"'app_remark' varchar(200)"`
Status int32 `xorm:"'status' tinyint(2)"`
KeyType int32 `xorm:"'key_type' tinyint(2)"`
PublicKey string `xorm:"'public_key' varchar(1024)"`
PrivateKey string `xorm:"'private_key' varchar(1024)"`
MerchantPublicKey string `xorm:"'merchant_public_key' varchar(1024)"`

View File

@ -1,5 +1,47 @@
package services
func validIp(ip string) bool {
import (
"PaymentCenter/app/constants/errorcode"
"PaymentCenter/app/constants/pojo"
"PaymentCenter/app/models/appmodel"
"PaymentCenter/app/utils"
"strings"
)
type AppCheck struct {
App *appmodel.App
Code int
}
func NewAppCheck(app *appmodel.App) *AppCheck {
return &AppCheck{
App: app,
Code: errorcode.Success,
}
}
func (a *AppCheck) IpCheck(ip string) bool {
if a.App.WhiteIp == "" {
return true
}
if !utils.ContainsString(strings.Split(a.App.WhiteIp, ","), ip) {
a.Code = errorcode.AppIpNotAllow
return false
}
return true
}
func (a *AppCheck) Check() *AppCheck {
if a.App.Status == pojo.STATUS_DISABLED {
a.Code = errorcode.AppDisabled
}
if a.App.DeleteTime.Location() == nil {
a.Code = errorcode.AppNotFound
}
return a
}
func (a *AppCheck) GetCode() int {
return a.Code
}

View File

@ -0,0 +1,17 @@
package apicrypt
import "PaymentCenter/app/models/appmodel"
func NewRsa(app *appmodel.App) ApiDecrypt {
return &Rsa{
App: app,
}
}
func (r *Rsa) Encrypt(decryptData interface{}) (encryptData string, err error) {
return
}
func (r *Rsa) Decrypt(encryptData string) (decryptData map[string]interface{}, err error) {
return
}

View File

@ -0,0 +1,9 @@
package apicrypt
func (r *SM2) Encrypt(decryptData interface{}) (encryptData string, err error) {
return
}
func (r *SM2) Decrypt(encryptData string) (decryptData map[string]interface{}, err error) {
return
}

View File

@ -0,0 +1,9 @@
package apicrypt
func (r *SM4) Encrypt(decryptData interface{}) (encryptData string, err error) {
return
}
func (r *SM4) Decrypt(encryptData string) (decryptData map[string]interface{}, err error) {
return
}

View File

@ -0,0 +1,22 @@
package apicrypt
import "PaymentCenter/app/models/appmodel"
type (
ApiDecrypt interface {
Encrypt(decryptData interface{}) (encryptData string, err error)
Decrypt(encryptData string) (decryptData map[string]interface{}, err error)
}
Rsa struct {
App *appmodel.App
}
SM2 struct {
App *appmodel.App
}
SM4 struct {
App *appmodel.App
}
)

View File

@ -8,6 +8,7 @@ import (
"PaymentCenter/app/models/appmodel"
"PaymentCenter/app/models/merchantmodel"
"PaymentCenter/app/models/paychannelmodel"
"database/sql"
"xorm.io/builder"
)
@ -84,3 +85,20 @@ func AppDelete(req entities.IdRequest) (code int) {
code = handErr(err)
return
}
func AppFindOne(req entities.IdRequest, col ...string) (row *appmodel.App, code int) {
repo := data.NewAppRepo(paychannelmodel.GetInstance().GetDb())
// 拼接查询条件
conn := builder.NewCond()
conn = conn.And(builder.Eq{"Id": req.Id})
m := appmodel.App{Id: req.Id}
row, err := repo.AppFindOne(&m, conn, col...)
if err != nil {
if err == sql.ErrNoRows {
return nil, errorcode.AppNotFound
}
return row, errorcode.SystemError
}
return row, errorcode.Success
}

View File

@ -4,6 +4,7 @@ import (
"encoding/base64"
"fmt"
"testing"
"time"
)
const (
@ -13,7 +14,8 @@ const (
)
func TestRsaEncrypt(t *testing.T) {
fmt.Printf("%s\n", encrypt())
fmt.Println(time.Now().UnixNano() / (1000000))
//fmt.Printf("%s\n", encrypt())
}
func TestRsaDecrypt(t *testing.T) {

View File

@ -431,3 +431,12 @@ func SonicApiDataToStruct(data interface{}, structInterFace interface{}) (dataSt
err = sonic.Unmarshal(bytes, &structInterFace)
return structInterFace, err
}
func ContainsString(slice []string, s string) bool {
for _, item := range slice {
if item == s {
return true
}
}
return false
}

View File

@ -22,6 +22,7 @@ type Config struct {
Debug bool `toml:"Debug"`
PrometheusCollectEnable bool `toml:"PrometheusCollectEnable"`
SkyWalkingOapServer string `toml:"SkyWalkingOapServer"`
TimeOut int64 `toml:"TimeOut"`
Log config.LogConfig `toml:"Log"`
Redis config.RedisConfig `toml:"Redis"`
Mns config.MnsConfig `toml:"AliMns"`