data_mask/filter/filter.go

179 lines
4.4 KiB
Go
Raw Normal View History

2024-04-07 22:15:10 +08:00
// Package filter ...
//
// Description : filter ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-04-07 21:59
package filter
import (
"errors"
"fmt"
2024-04-07 22:37:14 +08:00
"git.zhangdeman.cn/zhangdeman/data_mask"
2024-04-07 22:15:10 +08:00
"git.zhangdeman.cn/zhangdeman/data_mask/define"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
"strings"
)
// Execute 数据转换
//
// Author : go_developer@163.com<张德满>
//
// Date : 12:39 2024/3/26
func Execute(sourceData string, convertRule []*define.FilterRule) *Transform {
sourceData = strings.TrimSpace(sourceData)
t := &Transform{
sourceData: sourceData,
ruleList: convertRule,
result: "{}",
}
return t
}
// Transform 转换
//
// Author : go_developer@163.com<张德满>
//
// Date : 10:56 2024/3/27
type Transform struct {
sourceData string
ruleList []*define.FilterRule
result string
}
// Execute 执行
//
// Author : go_developer@163.com<张德满>
//
// Date : 10:57 2024/3/27
func (t *Transform) Execute() error {
sourceResult := gjson.Parse(t.sourceData)
if !sourceResult.IsObject() {
return errors.New("source data is not object")
}
if err := t.checkRule(); nil != err {
return err
}
for _, itemRule := range t.ruleList {
if err := t.rewrite(itemRule); nil != err {
return err
}
}
return nil
}
// GetResult 获取处理结果
//
// Author : go_developer@163.com<张德满>
//
// Date : 11:32 2024/3/27
func (t *Transform) GetResult() string {
return t.result
}
// checkRule 校验规则
//
// Author : go_developer@163.com<张德满>
//
// Date : 11:18 2024/3/27
func (t *Transform) checkRule() error {
for _, itemRule := range t.ruleList {
itemRule.SourceDataPath = strings.TrimRight(itemRule.SourceDataPath, ".[]")
itemRule.TargetDataPath = strings.TrimRight(itemRule.TargetDataPath, ".[]")
fromPathArr := strings.Split(itemRule.SourceDataPath, "[]")
targetPathArr := strings.Split(itemRule.TargetDataPath, "[]")
if len(targetPathArr) > len(fromPathArr) {
return errors.New("slice path config invalid : " + itemRule.SourceDataPath + " -> " + itemRule.TargetDataPath)
}
}
return nil
}
// rewrite 数据重写
//
// Author : go_developer@163.com<张德满>
//
// Date : 11:25 2024/3/27
func (t *Transform) rewrite(rule *define.FilterRule) error {
var (
err error
)
sourceResult := gjson.Get(t.sourceData, rule.SourceDataPath)
if !sourceResult.Exists() {
if rule.IsRequired {
return errors.New(rule.SourceDataPath + " is not exist, but required")
}
if strings.Contains(rule.SourceDataPath, "[]") {
return t.rewriteForSlice(rule)
}
2024-04-08 17:31:18 +08:00
// 走的默认值认为无需脱敏
2024-04-07 22:15:10 +08:00
if t.result, err = sjson.Set(t.result, rule.TargetDataPath, rule.DefaultValue); nil != err {
return err
}
return nil
}
2024-04-07 22:37:14 +08:00
// 数据脱敏
realValue := sourceResult.String()
if len(rule.DataMaskStrategy) > 0 {
if realValue, err = data_mask.ExecuteWithError(realValue, rule.DataMaskStrategy); nil != err {
return err
}
2024-04-08 17:31:18 +08:00
// 一旦执行数据脱敏, 统一以字符串输出
t.result, err = sjson.Set(t.result, rule.TargetDataPath, realValue)
return err
2024-04-07 22:37:14 +08:00
}
// TODO : 格式转换
2024-04-07 22:15:10 +08:00
t.result, err = sjson.Set(t.result, rule.TargetDataPath, sourceResult.Value())
2024-04-07 22:37:14 +08:00
return err
2024-04-07 22:15:10 +08:00
}
// rewriteForSlice 数组重写
//
// Author : go_developer@163.com<张德满>
//
// Date : 15:22 2024/3/27
func (t *Transform) rewriteForSlice(rule *define.FilterRule) error {
2024-04-08 17:31:18 +08:00
var (
err error
)
2024-04-07 22:15:10 +08:00
pathArr := strings.Split(rule.SourceDataPath, ".[].")
sliceUnfoldResult := t.unfoldSourceSliceData(t.sourceData, pathArr[0:len(pathArr)-1], nil)
targetArr := strings.Split(rule.TargetDataPath, ".[].")
for idx, itemRes := range sliceUnfoldResult {
2024-04-08 17:31:18 +08:00
if t.result, err = sjson.Set(t.result, fmt.Sprintf("%v.%v.%v", targetArr[0], idx, targetArr[1]), itemRes.Get(pathArr[len(pathArr)-1]).Value()); nil != err {
return err
}
2024-04-07 22:15:10 +08:00
}
return nil
}
// unfoldSourceSliceData 展开元数据的数组, 平铺
//
// Author : go_developer@163.com<张德满>
//
// Date : 17:39 2024/3/27
func (t *Transform) unfoldSourceSliceData(sourceData string, pathList []string, res []gjson.Result) []gjson.Result {
if nil == res {
res = make([]gjson.Result, 0)
}
arrRes := gjson.Get(sourceData, pathList[0]).Array()
if len(pathList) == 1 {
for _, itemRes := range arrRes {
res = append(res, itemRes)
}
return res
}
for i := 0; i < len(arrRes)-1; i++ {
res = t.unfoldSourceSliceData(arrRes[i].String(), pathList[1:], res)
}
return t.unfoldSourceSliceData(arrRes[len(arrRes)-1].String(), pathList[1:], res)
}