Skip to content

Commit

Permalink
chore: validate search host condition (#7971)
Browse files Browse the repository at this point in the history
  • Loading branch information
wcy00000000000000 committed May 13, 2024
1 parent 3626d83 commit f87ae1e
Showing 1 changed file with 140 additions and 3 deletions.
143 changes: 140 additions & 3 deletions src/scene_server/host_server/logics/hostsearch.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ package logics

import (
"context"
"fmt"
"net/http"
"sort"
"strconv"
Expand All @@ -32,7 +33,9 @@ import (
// SearchHost TODO
func (lgc *Logics) SearchHost(kit *rest.Kit, data *metadata.HostCommonSearch) (*metadata.SearchHost, error) {
searchHostInst := NewSearchHost(kit, lgc, data)
searchHostInst.ParseCondition()
if err := searchHostInst.ParseCondition(); err != nil {
return nil, err
}
retHostInfo := &metadata.SearchHost{
Info: make([]mapstr.MapStr, 0),
}
Expand Down Expand Up @@ -131,7 +134,7 @@ type appLevelInfo struct {

// searchHostInterface Too many methods, hiding private methods
type searchHostInterface interface {
ParseCondition()
ParseCondition() error
SearchHostByConds() errors.CCError
FillTopologyData() ([]mapstr.MapStr, int, errors.CCError)
}
Expand All @@ -155,9 +158,13 @@ func NewSearchHost(kit *rest.Kit, lgc *Logics, hostSearchParam *metadata.HostCom
}

// ParseCondition TODO
func (sh *searchHost) ParseCondition() {
func (sh *searchHost) ParseCondition() error {

for _, object := range sh.hostSearchParam.Condition {
if err := sh.validateObjCond(&object); err != nil {
return err
}

if object.ObjectID == common.BKInnerObjIDHost {
sh.conds.hostCond = object
} else if object.ObjectID == common.BKInnerObjIDSet {
Expand All @@ -181,6 +188,136 @@ func (sh *searchHost) ParseCondition() {

sh.tryParseAppID()

return nil
}

func (sh *searchHost) validateObjCond(objCond *metadata.SearchCondition) error {
attributes, err := sh.lgc.SearchObjectAttributes(sh.kit, sh.hostSearchParam.AppID, objCond.ObjectID)
if err != nil {
blog.Errorf("search %s obj attr for validation failed, err: %v, rid: %s", objCond.ObjectID, err, sh.kit.Rid)
return err
}

attributeMap := make(map[string]string)
for _, attribute := range attributes {
attributeMap[attribute.PropertyID] = attribute.PropertyType
}

switch objCond.ObjectID {
case common.BKInnerObjIDApp:
attributeMap[common.BKAppIDField] = common.FieldTypeInt
attributeMap[common.BKDefaultField] = common.FieldTypeInt
case common.BKInnerObjIDSet:
attributeMap[common.BKSetIDField] = common.FieldTypeInt
case common.BKInnerObjIDModule:
attributeMap[common.BKModuleIDField] = common.FieldTypeInt
case common.BKInnerObjIDHost:
attributeMap[common.BKHostIDField] = common.FieldTypeInt
attributeMap[common.BKCloudIDField] = common.FieldTypeInt
}

for _, cond := range objCond.Condition {
attrType, exists := attributeMap[cond.Field]
if !exists {
blog.Errorf("%s condition item field %s not exists, rid: %s", objCond.ObjectID, cond.Field, sh.kit.Rid)
return fmt.Errorf("condition field %s not exists", cond.Field)
}

supportedOpMap, exists := attrTypeSupportedOpMap[attrType]
if !exists {
blog.Errorf("%s condition item field %s attr type %s is invalid, rid: %s", objCond.ObjectID, cond.Field,
attrType, sh.kit.Rid)
return fmt.Errorf("condition field %s is invalid", cond.Field)
}

_, exists = supportedOpMap[cond.Operator]
if !exists {
blog.Errorf("%s condition item field %s op %s is invalid, rid: %s", objCond.ObjectID, cond.Field,
cond.Operator, sh.kit.Rid)
return fmt.Errorf("condition operator %s is invalid", cond.Operator)
}

switch cond.Operator {
case common.BKDBIN, common.BKDBNIN:
valueArr, ok := cond.Value.([]interface{})
if !ok {
blog.Errorf("%s condition item field %s op %s value(%+v) is invalid, rid: %s", objCond.ObjectID,
cond.Field, cond.Operator, cond.Value, sh.kit.Rid)
return fmt.Errorf("operator %s only support array value", cond.Operator)
}

for _, value := range valueArr {
if err = sh.validCondValueType(attrType, value); err != nil {
blog.Errorf("%s condition item field %s array value(%+v) is invalid, err: %v, rid: %s",
objCond.ObjectID, cond.Field, value, err, sh.kit.Rid)
return err
}
}
default:
if err = sh.validCondValueType(attrType, cond.Value); err != nil {
blog.Errorf("%s condition item field %s value(%+v) is invalid, err: %v, rid: %s", objCond.ObjectID,
cond.Field, cond.Value, err, sh.kit.Rid)
return err
}
}
}
return nil
}

var attrTypeSupportedOpMap = make(map[string]map[string]struct{})

func init() {
commonOps := []string{common.BKDBIN, common.BKDBNIN, common.BKDBEQ, common.BKDBNE}

commonOpMap := make(map[string]struct{})
for _, op := range commonOps {
commonOpMap[op] = struct{}{}
}

commonAttrTypes := []string{common.FieldTypeBool, common.FieldTypeOrganization}
for _, attrType := range commonAttrTypes {
attrTypeSupportedOpMap[attrType] = commonOpMap
}

strOpMap := make(map[string]struct{})
for _, op := range append(commonOps, common.BKDBLIKE) {
strOpMap[op] = struct{}{}
}

strAttrTypes := []string{common.FieldTypeSingleChar, common.FieldTypeEnum, common.FieldTypeEnumMulti,
common.FieldTypeDate, common.FieldTypeTime, common.FieldTypeLongChar, common.FieldTypeUser,
common.FieldTypeTimeZone, common.FieldTypeList}
for _, attrType := range strAttrTypes {
attrTypeSupportedOpMap[attrType] = strOpMap
}

numericOpMap := make(map[string]struct{})
for _, op := range append(commonOps, common.BKDBGT, common.BKDBGTE, common.BKDBLT, common.BKDBLTE) {
numericOpMap[op] = struct{}{}
}

numericAttrTypes := []string{common.FieldTypeInt, common.FieldTypeFloat}
for _, attrType := range numericAttrTypes {
attrTypeSupportedOpMap[attrType] = numericOpMap
}
}

func (sh *searchHost) validCondValueType(attrType string, value interface{}) error {
switch attrType {
case common.FieldTypeInt, common.FieldTypeFloat, common.FieldTypeOrganization:
if !util.IsNumeric(value) {
return fmt.Errorf("%s attribute type only support numeric value", attrType)
}
case common.FieldTypeBool:
if _, ok := value.(bool); !ok {
return fmt.Errorf("%s attribute type only support bool value", attrType)
}
default:
if _, ok := value.(string); !ok {
return fmt.Errorf("%s attribute type only support string value", attrType)
}
}
return nil
}

// SearchHostByConds TODO
Expand Down

0 comments on commit f87ae1e

Please sign in to comment.