github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/pkg/rego/convert/struct.go (about)

     1  package convert
     2  
     3  import (
     4  	"reflect"
     5  	"strings"
     6  
     7  	"github.com/khulnasoft-lab/defsec/pkg/types"
     8  )
     9  
    10  type metadataProvider interface {
    11  	GetMetadata() types.Metadata
    12  }
    13  
    14  var metadataInterface = reflect.TypeOf((*metadataProvider)(nil)).Elem()
    15  
    16  func StructToRego(inputValue reflect.Value) map[string]interface{} {
    17  
    18  	// make sure we have a struct literal
    19  	for inputValue.Type().Kind() == reflect.Ptr || inputValue.Type().Kind() == reflect.Interface {
    20  		if inputValue.IsNil() {
    21  			return nil
    22  		}
    23  		inputValue = inputValue.Elem()
    24  	}
    25  	if inputValue.Type().Kind() != reflect.Struct {
    26  		panic("not a struct")
    27  	}
    28  
    29  	output := make(map[string]interface{}, inputValue.NumField())
    30  
    31  	for i := 0; i < inputValue.NumField(); i++ {
    32  		field := inputValue.Field(i)
    33  		typ := inputValue.Type().Field(i)
    34  		name := typ.Name
    35  		if !typ.IsExported() {
    36  			continue
    37  		}
    38  		if field.Interface() == nil {
    39  			continue
    40  		}
    41  		val := anonymousToRego(reflect.ValueOf(field.Interface()))
    42  		if val == nil {
    43  			continue
    44  		}
    45  		key := strings.ToLower(name)
    46  		if _, ok := field.Interface().(types.Metadata); key == "metadata" && ok {
    47  			continue
    48  		}
    49  		output[strings.ToLower(name)] = val
    50  	}
    51  
    52  	if inputValue.Type().Implements(metadataInterface) {
    53  		returns := inputValue.MethodByName("GetMetadata").Call(nil)
    54  		if metadata, ok := returns[0].Interface().(types.Metadata); ok {
    55  			output["__defsec_metadata"] = metadata.ToRego()
    56  		}
    57  	} else {
    58  		metaVal := inputValue.FieldByName("Metadata")
    59  		if metaVal.Kind() == reflect.Struct {
    60  			if meta, ok := metaVal.Interface().(types.Metadata); ok {
    61  				output["__defsec_metadata"] = meta.ToRego()
    62  			}
    63  		}
    64  
    65  	}
    66  
    67  	return output
    68  }