Albirew/nyaa-pantsu
Albirew
/
nyaa-pantsu
Archivé
1
0
Bifurcation 0
Ce dépôt a été archivé le 2022-05-07. Vous pouvez voir ses fichiers ou le cloner, mais pas ouvrir de ticket ou de demandes d'ajout, ni soumettre de changements.
nyaa-pantsu/utils/validator/validator.go

170 lignes
6.0 KiB
Go

package validator
import (
"fmt"
"reflect"
"time"
"unicode"
"strconv"
"github.com/NyaaPantsu/nyaa/utils/log"
msg "github.com/NyaaPantsu/nyaa/utils/messages"
"github.com/go-playground/validator"
)
var validate *validator.Validate
func init() {
validate = validator.New()
validate.RegisterValidation("isutf", IsUTFLetterNumericValidator)
validate.RegisterValidation("default", DefaultValidator)
}
// ValidateForm : Check if a form is valid according to its tags
func ValidateForm(form interface{}, mes *msg.Messages) {
err := validate.Struct(form)
if err != nil {
for _, fieldError := range err.(validator.ValidationErrors) {
switch fieldError.Tag() {
case "required":
mes.AddErrorTf(fieldError.Field(), "error_field_needed", fieldError.Field())
case "eq":
mes.AddErrorTf(fieldError.Field(), "error_equal", fieldError.Field(), fieldError.Param())
case "ne", "nefield", "necsfield":
mes.AddErrorTf(fieldError.Field(), "error_not_equal", fieldError.Field(), fieldError.Param())
case "eqfield", "eqcsfield":
mes.AddErrorTf(fieldError.Field(), "error_same_value", fieldError.Field(), fieldError.Param())
case "gtfield", "gtcsfield":
mes.AddErrorTf(fieldError.Field(), "error_greater_number", fieldError.Field(), fieldError.Param())
case "ltfield", "ltcsfield":
mes.AddErrorTf(fieldError.Field(), "error_less_number", fieldError.Field(), fieldError.Param())
case "gtefield", "gtecsfield":
mes.AddErrorTf(fieldError.Field(), "error_min_field", fieldError.Field(), fieldError.Param())
case "ltefield", "ltecsfield":
mes.AddErrorTf(fieldError.Field(), "error_max_field", fieldError.Field(), fieldError.Param())
case "alpha":
mes.AddErrorTf(fieldError.Field(), "error_alpha", fieldError.Field())
case "alphanum":
mes.AddErrorTf(fieldError.Field(), "error_alphanum", fieldError.Field())
case "numeric":
mes.AddErrorTf(fieldError.Field(), "error_numeric_valid", fieldError.Field())
case "number":
mes.AddErrorTf(fieldError.Field(), "error_number_valid", fieldError.Field())
case "hexadecimal":
mes.AddErrorTf(fieldError.Field(), "error_hexadecimal_valid", fieldError.Field())
case "hexcolor":
mes.AddErrorTf(fieldError.Field(), "error_hex_valid", fieldError.Field())
case "rgb":
mes.AddErrorTf(fieldError.Field(), "error_rgb_valid", fieldError.Field())
case "rgba":
mes.AddErrorTf(fieldError.Field(), "error_rgba_valid", fieldError.Field())
case "hsl":
mes.AddErrorTf(fieldError.Field(), "error_hsl_valid", fieldError.Field())
case "hsla":
mes.AddErrorTf(fieldError.Field(), "error_hsla_valid", fieldError.Field())
case "url":
mes.AddErrorTf(fieldError.Field(), "error_url_valid", fieldError.Field())
case "uri":
mes.AddErrorTf(fieldError.Field(), "error_uri_valid", fieldError.Field())
case "base64":
mes.AddErrorTf(fieldError.Field(), "error_base64_valid", fieldError.Field())
case "contains":
mes.AddErrorTf(fieldError.Field(), "error_contains", fieldError.Field(), fieldError.Param())
case "containsany":
mes.AddErrorTf(fieldError.Field(), "error_contains_any", fieldError.Field(), fieldError.Param())
case "excludes":
mes.AddErrorTf(fieldError.Field(), "error_excludes", fieldError.Field(), fieldError.Param())
case "excludesall":
mes.AddErrorTf(fieldError.Field(), "error_excludes_all", fieldError.Field(), fieldError.Param())
case "excludesrune":
mes.AddErrorTf(fieldError.Field(), "error_excludes_rune", fieldError.Field(), fieldError.Param())
case "iscolor":
mes.AddErrorTf(fieldError.Field(), "error_color_valid", fieldError.Field())
default:
switch fieldError.Kind() {
case reflect.String:
stringErrors(fieldError, mes)
case reflect.Slice, reflect.Map, reflect.Array:
case reflect.Struct:
if fieldError.Type() != reflect.TypeOf(time.Time{}) {
fmt.Printf("tag '%s' cannot be used on a struct type.", fieldError.Tag())
mes.AddErrorTf(fieldError.Field(), "error_field", fieldError.Field())
}
dateErrors(fieldError, mes)
default:
numberErrors(fieldError, mes)
}
}
}
}
}
// Bind a validated form to a model, tag omit to not bind a field
func Bind(model interface{}, form interface{}) {
modelIndirect := reflect.Indirect(reflect.ValueOf(model))
formElem := reflect.ValueOf(form).Elem()
typeOfTForm := formElem.Type()
for i := 0; i < formElem.NumField(); i++ {
tag := typeOfTForm.Field(i).Tag
if tag.Get("omit") != "true" {
modelField := modelIndirect.FieldByName(typeOfTForm.Field(i).Name)
if modelField.IsValid() {
formField := formElem.Field(i)
modelField.Set(formField)
} else {
log.Warnf("modelField : %s - %s", typeOfTForm.Field(i).Name, modelField)
}
}
}
}
// IsUTFLetterNumeric check if the string contains only unicode letters and numbers. Empty string is valid.
func IsUTFLetterNumeric(str string) bool {
if len(str) == 0 {
return true
}
for _, c := range str {
if !unicode.IsLetter(c) && !unicode.IsNumber(c) { //letters && numbers are ok
return false
}
}
return true
}
// IsUTFLetterNumericValidator is an interface to IsUTFLetterNumeric from validator
func IsUTFLetterNumericValidator(fl validator.FieldLevel) bool {
value := fl.Field().String() // value
return IsUTFLetterNumeric(value)
}
// DefaultValidator default validator
func DefaultValidator(fl validator.FieldLevel) bool {
switch fl.Field().Kind() {
case reflect.String:
if len(fl.Field().String()) == 0 {
fl.Field().SetString(fl.Param())
}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if fl.Field().Int() == 0 {
number, err := strconv.Atoi(fl.Param())
if err != nil {
fmt.Printf("Couldn't convert default value for field %s", fl.FieldName())
return false
}
fl.Field().SetInt(int64(number))
}
case reflect.Float32, reflect.Float64:
if fl.Field().Float() == 0 {
number, err := strconv.ParseFloat(fl.Param(), 64)
if err != nil {
fmt.Printf("Couldn't convert default value for field %s", fl.FieldName())
return false
}
fl.Field().SetFloat(number)
}
}
return true
}