mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-30 20:22:25 -05:00 
			
		
		
		
	[chore] Bump go swagger (#2871)
* bump go swagger version * bump swagger version
This commit is contained in:
		
					parent
					
						
							
								3a369d834a
							
						
					
				
			
			
				commit
				
					
						fd8a724e77
					
				
			
		
					 251 changed files with 10841 additions and 11896 deletions
				
			
		
							
								
								
									
										188
									
								
								vendor/github.com/go-openapi/validate/spec.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										188
									
								
								vendor/github.com/go-openapi/validate/spec.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -15,6 +15,8 @@ | |||
| package validate | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/gob" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"sort" | ||||
|  | @ -26,23 +28,23 @@ import ( | |||
| 	"github.com/go-openapi/loads" | ||||
| 	"github.com/go-openapi/spec" | ||||
| 	"github.com/go-openapi/strfmt" | ||||
| 	"github.com/go-openapi/swag" | ||||
| ) | ||||
| 
 | ||||
| // Spec validates an OpenAPI 2.0 specification document. | ||||
| // | ||||
| // Returns an error flattening in a single standard error, all validation messages. | ||||
| // | ||||
| //  - TODO: $ref should not have siblings | ||||
| //  - TODO: make sure documentation reflects all checks and warnings | ||||
| //  - TODO: check on discriminators | ||||
| //  - TODO: explicit message on unsupported keywords (better than "forbidden property"...) | ||||
| //  - TODO: full list of unresolved refs | ||||
| //  - TODO: validate numeric constraints (issue#581): this should be handled like defaults and examples | ||||
| //  - TODO: option to determine if we validate for go-swagger or in a more general context | ||||
| //  - TODO: check on required properties to support anyOf, allOf, oneOf | ||||
| //   - TODO: $ref should not have siblings | ||||
| //   - TODO: make sure documentation reflects all checks and warnings | ||||
| //   - TODO: check on discriminators | ||||
| //   - TODO: explicit message on unsupported keywords (better than "forbidden property"...) | ||||
| //   - TODO: full list of unresolved refs | ||||
| //   - TODO: validate numeric constraints (issue#581): this should be handled like defaults and examples | ||||
| //   - TODO: option to determine if we validate for go-swagger or in a more general context | ||||
| //   - TODO: check on required properties to support anyOf, allOf, oneOf | ||||
| // | ||||
| // NOTE: SecurityScopes are maps: no need to check uniqueness | ||||
| // | ||||
| func Spec(doc *loads.Document, formats strfmt.Registry) error { | ||||
| 	errs, _ /*warns*/ := NewSpecValidator(doc.Schema(), formats).Validate(doc) | ||||
| 	if errs.HasErrors() { | ||||
|  | @ -53,25 +55,38 @@ func Spec(doc *loads.Document, formats strfmt.Registry) error { | |||
| 
 | ||||
| // SpecValidator validates a swagger 2.0 spec | ||||
| type SpecValidator struct { | ||||
| 	schema       *spec.Schema // swagger 2.0 schema | ||||
| 	spec         *loads.Document | ||||
| 	analyzer     *analysis.Spec | ||||
| 	expanded     *loads.Document | ||||
| 	KnownFormats strfmt.Registry | ||||
| 	Options      Opts // validation options | ||||
| 	schema        *spec.Schema // swagger 2.0 schema | ||||
| 	spec          *loads.Document | ||||
| 	analyzer      *analysis.Spec | ||||
| 	expanded      *loads.Document | ||||
| 	KnownFormats  strfmt.Registry | ||||
| 	Options       Opts // validation options | ||||
| 	schemaOptions *SchemaValidatorOptions | ||||
| } | ||||
| 
 | ||||
| // NewSpecValidator creates a new swagger spec validator instance | ||||
| func NewSpecValidator(schema *spec.Schema, formats strfmt.Registry) *SpecValidator { | ||||
| 	// schema options that apply to all called validators | ||||
| 	schemaOptions := new(SchemaValidatorOptions) | ||||
| 	for _, o := range []Option{ | ||||
| 		SwaggerSchema(true), | ||||
| 		WithRecycleValidators(true), | ||||
| 		// withRecycleResults(true), | ||||
| 	} { | ||||
| 		o(schemaOptions) | ||||
| 	} | ||||
| 
 | ||||
| 	return &SpecValidator{ | ||||
| 		schema:       schema, | ||||
| 		KnownFormats: formats, | ||||
| 		Options:      defaultOpts, | ||||
| 		schema:        schema, | ||||
| 		KnownFormats:  formats, | ||||
| 		Options:       defaultOpts, | ||||
| 		schemaOptions: schemaOptions, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Validate validates the swagger spec | ||||
| func (s *SpecValidator) Validate(data interface{}) (*Result, *Result) { | ||||
| 	s.schemaOptions.skipSchemataResult = s.Options.SkipSchemataResult | ||||
| 	var sd *loads.Document | ||||
| 	errs, warnings := new(Result), new(Result) | ||||
| 
 | ||||
|  | @ -85,11 +100,8 @@ func (s *SpecValidator) Validate(data interface{}) (*Result, *Result) { | |||
| 	s.spec = sd | ||||
| 	s.analyzer = analysis.New(sd.Spec()) | ||||
| 
 | ||||
| 	// Swagger schema validator | ||||
| 	schv := NewSchemaValidator(s.schema, nil, "", s.KnownFormats, SwaggerSchema(true)) | ||||
| 	var obj interface{} | ||||
| 
 | ||||
| 	// Raw spec unmarshalling errors | ||||
| 	var obj interface{} | ||||
| 	if err := json.Unmarshal(sd.Raw(), &obj); err != nil { | ||||
| 		// NOTE: under normal conditions, the *load.Document has been already unmarshalled | ||||
| 		// So this one is just a paranoid check on the behavior of the spec package | ||||
|  | @ -103,6 +115,8 @@ func (s *SpecValidator) Validate(data interface{}) (*Result, *Result) { | |||
| 		warnings.AddErrors(errs.Warnings...) | ||||
| 	}() | ||||
| 
 | ||||
| 	// Swagger schema validator | ||||
| 	schv := newSchemaValidator(s.schema, nil, "", s.KnownFormats, s.schemaOptions) | ||||
| 	errs.Merge(schv.Validate(obj)) // error - | ||||
| 	// There may be a point in continuing to try and determine more accurate errors | ||||
| 	if !s.Options.ContinueOnErrors && errs.HasErrors() { | ||||
|  | @ -130,13 +144,13 @@ func (s *SpecValidator) Validate(data interface{}) (*Result, *Result) { | |||
| 	} | ||||
| 
 | ||||
| 	// Values provided as default MUST validate their schema | ||||
| 	df := &defaultValidator{SpecValidator: s} | ||||
| 	df := &defaultValidator{SpecValidator: s, schemaOptions: s.schemaOptions} | ||||
| 	errs.Merge(df.Validate()) | ||||
| 
 | ||||
| 	// Values provided as examples MUST validate their schema | ||||
| 	// Value provided as examples in a response without schema generate a warning | ||||
| 	// Known limitations: examples in responses for mime type not application/json are ignored (warning) | ||||
| 	ex := &exampleValidator{SpecValidator: s} | ||||
| 	ex := &exampleValidator{SpecValidator: s, schemaOptions: s.schemaOptions} | ||||
| 	errs.Merge(ex.Validate()) | ||||
| 
 | ||||
| 	errs.Merge(s.validateNonEmptyPathParamNames()) | ||||
|  | @ -148,22 +162,27 @@ func (s *SpecValidator) Validate(data interface{}) (*Result, *Result) { | |||
| } | ||||
| 
 | ||||
| func (s *SpecValidator) validateNonEmptyPathParamNames() *Result { | ||||
| 	res := new(Result) | ||||
| 	res := pools.poolOfResults.BorrowResult() | ||||
| 	if s.spec.Spec().Paths == nil { | ||||
| 		// There is no Paths object: error | ||||
| 		res.AddErrors(noValidPathMsg()) | ||||
| 	} else { | ||||
| 		if s.spec.Spec().Paths.Paths == nil { | ||||
| 			// Paths may be empty: warning | ||||
| 			res.AddWarnings(noValidPathMsg()) | ||||
| 		} else { | ||||
| 			for k := range s.spec.Spec().Paths.Paths { | ||||
| 				if strings.Contains(k, "{}") { | ||||
| 					res.AddErrors(emptyPathParameterMsg(k)) | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 		return res | ||||
| 	} | ||||
| 
 | ||||
| 	if s.spec.Spec().Paths.Paths == nil { | ||||
| 		// Paths may be empty: warning | ||||
| 		res.AddWarnings(noValidPathMsg()) | ||||
| 
 | ||||
| 		return res | ||||
| 	} | ||||
| 
 | ||||
| 	for k := range s.spec.Spec().Paths.Paths { | ||||
| 		if strings.Contains(k, "{}") { | ||||
| 			res.AddErrors(emptyPathParameterMsg(k)) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return res | ||||
| } | ||||
| 
 | ||||
|  | @ -177,7 +196,7 @@ func (s *SpecValidator) validateDuplicateOperationIDs() *Result { | |||
| 		// fallback on possible incomplete picture because of previous errors | ||||
| 		analyzer = s.analyzer | ||||
| 	} | ||||
| 	res := new(Result) | ||||
| 	res := pools.poolOfResults.BorrowResult() | ||||
| 	known := make(map[string]int) | ||||
| 	for _, v := range analyzer.OperationIDs() { | ||||
| 		if v != "" { | ||||
|  | @ -199,7 +218,7 @@ type dupProp struct { | |||
| 
 | ||||
| func (s *SpecValidator) validateDuplicatePropertyNames() *Result { | ||||
| 	// definition can't declare a property that's already defined by one of its ancestors | ||||
| 	res := new(Result) | ||||
| 	res := pools.poolOfResults.BorrowResult() | ||||
| 	for k, sch := range s.spec.Spec().Definitions { | ||||
| 		if len(sch.AllOf) == 0 { | ||||
| 			continue | ||||
|  | @ -248,7 +267,7 @@ func (s *SpecValidator) validateSchemaPropertyNames(nm string, sch spec.Schema, | |||
| 
 | ||||
| 	schn := nm | ||||
| 	schc := &sch | ||||
| 	res := new(Result) | ||||
| 	res := pools.poolOfResults.BorrowResult() | ||||
| 
 | ||||
| 	for schc.Ref.String() != "" { | ||||
| 		// gather property names | ||||
|  | @ -285,7 +304,7 @@ func (s *SpecValidator) validateSchemaPropertyNames(nm string, sch spec.Schema, | |||
| } | ||||
| 
 | ||||
| func (s *SpecValidator) validateCircularAncestry(nm string, sch spec.Schema, knowns map[string]struct{}) ([]string, *Result) { | ||||
| 	res := new(Result) | ||||
| 	res := pools.poolOfResults.BorrowResult() | ||||
| 
 | ||||
| 	if sch.Ref.String() == "" && len(sch.AllOf) == 0 { // Safeguard. We should not be able to actually get there | ||||
| 		return nil, res | ||||
|  | @ -335,7 +354,7 @@ func (s *SpecValidator) validateCircularAncestry(nm string, sch spec.Schema, kno | |||
| 
 | ||||
| func (s *SpecValidator) validateItems() *Result { | ||||
| 	// validate parameter, items, schema and response objects for presence of item if type is array | ||||
| 	res := new(Result) | ||||
| 	res := pools.poolOfResults.BorrowResult() | ||||
| 
 | ||||
| 	for method, pi := range s.analyzer.Operations() { | ||||
| 		for path, op := range pi { | ||||
|  | @ -394,7 +413,7 @@ func (s *SpecValidator) validateItems() *Result { | |||
| 
 | ||||
| // Verifies constraints on array type | ||||
| func (s *SpecValidator) validateSchemaItems(schema spec.Schema, prefix, opID string) *Result { | ||||
| 	res := new(Result) | ||||
| 	res := pools.poolOfResults.BorrowResult() | ||||
| 	if !schema.Type.Contains(arrayType) { | ||||
| 		return res | ||||
| 	} | ||||
|  | @ -418,7 +437,7 @@ func (s *SpecValidator) validateSchemaItems(schema spec.Schema, prefix, opID str | |||
| func (s *SpecValidator) validatePathParamPresence(path string, fromPath, fromOperation []string) *Result { | ||||
| 	// Each defined operation path parameters must correspond to a named element in the API's path pattern. | ||||
| 	// (For example, you cannot have a path parameter named id for the following path /pets/{petId} but you must have a path parameter named petId.) | ||||
| 	res := new(Result) | ||||
| 	res := pools.poolOfResults.BorrowResult() | ||||
| 	for _, l := range fromPath { | ||||
| 		var matched bool | ||||
| 		for _, r := range fromOperation { | ||||
|  | @ -456,7 +475,6 @@ func (s *SpecValidator) validateReferenced() *Result { | |||
| 	return &res | ||||
| } | ||||
| 
 | ||||
| // nolint: dupl | ||||
| func (s *SpecValidator) validateReferencedParameters() *Result { | ||||
| 	// Each referenceable definition should have references. | ||||
| 	params := s.spec.Spec().Parameters | ||||
|  | @ -475,14 +493,13 @@ func (s *SpecValidator) validateReferencedParameters() *Result { | |||
| 	if len(expected) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	result := new(Result) | ||||
| 	result := pools.poolOfResults.BorrowResult() | ||||
| 	for k := range expected { | ||||
| 		result.AddWarnings(unusedParamMsg(k)) | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
| 
 | ||||
| // nolint: dupl | ||||
| func (s *SpecValidator) validateReferencedResponses() *Result { | ||||
| 	// Each referenceable definition should have references. | ||||
| 	responses := s.spec.Spec().Responses | ||||
|  | @ -501,14 +518,13 @@ func (s *SpecValidator) validateReferencedResponses() *Result { | |||
| 	if len(expected) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	result := new(Result) | ||||
| 	result := pools.poolOfResults.BorrowResult() | ||||
| 	for k := range expected { | ||||
| 		result.AddWarnings(unusedResponseMsg(k)) | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
| 
 | ||||
| // nolint: dupl | ||||
| func (s *SpecValidator) validateReferencedDefinitions() *Result { | ||||
| 	// Each referenceable definition must have references. | ||||
| 	defs := s.spec.Spec().Definitions | ||||
|  | @ -537,7 +553,7 @@ func (s *SpecValidator) validateReferencedDefinitions() *Result { | |||
| 
 | ||||
| func (s *SpecValidator) validateRequiredDefinitions() *Result { | ||||
| 	// Each property listed in the required array must be defined in the properties of the model | ||||
| 	res := new(Result) | ||||
| 	res := pools.poolOfResults.BorrowResult() | ||||
| 
 | ||||
| DEFINITIONS: | ||||
| 	for d, schema := range s.spec.Spec().Definitions { | ||||
|  | @ -556,7 +572,7 @@ DEFINITIONS: | |||
| 
 | ||||
| func (s *SpecValidator) validateRequiredProperties(path, in string, v *spec.Schema) *Result { | ||||
| 	// Takes care of recursive property definitions, which may be nested in additionalProperties schemas | ||||
| 	res := new(Result) | ||||
| 	res := pools.poolOfResults.BorrowResult() | ||||
| 	propertyMatch := false | ||||
| 	patternMatch := false | ||||
| 	additionalPropertiesMatch := false | ||||
|  | @ -615,40 +631,42 @@ func (s *SpecValidator) validateRequiredProperties(path, in string, v *spec.Sche | |||
| func (s *SpecValidator) validateParameters() *Result { | ||||
| 	// - for each method, path is unique, regardless of path parameters | ||||
| 	//   e.g. GET:/petstore/{id}, GET:/petstore/{pet}, GET:/petstore are | ||||
| 	//   considered duplicate paths | ||||
| 	//   considered duplicate paths, if StrictPathParamUniqueness is enabled. | ||||
| 	// - each parameter should have a unique `name` and `type` combination | ||||
| 	// - each operation should have only 1 parameter of type body | ||||
| 	// - there must be at most 1 parameter in body | ||||
| 	// - parameters with pattern property must specify valid patterns | ||||
| 	// - $ref in parameters must resolve | ||||
| 	// - path param must be required | ||||
| 	res := new(Result) | ||||
| 	res := pools.poolOfResults.BorrowResult() | ||||
| 	rexGarbledPathSegment := mustCompileRegexp(`.*[{}\s]+.*`) | ||||
| 	for method, pi := range s.expandedAnalyzer().Operations() { | ||||
| 		methodPaths := make(map[string]map[string]string) | ||||
| 		for path, op := range pi { | ||||
| 			pathToAdd := pathHelp.stripParametersInPath(path) | ||||
| 			if s.Options.StrictPathParamUniqueness { | ||||
| 				pathToAdd := pathHelp.stripParametersInPath(path) | ||||
| 
 | ||||
| 			// Warn on garbled path afer param stripping | ||||
| 			if rexGarbledPathSegment.MatchString(pathToAdd) { | ||||
| 				res.AddWarnings(pathStrippedParamGarbledMsg(pathToAdd)) | ||||
| 			} | ||||
| 				// Warn on garbled path afer param stripping | ||||
| 				if rexGarbledPathSegment.MatchString(pathToAdd) { | ||||
| 					res.AddWarnings(pathStrippedParamGarbledMsg(pathToAdd)) | ||||
| 				} | ||||
| 
 | ||||
| 			// Check uniqueness of stripped paths | ||||
| 			if _, found := methodPaths[method][pathToAdd]; found { | ||||
| 				// Check uniqueness of stripped paths | ||||
| 				if _, found := methodPaths[method][pathToAdd]; found { | ||||
| 
 | ||||
| 				// Sort names for stable, testable output | ||||
| 				if strings.Compare(path, methodPaths[method][pathToAdd]) < 0 { | ||||
| 					res.AddErrors(pathOverlapMsg(path, methodPaths[method][pathToAdd])) | ||||
| 					// Sort names for stable, testable output | ||||
| 					if strings.Compare(path, methodPaths[method][pathToAdd]) < 0 { | ||||
| 						res.AddErrors(pathOverlapMsg(path, methodPaths[method][pathToAdd])) | ||||
| 					} else { | ||||
| 						res.AddErrors(pathOverlapMsg(methodPaths[method][pathToAdd], path)) | ||||
| 					} | ||||
| 				} else { | ||||
| 					res.AddErrors(pathOverlapMsg(methodPaths[method][pathToAdd], path)) | ||||
| 				} | ||||
| 			} else { | ||||
| 				if _, found := methodPaths[method]; !found { | ||||
| 					methodPaths[method] = map[string]string{} | ||||
| 				} | ||||
| 				methodPaths[method][pathToAdd] = path // Original non stripped path | ||||
| 					if _, found := methodPaths[method]; !found { | ||||
| 						methodPaths[method] = map[string]string{} | ||||
| 					} | ||||
| 					methodPaths[method][pathToAdd] = path // Original non stripped path | ||||
| 
 | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			var bodyParams []string | ||||
|  | @ -659,7 +677,23 @@ func (s *SpecValidator) validateParameters() *Result { | |||
| 			// TODO: should be done after param expansion | ||||
| 			res.Merge(s.checkUniqueParams(path, method, op)) | ||||
| 
 | ||||
| 			// pick the root schema from the swagger specification which describes a parameter | ||||
| 			origSchema, ok := s.schema.Definitions["parameter"] | ||||
| 			if !ok { | ||||
| 				panic("unexpected swagger schema: missing #/definitions/parameter") | ||||
| 			} | ||||
| 			// clone it once to avoid expanding a global schema (e.g. swagger spec) | ||||
| 			paramSchema, err := deepCloneSchema(origSchema) | ||||
| 			if err != nil { | ||||
| 				panic(fmt.Errorf("can't clone schema: %v", err)) | ||||
| 			} | ||||
| 
 | ||||
| 			for _, pr := range paramHelp.safeExpandedParamsFor(path, method, op.ID, res, s) { | ||||
| 				// An expanded parameter must validate the Parameter schema (an unexpanded $ref always passes high-level schema validation) | ||||
| 				schv := newSchemaValidator(¶mSchema, s.schema, fmt.Sprintf("%s.%s.parameters.%s", path, method, pr.Name), s.KnownFormats, s.schemaOptions) | ||||
| 				obj := swag.ToDynamicJSON(pr) | ||||
| 				res.Merge(schv.Validate(obj)) | ||||
| 
 | ||||
| 				// Validate pattern regexp for parameters with a Pattern property | ||||
| 				if _, err := compileRegexp(pr.Pattern); err != nil { | ||||
| 					res.AddErrors(invalidPatternInParamMsg(op.ID, pr.Name, pr.Pattern)) | ||||
|  | @ -741,7 +775,7 @@ func (s *SpecValidator) validateParameters() *Result { | |||
| 
 | ||||
| func (s *SpecValidator) validateReferencesValid() *Result { | ||||
| 	// each reference must point to a valid object | ||||
| 	res := new(Result) | ||||
| 	res := pools.poolOfResults.BorrowResult() | ||||
| 	for _, r := range s.analyzer.AllRefs() { | ||||
| 		if !r.IsValidURI(s.spec.SpecFilePath()) { // Safeguard - spec should always yield a valid URI | ||||
| 			res.AddErrors(invalidRefMsg(r.String())) | ||||
|  | @ -767,7 +801,7 @@ func (s *SpecValidator) checkUniqueParams(path, method string, op *spec.Operatio | |||
| 	// However, there are some issues with such a factorization: | ||||
| 	// - analysis does not seem to fully expand params | ||||
| 	// - param keys may be altered by x-go-name | ||||
| 	res := new(Result) | ||||
| 	res := pools.poolOfResults.BorrowResult() | ||||
| 	pnames := make(map[string]struct{}) | ||||
| 
 | ||||
| 	if op.Parameters != nil { // Safeguard | ||||
|  | @ -802,3 +836,17 @@ func (s *SpecValidator) expandedAnalyzer() *analysis.Spec { | |||
| 	} | ||||
| 	return s.analyzer | ||||
| } | ||||
| 
 | ||||
| func deepCloneSchema(src spec.Schema) (spec.Schema, error) { | ||||
| 	var b bytes.Buffer | ||||
| 	if err := gob.NewEncoder(&b).Encode(src); err != nil { | ||||
| 		return spec.Schema{}, err | ||||
| 	} | ||||
| 
 | ||||
| 	var dst spec.Schema | ||||
| 	if err := gob.NewDecoder(&b).Decode(&dst); err != nil { | ||||
| 		return spec.Schema{}, err | ||||
| 	} | ||||
| 
 | ||||
| 	return dst, nil | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue