/* @Time : 2020/4/23 17:44 @Author : gaoshiyao @File : field @Software: GoLand @Des: */ package service import ( "encoding/json" "errors" "fmt" "gitlab.wodcloud.com/apaas/apaas-meshproxy/src/client" "gitlab.wodcloud.com/apaas/apaas-meshproxy/src/config" "gitlab.wodcloud.com/apaas/apaas-meshproxy/src/dao" "gitlab.wodcloud.com/apaas/apaas-meshproxy/src/model" "gitlab.wodcloud.com/apaas/apaas-meshproxy/src/model/request" "gitlab.wodcloud.com/apaas/apaas-meshproxy/src/tools" "gitlab.wodcloud.com/apaas/apaas-meshproxy/src/tools/dataconvertutil" "strconv" "time" ) // 判断是否设置了敏感字段,并有敏感词 func CheckSensitiveField() bool { return true } //获取当日调用次数 返回是否到达当日访问量,是否到达敏感字段访问量 func QueryCallsCount(filter model.ProxyData) (call bool, sensitiveCall bool, err error) { //连接redis redis, err := client.GetRedisClient() if err != nil { return } date := time.Now().Format(config.LocalDateFormat) key := fmt.Sprintf("%d-%s", filter.Apply_id, date) countStr, err := redis.Get(key) if err != nil && err.Error() != `redis: nil` { return } var count int call = true sensitiveCall = true if countStr == "" { expire := GetExpire() err = redis.Set(key, 1, expire) count = 1 } else { count, err = strconv.Atoi(countStr) if err != nil { return } if count+1 > filter.Count { call = false return } //超过允许访问敏感字段次数 if count+1 > filter.Sensitive_count && filter.Sensituve_word != "" { sensitiveCall = false } expire := GetExpire() err = redis.Set(key, count+1, expire) } return } //获取过期时间 func GetExpire() time.Duration { now := time.Now() timeStr := time.Now().AddDate(0, 0, 1).Format("2006-01-02") fmt.Println("timeStr:", timeStr) zero, _ := time.Parse("2006-01-02", timeStr) timeNumber := zero fmt.Println("timeNumber:", timeNumber) subMin := now.Sub(zero) fmt.Println(subMin.Minutes(), "分钟") return subMin } //记录调用痕迹 func RecordCall(proxyData model.ProxyData, status int, res []byte) { acc := dao.Service_request_record{} redis, err := client.GetRedisClient() if err != nil { fmt.Println(err.Error()) return } if status != 200 { acc.Error = string(res[:]) //mjson,_ :=json.Marshal(res) //mString :=string(mjson) //acc.Error = mString } acc.Request_time = tools.JsonTime(time.Now()) acc.Apply_id = proxyData.Apply_id acc.User_id = proxyData.User_id acc.Service_id = proxyData.Service_id acc.Date_day = time.Now().Day() fmt.Println(time.Now().Month().String()) acc.Date_month = int(time.Now().Month()) acc.Date_year = time.Now().Year() acc.Status = status b, _ := json.Marshal(acc) if errs := redis.Conn.RPush(config.CallRecord, b).Err(); errs != nil { err = errs fmt.Println("rpush data to list failed:", errs.Error()) return } fmt.Println("调用记录进入队列") return } //服务调用计次 //func CallCounts(proxyData model.ProxyData) (err error) { // redis, err := client.GetRedisClient() // if err != nil { // fmt.Println(err.Error()) // return // } // date := time.Now().Format(config.LocalDateFormat) // aMonBefore := time.Now().AddDate(0, -1, 0).Format(config.LocalDateFormat) // // str, err := redis.Get(fmt.Sprintf("%s-%d", config.SvcTag, proxyData.Service_id)) // if err != nil && err.Error() != `redis: nil` { // return // } // // dateMap := make(map[string]int) // if str != "" { // err = json.Unmarshal([]byte(str), &dateMap) // if err != nil { // return // } // if _, ok := dateMap[date]; ok { // dateMap[date] = dateMap[date] + 1 // } else { // dateMap[date] = 1 // } // for k, _ := range dateMap { // if tools.CompareDate(k, aMonBefore) { // delete(dateMap, k) // } // } // // } else { // dateMap[date] = 1 // } // content, err := json.Marshal(dateMap) // err = redis.Set(fmt.Sprintf("%s-%d", config.SvcTag, proxyData.Service_id), content, -1) // return //} //服务调用计次 func CallCounts(proxyData model.ProxyData) (err error) { redis, err := client.GetRedisClient() if err != nil { fmt.Println(err.Error()) return } //date := time.Now().Format(config.LocalDateFormat) //aMonBefore := time.Now().AddDate(0, -1, 0).Format(config.LocalDateFormat) str, err := redis.Get(fmt.Sprintf("%s", config.ServiceTag)) if err != nil && err.Error() != `redis: nil` { return } dateMap := make(map[int]int) if str != "" { err = json.Unmarshal([]byte(str), &dateMap) if err != nil { return } if _, ok := dateMap[proxyData.Service_id]; ok { dateMap[proxyData.Service_id] = dateMap[proxyData.Service_id] + 1 } else { dateMap[proxyData.Service_id] = 1 } } else { dateMap[proxyData.Service_id] = 1 } content, err := json.Marshal(dateMap) err = redis.Set(fmt.Sprintf("%s", config.ServiceTag), content, -1) return } /* 申请调用记录 */ func ApplyCallCounts(proxyData model.ProxyData) (err error) { redis, err := client.GetRedisClient() if err != nil { fmt.Println(err.Error()) return } //date := time.Now().Format(config.LocalDateTimeFormat) err = redis.RPush(fmt.Sprintf("%s", config.ApplyTag), proxyData.Apply_id) fmt.Println("rpush data to list failed:", err) return } //过滤返回字段 func FiledFilter(proxyData model.ProxyData, respbody []byte) interface{} { fields := []request.ServiceField{} fields = dataconvertutil.GetResponseField(proxyData.ResFields) _, arrmodel := dataconvertutil.ConvertJson(fields) realData := make(map[string]interface{}) json.Unmarshal(respbody, &realData) if arrmodel != nil && len(arrmodel) != 0 && len(realData) != 0 { return Change(arrmodel[0], realData) } return respbody } //返回申请字段 func Change(model interface{}, returnData interface{}) interface{} { switch t := model.(type) { case map[string]interface{}: // TODO 判定值是否相等 for k, v := range returnData.(map[string]interface{}) { flag := false for k1, v1 := range model.(map[string]interface{}) { if k == k1 { flag = true //Change(v, v1) Change(v1, v) } } // 删除属性 if !flag { fmt.Println("删除属性:", k) delete(returnData.(map[string]interface{}), k) } } break case []interface{}: for k, v := range returnData.([]interface{}) { switch v.(type) { case map[string]interface{}: for _, a2 := range model.([]interface{}) { for k1, v1 := range v.(map[string]interface{}) { flag := false for k2, v2 := range a2.(map[string]interface{}) { if k1 == k2 { flag = true Change(v1, v2) } } // 删除属性 if !flag { fmt.Println("删除属性:", k) delete(v.(map[string]interface{}), k1) } } } break case []interface{}: for _, v2 := range model.([]interface{}) { fmt.Println(v2) Change(v2, v) } break default: // TODO 判断old是否有这个值 fmt.Println("数组类型 |||||||||||||||||||||||||||||||| old=====new=====>: ", model, returnData) } } break default: fmt.Println("old=====new=====>: ", model, returnData) fmt.Println("类型是*******>:", t) } return returnData } //更新调用次数 func UpdateCallsCount(applyId string) (err error) { db, err := client.GetConnect() if err != nil { return } sql := `update service_apply set request_count = request_count+1 where service_apply.service_id = '?'` db.SQL(sql, applyId) return } //返回过滤后的敏感字段 func SensitiveFilter(proxyData model.ProxyData, res interface{}) interface{} { fields := []request.ServiceField{} fields = dataconvertutil.GetResponseField(proxyData.Sensituve_word) _, arrSensituve_word := dataconvertutil.ConvertJson(fields) //if Sensituve_word != nil && len(Sensituve_word) != 0 { // return FilterSensituveField(Sensituve_word, res) //} else if arrSensituve_word != nil && len(arrSensituve_word) != 0 { // return FilterSensituveField(arrSensituve_word, res) //} if arrSensituve_word != nil && len(arrSensituve_word) != 0 { return Change(arrSensituve_word[0], res) } return res } // 过滤敏感字段 func FilterSensituveField(model interface{}, returnData interface{}) (body interface{}) { switch t := model.(type) { case map[string]interface{}: // TODO 判定值是否相等 for k, v := range returnData.(map[string]interface{}) { //flag := false for k1, v1 := range model.(map[string]interface{}) { if k == k1 { //flag = true switch v.(type) { case float64: returnData.(map[string]interface{})[k] = `xxx` case float32: returnData.(map[string]interface{})[k] = `xxx` case int: returnData.(map[string]interface{})[k] = `xxx` case bool: returnData.(map[string]interface{})[k] = `xxx` case string: returnData.(map[string]interface{})[k] = `xxx` default: } FilterSensituveField(v, v1) } } } break case []interface{}: for _, v := range returnData.([]interface{}) { switch v.(type) { case map[string]interface{}: for _, a2 := range model.([]interface{}) { for k1, v1 := range v.(map[string]interface{}) { //flag := false for k2, v2 := range a2.(map[string]interface{}) { if k1 == k2 { //flag = true switch v.(map[string]interface{})[k1].(type) { case string: v.(map[string]interface{})[k1] = `xxx` case float64: v.(map[string]interface{})[k1] = `xxx` case float32: v.(map[string]interface{})[k1] = `xxx` case int: v.(map[string]interface{})[k1] = `xxx` case bool: v.(map[string]interface{})[k1] = `xxx` default: } FilterSensituveField(v1, v2) } } } } break case []interface{}: for _, v2 := range model.([]interface{}) { fmt.Println(v2) FilterSensituveField(v2, v) } break default: // TODO 判断old是否有这个值 fmt.Println("数组类型 |||||||||||||||||||||||||||||||| old=====new=====>: ", model, returnData) } } break default: fmt.Println("old=====new=====>: ", model, returnData) fmt.Println("类型是*******>:", t) } return returnData } // 获取真实地址和返回结构、调用限定次数 func GetRealPath(applyId string) (res model.ProxyData, err error) { db, err := client.GetConnect() if err != nil { return } has, err := db. Select(`service_apply.res_fields as res_fields,service.req_url as req_url,service_request_spcs.count as count,service_safe_config.sensituve_word as sensituve_word ,service_request_spcs.sensitive_count as sensitive_count,service_apply.service_id as service_id,service_apply.id as apply_id,service_apply.user_id as user_id,service.data_service_type1,domains.name`). Table(`service`). Join(`inner`, `service_apply`, `service_apply.service_id = service.id`). Join(`left`, `service_request_spcs`, `service_request_spcs.id = service_apply.request_spcs_id`). Join(`left`, `service_safe_config`, `service_apply.service_id = service_safe_config.service_id`). Join("inner", "domains", "domains.id = service.data_service_type1"). Where(`service_apply.uuid=?`, applyId).Get(&res) if !has { err = errors.New(`未找到发布的服务!`) } return }