示例#1
0
func (s *Spec) analyzeOperations(path string, pi *spec.PathItem) {
	// TODO: resolve refs here?
	op := pi
	if pi.Ref.String() != "" {
		key := slashpath.Join("/paths", jsonpointer.Escape(path))
		s.references.addPathItemRef(key, pi)
	}
	s.analyzeOperation("GET", path, op.Get)
	s.analyzeOperation("PUT", path, op.Put)
	s.analyzeOperation("POST", path, op.Post)
	s.analyzeOperation("PATCH", path, op.Patch)
	s.analyzeOperation("DELETE", path, op.Delete)
	s.analyzeOperation("HEAD", path, op.Head)
	s.analyzeOperation("OPTIONS", path, op.Options)
	for i, param := range op.Parameters {
		refPref := slashpath.Join("/paths", jsonpointer.Escape(path), "parameters", strconv.Itoa(i))
		if param.Ref.String() != "" {
			s.references.addParamRef(refPref, &param)
		}
		if param.Pattern != "" {
			s.patterns.addParameterPattern(refPref, param.Pattern)
		}
		if param.Items != nil {
			s.analyzeItems("items", param.Items, refPref, "parameter")
		}
		if param.Schema != nil {
			s.analyzeSchema("schema", *param.Schema, refPref)
		}
	}
}
示例#2
0
func (s *Spec) initialize() {
	for _, c := range s.spec.Consumes {
		s.consumes[c] = struct{}{}
	}
	for _, c := range s.spec.Produces {
		s.produces[c] = struct{}{}
	}
	for _, ss := range s.spec.Security {
		for k := range ss {
			s.authSchemes[k] = struct{}{}
		}
	}
	for path, pathItem := range s.AllPaths() {
		s.analyzeOperations(path, &pathItem)
	}

	for name, parameter := range s.spec.Parameters {
		refPref := slashpath.Join("/parameters", jsonpointer.Escape(name))
		if parameter.Items != nil {
			s.analyzeItems("items", parameter.Items, refPref, "parameter")
		}
		if parameter.In == "body" && parameter.Schema != nil {
			s.analyzeSchema("schema", *parameter.Schema, refPref)
		}
		if parameter.Pattern != "" {
			s.patterns.addParameterPattern(refPref, parameter.Pattern)
		}
	}

	for name, response := range s.spec.Responses {
		refPref := slashpath.Join("/responses", jsonpointer.Escape(name))
		for k, v := range response.Headers {
			hRefPref := slashpath.Join(refPref, "headers", k)
			if v.Items != nil {
				s.analyzeItems("items", v.Items, hRefPref, "header")
			}
			if v.Pattern != "" {
				s.patterns.addHeaderPattern(hRefPref, v.Pattern)
			}
		}
		if response.Schema != nil {
			s.analyzeSchema("schema", *response.Schema, refPref)
		}
	}

	for name, schema := range s.spec.Definitions {
		s.analyzeSchema(name, schema, "/definitions")
	}
	// TODO: after analyzing all things and flattening schemas etc
	// resolve all the collected references to their final representations
	// best put in a separate method because this could get expensive
}
示例#3
0
func (s *SpecValidator) validateReferencedDefinitions() *Result {
	// Each referenceable definition must have references.
	defs := s.spec.Spec().Definitions
	if len(defs) == 0 {
		return nil
	}

	expected := make(map[string]struct{})
	for k := range defs {
		expected["#/definitions/"+jsonpointer.Escape(k)] = struct{}{}
	}
	for _, k := range s.analyzer.AllDefinitionReferences() {
		if _, ok := expected[k]; ok {
			delete(expected, k)
		}
	}

	if len(expected) == 0 {
		return nil
	}
	var result Result
	for k := range expected {
		result.AddErrors(errors.New(422, "definition %q is not used anywhere", k))
	}
	return &result
}
示例#4
0
func (s *Spec) analyzeOperation(method, path string, op *spec.Operation) {
	if op == nil {
		return
	}

	for _, c := range op.Consumes {
		s.consumes[c] = struct{}{}
	}
	for _, c := range op.Produces {
		s.produces[c] = struct{}{}
	}
	for _, ss := range op.Security {
		for k := range ss {
			s.authSchemes[k] = struct{}{}
		}
	}
	if _, ok := s.operations[method]; !ok {
		s.operations[method] = make(map[string]*spec.Operation)
	}
	s.operations[method][path] = op
	prefix := slashpath.Join("/paths", jsonpointer.Escape(path), strings.ToLower(method))
	for i, param := range op.Parameters {
		refPref := slashpath.Join(prefix, "parameters", strconv.Itoa(i))
		if param.Ref.String() != "" {
			s.references.addParamRef(refPref, &param)
		}
		s.analyzeItems("items", param.Items, refPref)
		if param.In == "body" && param.Schema != nil {
			s.analyzeSchema("schema", *param.Schema, refPref)
		}
	}
	if op.Responses != nil {
		if op.Responses.Default != nil {
			refPref := slashpath.Join(prefix, "responses", "default")
			if op.Responses.Default.Ref.String() != "" {
				s.references.addResponseRef(refPref, op.Responses.Default)
			}
			for _, v := range op.Responses.Default.Headers {
				s.analyzeItems("items", v.Items, refPref)
			}
			if op.Responses.Default.Schema != nil {
				s.analyzeSchema("schema", *op.Responses.Default.Schema, refPref)
			}
		}
		for k, res := range op.Responses.StatusCodeResponses {
			refPref := slashpath.Join(prefix, "responses", strconv.Itoa(k))
			if res.Ref.String() != "" {
				s.references.addResponseRef(refPref, &res)
			}
			for _, v := range res.Headers {
				s.analyzeItems("items", v.Items, refPref)
			}
			if res.Schema != nil {
				s.analyzeSchema("schema", *res.Schema, refPref)
			}
		}
	}
}
示例#5
0
func (s *Spec) analyzeSchema(name string, schema spec.Schema, prefix string) {
	refURI := slashpath.Join(prefix, jsonpointer.Escape(name))
	schRef := SchemaRef{
		Name:     name,
		Schema:   &schema,
		Ref:      spec.MustCreateRef("#" + refURI),
		TopLevel: prefix == "/definitions",
	}

	s.allSchemas["#"+refURI] = schRef

	if schema.Ref.String() != "" {
		s.references.addSchemaRef(refURI, schRef)
	}
	if schema.Pattern != "" {
		s.patterns.addSchemaPattern(refURI, schema.Pattern)
	}

	for k, v := range schema.Definitions {
		s.analyzeSchema(k, v, slashpath.Join(refURI, "definitions"))
	}
	for k, v := range schema.Properties {
		s.analyzeSchema(k, v, slashpath.Join(refURI, "properties"))
	}
	for k, v := range schema.PatternProperties {
		s.analyzeSchema(k, v, slashpath.Join(refURI, "patternProperties"))
	}
	for i, v := range schema.AllOf {
		s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "allOf"))
	}
	if len(schema.AllOf) > 0 {
		s.allOfs["#"+refURI] = schRef
	}
	for i, v := range schema.AnyOf {
		s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "anyOf"))
	}
	for i, v := range schema.OneOf {
		s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "oneOf"))
	}
	if schema.Not != nil {
		s.analyzeSchema("not", *schema.Not, refURI)
	}
	if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
		s.analyzeSchema("additionalProperties", *schema.AdditionalProperties.Schema, refURI)
	}
	if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
		s.analyzeSchema("additionalItems", *schema.AdditionalItems.Schema, refURI)
	}
	if schema.Items != nil {
		if schema.Items.Schema != nil {
			s.analyzeSchema("items", *schema.Items.Schema, refURI)
		}
		for i, sch := range schema.Items.Schemas {
			s.analyzeSchema(strconv.Itoa(i), sch, slashpath.Join(refURI, "items"))
		}
	}
}
示例#6
0
func (s splitKey) PathItemRef() swspec.Ref {
	if len(s) < 3 {
		return swspec.Ref{}
	}
	pth, method := s[1], s[2]
	if _, validMethod := validMethods[strings.ToUpper(method)]; !validMethod && !strings.HasPrefix(method, "x-") {
		return swspec.Ref{}
	}
	return swspec.MustCreateRef("#" + path.Join("/", pths, jsonpointer.Escape(pth), strings.ToUpper(method)))
}
示例#7
0
func TestResolveLocalRef_PathItem(t *testing.T) {
	rootDoc := new(Swagger)
	b, err := ioutil.ReadFile("fixtures/specs/refed.json")
	if assert.NoError(t, err) && assert.NoError(t, json.Unmarshal(b, rootDoc)) {
		var tgt PathItem
		ref, err := NewRef("#/paths/" + jsonpointer.Escape("/pets/{id}"))
		if assert.NoError(t, err) {
			resolver, _ := defaultSchemaLoader(rootDoc, nil, nil)
			if assert.NoError(t, resolver.Resolve(&ref, &tgt)) {
				assert.Equal(t, rootDoc.Paths.Paths["/pets/{id}"].Get, tgt.Get)
			}
		}
	}
}
示例#8
0
func TestResolveRemoteRef_ToPathItem(t *testing.T) {
	specs := "fixtures/specs"
	fileserver := http.FileServer(http.Dir(specs))
	server := httptest.NewServer(fileserver)
	defer server.Close()

	rootDoc := new(Swagger)
	b, err := ioutil.ReadFile("fixtures/specs/refed.json")
	if assert.NoError(t, err) && assert.NoError(t, json.Unmarshal(b, rootDoc)) {
		var tgt PathItem
		ref, err := NewRef(server.URL + "/refed.json#/paths/" + jsonpointer.Escape("/pets/{id}"))
		if assert.NoError(t, err) {

			resolver, _ := defaultSchemaLoader(rootDoc, nil, nil)
			if assert.NoError(t, resolver.Resolve(&ref, &tgt)) {
				assert.Equal(t, rootDoc.Paths.Paths["/pets/{id}"].Get, tgt.Get)
			}
		}
	}
}
示例#9
0
func gatherOperations(specDoc *Spec, operationIDs []string) map[string]opRef {
	var oprefs opRefs

	for method, pathItem := range specDoc.Operations() {
		for pth, operation := range pathItem {
			vv := *operation
			oprefs = append(oprefs, opRef{
				Key:    swag.ToGoName(strings.ToLower(method) + " " + pth),
				Method: method,
				Path:   pth,
				ID:     vv.ID,
				Op:     &vv,
				Ref:    swspec.MustCreateRef("#" + path.Join("/paths", jsonpointer.Escape(pth), method)),
			})
		}
	}

	sort.Sort(oprefs)

	operations := make(map[string]opRef)
	for _, opr := range oprefs {
		nm := opr.ID
		if nm == "" {
			nm = opr.Key
		}

		oo, found := operations[nm]
		if found && oo.Method != opr.Method && oo.Path != opr.Path {
			nm = opr.Key
		}
		if len(operationIDs) == 0 || containsString(operationIDs, opr.ID) || containsString(operationIDs, nm) {
			opr.ID = nm
			opr.Op.ID = nm
			operations[nm] = opr
		}
	}

	return operations
}
示例#10
0
func (s splitKey) PathRef() swspec.Ref {
	if !s.IsOperation() {
		return swspec.Ref{}
	}
	return swspec.MustCreateRef("#" + path.Join("/", pths, jsonpointer.Escape(s[1])))
}