| 9 | var jsonKeyRegex = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9_]*$`) |
| 10 | |
| 11 | func Validate(filters *QueryFilterSet, table string) error { |
| 12 | if filters == nil { |
| 13 | return nil |
| 14 | } |
| 15 | |
| 16 | if !IsValidLogicalOperator(filters.LogicalOperator) { |
| 17 | return fmt.Errorf("invalid logical_operator '%s': must be 'and' or 'or'", filters.LogicalOperator) |
| 18 | } |
| 19 | |
| 20 | validFields := GetValidFieldsForTable(table) |
| 21 | if len(validFields) == 0 { |
| 22 | return fmt.Errorf("unsupported table for advanced filtering: %s", table) |
| 23 | } |
| 24 | |
| 25 | for _, f := range filters.Filters { |
| 26 | if strings.HasPrefix(f.Field, "meta_data.") && validFields["meta_data"] { |
| 27 | jsonKey := strings.TrimPrefix(f.Field, "meta_data.") |
| 28 | if !jsonKeyRegex.MatchString(jsonKey) { |
| 29 | return fmt.Errorf("invalid JSON key '%s' in field '%s': must match pattern ^[a-zA-Z][a-zA-Z0-9_]*$", jsonKey, f.Field) |
| 30 | } |
| 31 | continue |
| 32 | } |
| 33 | |
| 34 | if !validFields[f.Field] { |
| 35 | return fmt.Errorf("invalid field '%s' for table '%s'", f.Field, table) |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | return nil |
| 40 | } |
| 41 | |
| 42 | func GetValidFieldsForTable(table string) map[string]bool { |
| 43 | switch table { |