mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2025-12-31 00:34:25 +00:00
Some validation and header decoding
This commit is contained in:
@@ -93,6 +93,10 @@ func (h *Handler) Handle(w common.ResponseWriter, r common.Request, params map[s
|
||||
// Add request-scoped data to context
|
||||
ctx = WithRequestData(ctx, schema, entity, tableName, model, modelPtr)
|
||||
|
||||
// Validate and filter columns in options (log warnings for invalid columns)
|
||||
validator := common.NewColumnValidator(model)
|
||||
options = filterExtendedOptions(validator, options)
|
||||
|
||||
switch method {
|
||||
case "GET":
|
||||
if id != "" {
|
||||
@@ -750,3 +754,41 @@ func (h *Handler) sendError(w common.ResponseWriter, statusCode int, code, messa
|
||||
w.WriteHeader(statusCode)
|
||||
w.WriteJSON(response)
|
||||
}
|
||||
|
||||
// filterExtendedOptions filters all column references, removing invalid ones and logging warnings
|
||||
func filterExtendedOptions(validator *common.ColumnValidator, options ExtendedRequestOptions) ExtendedRequestOptions {
|
||||
filtered := options
|
||||
|
||||
// Filter base RequestOptions
|
||||
filtered.RequestOptions = validator.FilterRequestOptions(options.RequestOptions)
|
||||
|
||||
// Filter SearchColumns
|
||||
filtered.SearchColumns = validator.FilterValidColumns(options.SearchColumns)
|
||||
|
||||
// Filter AdvancedSQL column keys
|
||||
filteredAdvSQL := make(map[string]string)
|
||||
for colName, sqlExpr := range options.AdvancedSQL {
|
||||
if validator.IsValidColumn(colName) {
|
||||
filteredAdvSQL[colName] = sqlExpr
|
||||
} else {
|
||||
logger.Warn("Invalid column in advanced SQL removed: %s", colName)
|
||||
}
|
||||
}
|
||||
filtered.AdvancedSQL = filteredAdvSQL
|
||||
|
||||
// ComputedQL columns are allowed to be any name since they're computed
|
||||
// No filtering needed for ComputedQL keys
|
||||
filtered.ComputedQL = options.ComputedQL
|
||||
|
||||
// Filter Expand columns
|
||||
filteredExpands := make([]ExpandOption, 0, len(options.Expand))
|
||||
for _, expand := range options.Expand {
|
||||
filteredExpand := expand
|
||||
// Don't validate relation name, only columns
|
||||
filteredExpand.Columns = validator.FilterValidColumns(expand.Columns)
|
||||
filteredExpands = append(filteredExpands, filteredExpand)
|
||||
}
|
||||
filtered.Expand = filteredExpands
|
||||
|
||||
return filtered
|
||||
}
|
||||
|
||||
@@ -57,27 +57,43 @@ type ExpandOption struct {
|
||||
// decodeHeaderValue decodes base64 encoded header values
|
||||
// Supports ZIP_ and __ prefixes for base64 encoding
|
||||
func decodeHeaderValue(value string) string {
|
||||
// Check for ZIP_ prefix
|
||||
if strings.HasPrefix(value, "ZIP_") {
|
||||
decoded, err := base64.StdEncoding.DecodeString(value[4:])
|
||||
if err == nil {
|
||||
return string(decoded)
|
||||
str, _ := DecodeParam(value)
|
||||
return str
|
||||
}
|
||||
|
||||
// DecodeParam - Decodes parameter string and returns unencoded string
|
||||
func DecodeParam(pStr string) (string, error) {
|
||||
var code string = pStr
|
||||
if strings.HasPrefix(pStr, "ZIP_") {
|
||||
code = strings.ReplaceAll(pStr, "ZIP_", "")
|
||||
code = strings.ReplaceAll(code, "\n", "")
|
||||
code = strings.ReplaceAll(code, "\r", "")
|
||||
code = strings.ReplaceAll(code, " ", "")
|
||||
strDat, err := base64.StdEncoding.DecodeString(code)
|
||||
if err != nil {
|
||||
return code, fmt.Errorf("failed to read parameter base64: %v", err)
|
||||
} else {
|
||||
code = string(strDat)
|
||||
}
|
||||
} else if strings.HasPrefix(pStr, "__") {
|
||||
code = strings.ReplaceAll(pStr, "__", "")
|
||||
code = strings.ReplaceAll(code, "\n", "")
|
||||
code = strings.ReplaceAll(code, "\r", "")
|
||||
code = strings.ReplaceAll(code, " ", "")
|
||||
|
||||
strDat, err := base64.StdEncoding.DecodeString(code)
|
||||
if err != nil {
|
||||
return code, fmt.Errorf("failed to read parameter base64: %v", err)
|
||||
} else {
|
||||
code = string(strDat)
|
||||
}
|
||||
logger.Warn("Failed to decode ZIP_ prefixed value: %v", err)
|
||||
return value
|
||||
}
|
||||
|
||||
// Check for __ prefix
|
||||
if strings.HasPrefix(value, "__") {
|
||||
decoded, err := base64.StdEncoding.DecodeString(value[2:])
|
||||
if err == nil {
|
||||
return string(decoded)
|
||||
}
|
||||
logger.Warn("Failed to decode __ prefixed value: %v", err)
|
||||
return value
|
||||
if strings.HasPrefix(code, "ZIP_") || strings.HasPrefix(code, "__") {
|
||||
code, _ = DecodeParam(code)
|
||||
}
|
||||
|
||||
return value
|
||||
return code, nil
|
||||
}
|
||||
|
||||
// parseOptionsFromHeaders parses all request options from HTTP headers
|
||||
|
||||
Reference in New Issue
Block a user