Update a few dependencies

github.com/go-openapi/*
github.com/asaskevich/govalidator
This commit is contained in:
Mikhail Mazurskiy
2018-10-18 23:33:10 +11:00
parent b8731a76f0
commit 8763223ab9
191 changed files with 18648 additions and 1800 deletions

View File

@@ -15,7 +15,6 @@
package validate
import (
"log"
"reflect"
"regexp"
"strings"
@@ -47,9 +46,7 @@ func (o *objectValidator) Applies(source interface{}, kind reflect.Kind) bool {
// there is a problem in the type validator where it will be unhappy about null values
// so that requires more testing
r := reflect.TypeOf(source) == specSchemaType && (kind == reflect.Map || kind == reflect.Struct)
if Debug {
log.Printf("object validator for %q applies %t for %T (kind: %v)\n", o.Path, r, source, kind)
}
debugLog("object validator for %q applies %t for %T (kind: %v)\n", o.Path, r, source, kind)
return r
}
@@ -57,6 +54,7 @@ func (o *objectValidator) isPropertyName() bool {
p := strings.Split(o.Path, ".")
return p[len(p)-1] == "properties" && p[len(p)-2] != "properties"
}
func (o *objectValidator) checkArrayMustHaveItems(res *Result, val map[string]interface{}) {
if t, typeFound := val["type"]; typeFound {
if tpe, ok := t.(string); ok && tpe == "array" {
@@ -82,26 +80,31 @@ func (o *objectValidator) checkItemsMustBeTypeArray(res *Result, val map[string]
}
}
}
func (o *objectValidator) precheck(res *Result, val map[string]interface{}) {
o.checkArrayMustHaveItems(res, val)
o.checkItemsMustBeTypeArray(res, val)
}
func (o *objectValidator) Validate(data interface{}) *Result {
val := data.(map[string]interface{})
// TODO: guard against nil data
numKeys := int64(len(val))
if o.MinProperties != nil && numKeys < *o.MinProperties {
return sErr(errors.TooFewProperties(o.Path, o.In, *o.MinProperties))
return errorHelp.sErr(errors.TooFewProperties(o.Path, o.In, *o.MinProperties))
}
if o.MaxProperties != nil && numKeys > *o.MaxProperties {
return sErr(errors.TooManyProperties(o.Path, o.In, *o.MaxProperties))
return errorHelp.sErr(errors.TooManyProperties(o.Path, o.In, *o.MaxProperties))
}
res := new(Result)
o.precheck(res, val)
// check validity of field names
if o.AdditionalProperties != nil && !o.AdditionalProperties.Allows {
// Case: additionalProperties: false
for k := range val {
_, regularProperty := o.Properties[k]
matched := false
@@ -112,45 +115,102 @@ func (o *objectValidator) Validate(data interface{}) *Result {
break
}
}
if !regularProperty && k != "$schema" && k != "id" && !matched {
// Special properties "$schema" and "id" are ignored
res.AddErrors(errors.PropertyNotAllowed(o.Path, o.In, k))
// BUG(fredbi): This section should move to a part dedicated to spec validation as
// it will conflict with regular schemas where a property "headers" is defined.
//
// Croaks a more explicit message on top of the standard one
// on some recognized cases.
//
// NOTE: edge cases with invalid type assertion are simply ignored here.
// NOTE: prefix your messages here by "IMPORTANT!" so there are not filtered
// by higher level callers (the IMPORTANT! tag will be eventually
// removed).
switch k {
// $ref is forbidden in header
case "headers":
if val[k] != nil {
if headers, mapOk := val[k].(map[string]interface{}); mapOk {
for headerKey, headerBody := range headers {
if headerBody != nil {
if headerSchema, mapOfMapOk := headerBody.(map[string]interface{}); mapOfMapOk {
if _, found := headerSchema["$ref"]; found {
var msg string
if refString, stringOk := headerSchema["$ref"].(string); stringOk {
msg = strings.Join([]string{", one may not use $ref=\":", refString, "\""}, "")
}
res.AddErrors(refNotAllowedInHeaderMsg(o.Path, headerKey, msg))
}
}
}
}
}
}
/*
case "$ref":
if val[k] != nil {
// TODO: check context of that ref: warn about siblings, check against invalid context
}
*/
}
}
}
} else {
// Cases: no additionalProperties (implying: true), or additionalProperties: true, or additionalProperties: { <<schema>> }
for key, value := range val {
_, regularProperty := o.Properties[key]
// Validates property against "patternProperties" if applicable
// BUG(fredbi): succeededOnce is always false
// NOTE: how about regular properties which do not match patternProperties?
matched, succeededOnce, _ := o.validatePatternProperty(key, value, res)
if !(regularProperty || matched || succeededOnce) {
// Cases: properties which are not regular properties and have not been matched by the PatternProperties validator
if o.AdditionalProperties != nil && o.AdditionalProperties.Schema != nil {
res.Merge(NewSchemaValidator(o.AdditionalProperties.Schema, o.Root, o.Path+"."+key, o.KnownFormats).Validate(value))
// AdditionalProperties as Schema
r := NewSchemaValidator(o.AdditionalProperties.Schema, o.Root, o.Path+"."+key, o.KnownFormats).Validate(value)
res.mergeForField(data.(map[string]interface{}), key, r)
} else if regularProperty && !(matched || succeededOnce) {
// TODO: this is dead code since regularProperty=false here
res.AddErrors(errors.FailedAllPatternProperties(o.Path, o.In, key))
}
}
}
// Valid cases: additionalProperties: true or undefined
}
createdFromDefaults := map[string]bool{}
for pName, pSchema := range o.Properties {
// Property types:
// - regular Property
for pName := range o.Properties {
pSchema := o.Properties[pName] // one instance per iteration
rName := pName
if o.Path != "" {
rName = o.Path + "." + pName
}
// Recursively validates each property against its schema
if v, ok := val[pName]; ok {
r := NewSchemaValidator(&pSchema, o.Root, rName, o.KnownFormats).Validate(v)
res.Merge(r)
res.mergeForField(data.(map[string]interface{}), pName, r)
} else if pSchema.Default != nil {
// If a default value is defined, creates the property from defaults
// NOTE: JSON schema does not enforce default values to be valid against schema. Swagger does.
createdFromDefaults[pName] = true
pName := pName // shaddow
def := pSchema.Default
res.Defaulters = append(res.Defaulters, DefaulterFunc(func() {
val[pName] = def
}))
res.addPropertySchemata(data.(map[string]interface{}), pName, &pSchema)
}
}
// Check required properties
if len(o.Required) > 0 {
for _, k := range o.Required {
if _, ok := val[k]; !ok && !createdFromDefaults[k] {
@@ -160,13 +220,16 @@ func (o *objectValidator) Validate(data interface{}) *Result {
}
}
// Check patternProperties
// TODO: it looks like we have done that twice in many cases
for key, value := range val {
_, regularProperty := o.Properties[key]
matched, succeededOnce, patterns := o.validatePatternProperty(key, value, res)
if !regularProperty && (matched || succeededOnce) {
matched, _ /*succeededOnce*/, patterns := o.validatePatternProperty(key, value, res)
if !regularProperty && (matched /*|| succeededOnce*/) {
for _, pName := range patterns {
if v, ok := o.PatternProperties[pName]; ok {
res.Merge(NewSchemaValidator(&v, o.Root, o.Path+"."+key, o.KnownFormats).Validate(value))
r := NewSchemaValidator(&v, o.Root, o.Path+"."+key, o.KnownFormats).Validate(value)
res.mergeForField(data.(map[string]interface{}), key, r)
}
}
}
@@ -174,6 +237,7 @@ func (o *objectValidator) Validate(data interface{}) *Result {
return res
}
// TODO: succeededOnce is not used anywhere
func (o *objectValidator) validatePatternProperty(key string, value interface{}, result *Result) (bool, bool, []string) {
matched := false
succeededOnce := false
@@ -190,9 +254,11 @@ func (o *objectValidator) validatePatternProperty(key string, value interface{},
}
}
if succeededOnce {
result.Inc()
}
// BUG(fredbi): can't get to here. Should remove dead code (commented out).
//if succeededOnce {
// result.Inc()
//}
return matched, succeededOnce, patterns
}