forked from baron/baron-sso
feat: add schema check on bulk user move and support for float/datetime in custom metadata
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -1463,6 +1464,87 @@ func (h *UserHandler) validateMetadataWithAuth(metadata map[string]any, schema [
|
||||
return errors.New("field " + key + " is admin only")
|
||||
}
|
||||
|
||||
// Type validation
|
||||
if expectedType, ok := config["type"].(string); ok && expectedType != "" && val != nil && val != "" {
|
||||
switch expectedType {
|
||||
case "number":
|
||||
var numVal float64
|
||||
switch v := val.(type) {
|
||||
case float64:
|
||||
numVal = v
|
||||
case int:
|
||||
numVal = float64(v)
|
||||
case string:
|
||||
parsed, err := strconv.ParseFloat(v, 64)
|
||||
if err != nil {
|
||||
return errors.New("field " + key + " must be a number")
|
||||
}
|
||||
numVal = parsed
|
||||
default:
|
||||
return errors.New("field " + key + " must be a number")
|
||||
}
|
||||
if float64(int(numVal)) != numVal {
|
||||
return errors.New("field " + key + " must be an integer")
|
||||
}
|
||||
if unsigned, ok := config["unsigned"].(bool); ok && unsigned && numVal < 0 {
|
||||
return errors.New("field " + key + " must be an unsigned integer")
|
||||
}
|
||||
case "float":
|
||||
var numVal float64
|
||||
switch v := val.(type) {
|
||||
case float64:
|
||||
numVal = v
|
||||
case int:
|
||||
numVal = float64(v)
|
||||
case string:
|
||||
parsed, err := strconv.ParseFloat(v, 64)
|
||||
if err != nil {
|
||||
return errors.New("field " + key + " must be a float")
|
||||
}
|
||||
numVal = parsed
|
||||
default:
|
||||
return errors.New("field " + key + " must be a float")
|
||||
}
|
||||
if unsigned, ok := config["unsigned"].(bool); ok && unsigned && numVal < 0 {
|
||||
return errors.New("field " + key + " must be an unsigned float")
|
||||
}
|
||||
case "boolean":
|
||||
switch v := val.(type) {
|
||||
case bool:
|
||||
// ok
|
||||
case string:
|
||||
if v != "true" && v != "false" {
|
||||
return errors.New("field " + key + " must be a boolean")
|
||||
}
|
||||
default:
|
||||
return errors.New("field " + key + " must be a boolean")
|
||||
}
|
||||
case "date":
|
||||
if strVal, ok := val.(string); ok {
|
||||
if _, err := time.Parse("2006-01-02", strVal); err != nil {
|
||||
return errors.New("field " + key + " must be a valid date (YYYY-MM-DD)")
|
||||
}
|
||||
} else {
|
||||
return errors.New("field " + key + " must be a date string")
|
||||
}
|
||||
case "datetime":
|
||||
if strVal, ok := val.(string); ok {
|
||||
_, err1 := time.Parse(time.RFC3339, strVal)
|
||||
_, err2 := time.Parse("2006-01-02T15:04", strVal)
|
||||
_, err3 := time.Parse("2006-01-02T15:04:05", strVal)
|
||||
if err1 != nil && err2 != nil && err3 != nil {
|
||||
return errors.New("field " + key + " must be a valid datetime")
|
||||
}
|
||||
} else {
|
||||
return errors.New("field " + key + " must be a datetime string")
|
||||
}
|
||||
case "text":
|
||||
if _, ok := val.(string); !ok {
|
||||
return errors.New("field " + key + " must be a string")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Regex validation
|
||||
if regexStr, ok := config["validation"].(string); ok && regexStr != "" {
|
||||
strVal := ""
|
||||
|
||||
Reference in New Issue
Block a user