MCPcopy Create free account
hub / github.com/chainloop-dev/chainloop / BuildEntSelectorFromJSONFilter

Function BuildEntSelectorFromJSONFilter

pkg/jsonfilter/jsonfilter.go:74–123  ·  view source on GitHub ↗

BuildEntSelectorFromJSONFilter constructs an Ent SQL predicate for JSON filtering.

(jsonFilter *JSONFilter)

Source from the content-addressed store, hash-verified

72
73// BuildEntSelectorFromJSONFilter constructs an Ent SQL predicate for JSON filtering.
74func BuildEntSelectorFromJSONFilter(jsonFilter *JSONFilter) (*entsql.Predicate, error) {
75 if jsonFilter.Column == "" || jsonFilter.Operator == "" {
76 return nil, errors.New("invalid filter: column and operator are required")
77 }
78
79 // Validate the column before it reaches the SQL builder. Like the field
80 // path, the column is emitted into the query by the ent sqljson helpers
81 // without reliable escaping, so an unsafe value would allow SQL injection.
82 if err := validateColumn(jsonFilter.Column); err != nil {
83 return nil, err
84 }
85
86 // Validate the field path before it reaches the SQL builder. The ent
87 // sqljson helpers concatenate the path segments unescaped into the query,
88 // so an unsafe value would allow SQL injection.
89 if err := validateFieldPath(jsonFilter.FieldPath); err != nil {
90 return nil, err
91 }
92
93 // Convert the dot notation to the path that Ent expects.
94 dotPath := sqljson.DotPath(jsonFilter.FieldPath)
95
96 // Build the predicate based on the operator.
97 switch jsonFilter.Operator {
98 case OpEQ:
99 return sqljson.ValueEQ(jsonFilter.Column, jsonFilter.Value, dotPath), nil
100 case OpNEQ:
101 return sqljson.ValueNEQ(jsonFilter.Column, jsonFilter.Value, dotPath), nil
102 case OpIN:
103 // Parse the jsonFilter.Value into a string
104 castedValue, ok := jsonFilter.Value.(string)
105 if !ok {
106 return nil, errors.New("invalid value for 'in' operator: must be a slice of strings")
107 }
108
109 // Split the string into a slice of strings by comma.
110 values := strings.Split(castedValue, ",")
111
112 // Trim the spaces from each value and transform them into a slice of any needed for the predicate.
113 inputValue := make([]any, 0, len(values))
114 for _, value := range values {
115 inputValue = append(inputValue, strings.TrimSpace(value))
116 }
117
118 // Create the predicate.
119 return sqljson.ValueIn(jsonFilter.Column, inputValue, dotPath), nil
120 default:
121 return nil, fmt.Errorf("unsupported operator: %s", jsonFilter.Operator)
122 }
123}
124
125// validateColumn ensures the JSON column is a bare SQL identifier before it is
126// emitted into the query by the ent sqljson helpers. Callers are expected to set

Callers 2

applyWorkflowFiltersFunction · 0.92

Calls 2

validateColumnFunction · 0.85
validateFieldPathFunction · 0.85

Tested by 1