Coder Social home page Coder Social logo

validate's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

validate's Issues

Valid JSON Example Triggers Swagger Spec Failure

Brief backstory: Was investigating an issue with go-swagger failing to generate client code for Eve Online's latest swagger spec.

Long story short, this file will fail validation:

{
    "swagger": "2.0",
    "info": {
        "title": "Test",
        "description": "Tests issue with examples and nested objects with items properties",
        "version": "1.0"
    },
    "host": "FooBar",
    "basePath": "/latest",
    "schemes": [
        "https"
    ],
    "produces": [
        "application/json"
    ],
    "paths": {
        "/foo/": {
            "get": {
                "description": "Tests issue with nested items object properties and examples",
                "summary": "Tests issue with nested items object properties and examples",
                "responses": {
                    "200": {
                        "description": "Example should match spec",
                        "examples": {
                            "application/json": [
                                {
                                    "items": [
                                        {
                                            "id": 1
                                        }
                                    ]
                                }
                            ]
                        },
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "items": {
                                        "type": "array",
                                        "maxItems": 255,
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "format": "int32"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

The test I added to spec_test.go was similar to the other issue tests, if the above is put into fixtures/bugs/new/swagger.json:

func TestNewIssue(t *testing.T) {
	fp := filepath.Join("fixtures", "bugs", "new", "swagger.json")
	jstext, _ := ioutil.ReadFile(fp)

	// as json schema
	var sch spec.Schema
	if assert.NoError(t, json.Unmarshal(jstext, &sch)) {
		validator := NewSchemaValidator(spec.MustLoadSwagger20Schema(), nil, "", strfmt.Default)
		res := validator.Validate(&sch)
		assert.True(t, res.IsValid())
	}

	// as swagger spec
	doc, err := loads.Spec(fp)
	if assert.NoError(t, err) {
		validator := NewSpecValidator(doc.Schema(), strfmt.Default)
		res, _ := validator.Validate(doc)
		assert.True(t, res.IsValid())
	}

}

Note that the first assert passes, the second fails:

--- FAIL: TestNewIssue (8.64s)
        Error Trace:    spec_test.go:79
	Error:      	Should be true
FAIL
exit status 1

Note that deleting the examples object will cause the spec parsing to be successful.

Note that I also tried 'peeling' back the outermost layer of the schema, by only making it an object with an items property that is an array. The example also still fails in this case, when adjusted in the same manner.

Better advertising of $ref sibling issues

When writing yaml specs, indentation does matter.

It is vey easy to mismatch a $ref into a sibling object.

In that case, the parser overrides the schema by the $ref, which is correct behavior.

Often, valid vs invalid differ by only a few blanks.

Currently, the validator follows the parsed schema. Most likely, we get some difficult to understand errors such as 'xxx in body does not validate OneOf()' ... I found very frustrating to plow specs for hours to eventually figure out the problem.

Todo:

  • A warning should be issued when $ref have sibling properties in schema.
  • Similarly, $ref in inappropriate places according to swagger spec (not json schema) should be advertised as errors
  • The previous line has been patched for the special case of headers by PR#44. This work around introduced a small bug, in the case the user spec's contains a "header" property with a "$ref" inside

Enhancement: CI configuration

Since this pakage has recently undergone a vast extension of UT and coverage, it would be
nice to reap the benefits in our CI chain.

Problem statement

  • Validating a lot of specs takes some time
  • default go test timeout is 10 min
  • current CI configuration wants -race, thus even more resources and time consuming (about 1h)

Suggested solution

The suggested travis setup with PR #60 splits CI tasks in the following build matrix:

  • run tests as go 1.8 and 1.9 (I could see significant performance improvements with 1.9)
  • split test suites in 3 parts:
    • ordinary unit tests (covers ~90% statements), with -race. Builds in less than 10 min (default go test timeout). Includes json-schema-suite which is very fast.
    • advanced functional tests with full message output verification and long running issue fixtures.
      This one does not use -race but produces the test coverage report. Timeout is set to larger value (to account for 1.8 speed limitations and possible travis workload)
    • go-swagger non regression suite, which tests about 110 specs taken from go-swagger/go-swagger/fixtures (from canary and the like, but not fixtures/codegen) and verifies that the validation status remains unaltered

compile error when trying to include github.com/go-openapi/analysis

I am trying to use openapi to validate crd schema. I used glide to install the opeapi but i am getting compilation error below while trying to compile

code:

package validate

import (
"github.com/go-openapi/analysis"
)

error:

GOROOT=/usr/local/go #gosetup
GOPATH=/Users/pitiwari/go-ws #gosetup
/usr/local/go/bin/go build -i -o /private/var/folders/y4/zplxn82n5293wh__31pqxsth39682s/T/___go_build_crd_validator_go /Users/pitiwari/go-ws/src/github.com/ebayinc/ingress/crd_validator.go #gosetup

github.com/ebayinc/ingress/vendor/github.com/go-openapi/strfmt

vendor/github.com/go-openapi/strfmt/format.go:96:9: cannot use func literal (type func(reflect.Type, reflect.Type, interface {}) (interface {}, error)) as type mapstructure.DecodeHookFunc in return argument

Compilation finished with exit code 2

Propose a mode for model only validation

Since go-swagger model generation may generate models from only partial specs (e.g. definitions only) and supports (at least partially) the additionalItems JSON-schema construct,

it would be nice to implement some option in validate to validate such models which are not strictly swagger-compliant

Validation of zero values

This library currently marks a zero value for a required property as an error (

if reflect.DeepEqual(reflect.Zero(val.Type()).Interface(), val.Interface()) {
).

But this doesn't really make sense in an API, because you should be allowed to send in a 0 for an integer property or a false for a boolean property even if it is required.

In regards to integers, the minimum option should define whether 0 is allowed, not the required option.

In regards to booleans, the required check doesn't make any sense at all in its current form as you aren't able to send anything other than true.

validation issue: can't have same parameter name in path and formData

If the name of path parameter and form parameter is same, then validation failed. Definition, eg:

"parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "",
            "required": true,
            "type": "string"
          },
          {
            "name": "id",
            "in": "formData",
            "description": "",
            "required": false,
            "type": "string"
          }
        ]

Error:

path param "{id}" has no parameter definition

As per swagger spec, the definition is allowed.

enum validation fails for int enum

for the following schema:

{
  "type": "object",
  "properties": {
    "sizes": {
      "type": "object",
      "properties": {
        "first": {
          "type": "object",
          "properties": {
            "count": {
              "type": "integer",
              "default": 3,
              "enum": [3, 5, 7]
            }
          },
          "required": ["count"]
        }
      },
      "required": ["first"]
    }
  },
  "required": ["sizes"]
}

the following data fails and it should succeed

{
  "sizes": {
    "first": {
      "count": 3
    }
  }
}

This data should fail

{
  "sizes": {
    "first": {
      "count": 2
    }
  }
}

Better error reporting on unsupported keywords

Unsupported json keywords in swagger are a common failure for my specs which are largely inherited from previously designed json schemas.

Currently, error reporting is terse on this kind of problem.

At best, I have a "forbidden property xxx" message.
At worse, I have a "xxx does not validate oneOf ..." message.

The switch between these 2 types of message is dificult to control (related to MatchCount, which makes a best effort to provide correct reporting on anyOf|oneOf failures).

I think an additional scan with a list of json keywords explicitly not supported by swagger (e.g: $schema, additionalItems, ...) would provide the user a clearer view on what's wrong with the spec.

go-swagger and additionalProperties generates panic

I got this panic by using additionalProperties in one of the response definitions.
(I guessed that this issue blongs to go-openapi instead of go-swagger, let me know if I'm wrong)

$ % swagger generate server  
panic: interface conversion: interface {} is spec.Schema, not spec.Response

goroutine 1 [running]:
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/validate.(*SpecValidator).validateResponseExample(0xc421ea7958, 0xc42046d8a0, 0x8, 0xc421ea76a8, 0x0)
	/Users/daisuke/dev/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/validate/spec.go:645 +0x2e6
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/validate.(*SpecValidator).validateExamplesValidAgainstSchema(0xc421ea7958, 0xc4203a6300)
	/Users/daisuke/dev/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/validate/spec.go:671 +0x25d
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/validate.(*SpecValidator).Validate(0xc421ea7958, 0x17619a0, 0xc420721c20, 0x1322b44, 0x16f1360)
	/Users/daisuke/dev/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/validate/spec.go:125 +0x37b
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/validate.Spec(0xc420721c20, 0x1b7ef80, 0xc420373b00, 0x0, 0x0)
	/Users/daisuke/dev/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/validate/spec.go:51 +0x81
github.com/go-swagger/go-swagger/generator.validateSpec(0x17baa07, 0xc, 0xc420721c20, 0xc, 0xc420721c20)
	/Users/daisuke/dev/src/github.com/go-swagger/go-swagger/generator/shared.go:607 +0x86
github.com/go-swagger/go-swagger/generator.newAppGenerator(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc420162380, 0x1583cba, ...)
	/Users/daisuke/dev/src/github.com/go-swagger/go-swagger/generator/support.go:80 +0xae4
github.com/go-swagger/go-swagger/generator.GenerateServer(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc420162380, 0xc4204c9c98, ...)
	/Users/daisuke/dev/src/github.com/go-swagger/go-swagger/generator/support.go:39 +0x94
github.com/go-swagger/go-swagger/cmd/swagger/commands/generate.(*Server).Execute(0xc420822b40, 0xc420848200, 0x0, 0x2, 0xc420822b40, 0x1)
	/Users/daisuke/dev/src/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/server.go:102 +0x4e9
github.com/go-swagger/go-swagger/vendor/github.com/jessevdk/go-flags.(*Parser).ParseArgs(0xc420812a80, 0xc420010160, 0x2, 0x2, 0x1010f88, 0x30, 0xc420246900, 0xc420427980, 0xc4204272c8)
	/Users/daisuke/dev/src/github.com/go-swagger/go-swagger/vendor/github.com/jessevdk/go-flags/parser.go:316 +0x893
github.com/go-swagger/go-swagger/vendor/github.com/jessevdk/go-flags.(*Parser).Parse(0xc420812a80, 0x6, 0x17b15d2, 0x6, 0x0, 0x17f9437)
	/Users/daisuke/dev/src/github.com/go-swagger/go-swagger/vendor/github.com/jessevdk/go-flags/parser.go:186 +0x73
main.main()
	/Users/daisuke/dev/src/github.com/go-swagger/go-swagger/cmd/swagger/swagger.go:105 +0x858
swagger: '2.0'
info:
  description: Example API service
  version: 1.0.0
  title: Example API
host: localhost
basePath: /v1
tags:
  - name: example
    description: Example API
schemes:
  - http
paths:
  '/example':
    get:
      tags:
        - example
      summary: summary
      description: description
      operationId: example
      produces:
        - application/json
      responses:
        '200':
          $ref: '#/definitions/Example'
definitions:
  Example:
    type: object
    description: "Blah blah"
    additionalProperties:
      type: array
      example: blah
      items:
        type: string

Constraints on numbers do not validate against proper type|format

Applies to: numbers or integers with constraints

Constraints such as Maximum, Minimum, MultipleOf are not validated against the proper type and format.
Instead, the constraint operand (boundary or factor) is systematically (and silently) converted as float64, with a risk of information loss.

We should provide spec consistency check between object/param types and constraints,
and avoid possible loss of information when casting int64 to float64.

Don't be mistaken, this one is not about providing bigint arithmetics.

Incompatible operands (e.g. constraining a uint32 with a negative value in Maxium) should be detected.

This kind of error could trigger a warning (please advise), since it is not illegal to specify a constraint with a different type than the constrained value.

NOTE: PR #42 make it work on inline params (validator.go) in presence of default values [a default value will trigger the check, but schemas without default remain skipped].

This should be generalized to all situations (objects, arrays).

Also refered by:

Regex cache has potential data race

validate/rexp.go

Lines 28 to 32 in 659e09d

func compileRegexp(pattern string) (*re.Regexp, error) {
// Save repeated regexp compilation
if reDict[pattern] != nil {
return reDict[pattern], nil
}

The current implementation allows for read to happen without acquiring lock. This leads to data race when read and write happen concurrently.

Accurate spec validation message on type: [ ...] construct

In spec ./fixtures/swagger/canary/docker/swagger.json we find a construct for multiple-types,
e.g.:

"type": [ "string", "array"]

The following "items" specification is not well validated, and unduly reports a spec validation message.

Check constraint on discriminator property

As per swagger 2.0 spec (https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md), we have the following constraint:

discriminator string Adds support for polymorphism. The discriminator is the schema property name that is used to differentiate between other schema that inherit this schema. The property name used MUST be defined at this schema and it MUST be in the required property list. When used, the value MUST be the name of this schema or any schema that inherits it.

This is currently not checked by the spec validation package.

Improvement: error context reporting

Errors and warnings are dumped in any order, with poor information about context in the spec.

Since retrieving line numbers is a hard problem, I suggest we could extend the Result object to provide a map of paths linked to errors.

Beware : this would affect the interface with Result (AddError and possibly some more direct usage).

In the end, messages would be pretty printed by sorting and indenting keys.
Not quite line numbers but better than the unordered list we have today.

Also referred by:

PathParam declared as a fragment within a path segment is not recognized

When a path parameter is declared as a fragment in a path segment, as in

paths:
  /foo/bar{fragment}:

go-openapi's validator fails to recognize this parameter and results in the error:
2017/11/10 15:54:50 path param "fragment" is not present in path "/foo/bar{fragment}"

I noticed this problem when I was using go-swagger and the error was coming from the validation code of go-openapi

I will add a PR that fixes the validator (in spec.go)'s path handling and with this change. Please take a look at it.

Thank you

Regards, aki

failed to validate with simple type:object schema

This test should be passed, because a schema {"type":"object"} accepts any objects.
It should not depend on contents of validation target.

func TestSchemaValidator2_TypeArray(t *testing.T) {
	var schemaJSON = `
{
	"type": "object"
}`

	schema := new(spec.Schema)
	require.NoError(t, json.Unmarshal([]byte(schemaJSON), schema))

	var input map[string]interface{}
	var inputJSON = `{"type": "array"}`

	require.NoError(t, json.Unmarshal([]byte(inputJSON), &input))
	assert.NoError(t, AgainstSchema(schema, input, strfmt.Default))
}

However it fails just only for {"type":"array"}.

$ go test -v -run TestSchemaValidator2
=== RUN   TestSchemaValidator2_TypeArray
--- FAIL: TestSchemaValidator2_TypeArray (0.00s)
	schema2_test.go:27: 
			Error Trace:	schema2_test.go:27
			Error:      	Received unexpected error:
			            	validation failure list:
			            	items is required
			Test:       	TestSchemaValidator2_TypeArray
FAIL
exit status 1
FAIL	github.com/go-openapi/validate	0.025s

This is caused by objectValidator.checkArrayMustHaveItems(),
it checks contents of target value, when there are type:array, it requires items field too always.

What is the function's purpose? It seems do strange thing for me.

Panic validating an object with a json.Number in a "type":"string" field

The following test throws a panic in the last line:

package validator

import (
	"encoding/json"
	"testing"

	"github.com/go-openapi/spec"
	"github.com/go-openapi/strfmt"
	"github.com/go-openapi/validate"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestPanic(t *testing.T) {
	var schemaJSON = `
{
    "properties": {
        "name": {
            "type": "string",
            "pattern": "^[A-Za-z]+$",
            "minLength": 1
        },
        "place": {
            "type": "string",
            "pattern": "^[A-Za-z]+$",
            "minLength": 1
        }
    },
    "required": [
        "name"
    ]
}`
	var inputJSON = `{"name": "Ivan"}`
	schema := new(spec.Schema)
	require.NoError(t, json.Unmarshal([]byte(schemaJSON), schema))
	var input map[string]interface{}
	require.NoError(t, json.Unmarshal([]byte(inputJSON), &input))
	input["place"] = json.Number("10")

	assert.Error(t, validate.AgainstSchema(schema, input, strfmt.Default))
}

Publish data validator benchmark

The validator provided by this package is quite fast
and it may be used independently from the go-swagger suite.

It would nice to compare it with other popular json validation package and publish the benchmark.
I am thinking of a comparison with:

Since this would add some unwanted dependencies, it would be best to publish this as a separate repo.

refs with an invalid format cause out of memory

It takes a very long time to validate and render a spec that has invalid syntax for refs. In the example the refs have a syntax of #definitions/Bar as opposed to #/definitions/Bar which triggers the issue.

swagger: '2.0'
info:
  title: swagger validate out of memory
  version: 0.1.0
paths:
  /foos:
    post:
      operationId: createFoo
      responses:
        200:
          description: OK
          schema:
            $ref: '#/definitions/Foo'

definitions:
  Foo:
    type: object
    properties:
      bar:
        $ref: '#definitions/Bar'
      baz:
        $ref: '#definitions/Baz'

  Bar:
    type: string
    enum:
      - a
      - b

  Baz:
    type: array
    items:
      type: string

related: go-swagger/go-swagger#605

validation fails for a valid spec

I am trying to validate this spec:
https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/yaml/petstore-separate/spec/swagger.yaml

Using go swagger:

swagger version
version: 0.7.2
commit: f56b02a7f80ed9ec54fee277ec7a57de1e329f79
swagger validate swagger.yaml

Fails with:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0xe1ee7]

goroutine 1 [running]:
panic(0x689080, 0xc420014090)
    /usr/local/go/src/runtime/panic.go:500 +0x1a1
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/spec.expandSchema(0x0, 0x0, 0x0, 0xc420284600, 0x0, 0x0, 0x0, 0x100, 0x0, 0x0, ...)
    /go/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/spec/expander.go:446 +0x3e7
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/spec.expandItems(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /go/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/spec/expander.go:405 +0x2cf
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/spec.expandSchema(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /go/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/spec/expander.go:449 +0x58e
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/spec.expandResponse(0xc42097a910, 0xc4204730c0, 0xc42055e8a0, 0x0)
    /go/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/spec/expander.go:602 +0x1ff
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/spec.expandOperation(0xc420105a40, 0xc4204730c0, 0x0, 0xc42055ef70)
    /go/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/spec/expander.go:575 +0x31b
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/spec.expandPathItem(0xc42020c800, 0xc4204730c0, 0xc42055ef70, 0xadde40)
    /go/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/spec/expander.go:534 +0x14e
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/spec.ExpandSpec(0xc420344900, 0xde5, 0x1023)
    /go/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/spec/expander.go:351 +0x7a1
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/loads.(*Document).Expanded(0xc4207679c0, 0xc420891901, 0x3, 0x4)
    /go/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/loads/spec.go:140 +0x91
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/validate.(*SpecValidator).validateReferencesValid(0xc42055fac8, 0xc42073eb60)
    /go/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/validate/spec.go:614 +0x181
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/validate.(*SpecValidator).Validate(0xc42055fac8, 0x6eb3e0, 0xc4207679c0, 0x1023, 0x734f36)
    /go/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/validate/spec.go:113 +0x2a4
github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/validate.Spec(0xc4207679c0, 0xae5300, 0xc420474d20, 0x0, 0x0)
    /go/src/github.com/go-swagger/go-swagger/vendor/github.com/go-openapi/validate/spec.go:50 +0x81
github.com/go-swagger/go-swagger/cmd/swagger/commands.(*ValidateSpec).Execute(0xb4baf0, 0xc4203123e0, 0x1, 0x2, 0x1, 0x2)
    /go/src/github.com/go-swagger/go-swagger/cmd/swagger/commands/validate.go:46 +0xbe
github.com/go-swagger/go-swagger/vendor/github.com/jessevdk/go-flags.(*Parser).ParseArgs(0xc4203a4d20, 0xc4200780a0, 0x2, 0x2, 0x8, 0x4, 0xc420098b40, 0xc4202be800, 0xc4202f7e48)
    /go/src/github.com/go-swagger/go-swagger/vendor/github.com/jessevdk/go-flags/parser.go:315 +0x8e6
github.com/go-swagger/go-swagger/vendor/github.com/jessevdk/go-flags.(*Parser).Parse(0xc4203a4d20, 0x6, 0x737738, 0x6, 0x1, 0x77c2b1)
    /go/src/github.com/go-swagger/go-swagger/vendor/github.com/jessevdk/go-flags/parser.go:185 +0x74
main.main()
    /go/src/github.com/go-swagger/go-swagger/cmd/swagger/swagger.go:90 +0x455

Using swagger tools:

swagger-tools --version
0.10.1
swagger-tools validate -v swagger.yaml

Succeeds with:

Validation Details:

  Swagger Version: 2.0
  Swagger file: swagger.yaml

Swagger document is valid

Validation of objects not working?

I stumbled on this project a day or two ago and wanted to put it through its paces, but I seem to be having trouble getting object validation to work properly:

package main

import (
        "github.com/go-openapi/loads"
//        "github.com/go-openapi/spec"
    "github.com/go-openapi/strfmt"
        "github.com/go-openapi/validate"
    "encoding/json"
    "log"
)

func main() {
    doc := json.RawMessage{}
    err := json.Unmarshal([]byte(`{
  "info": {
    "version": "0.0.0", 
    "title": "Sano API"
  }, 
  "paths": {
    "/alt": {
      "post": {
        "consumes": [
          "application/json"
        ], 
        "parameters": [
          {
            "required": true, 
            "type": "string", 
            "name": "var1", 
            "in": "query"
          }
        ], 
        "operationId": "basic2"
      }
    }, 
    "/alt2": {
      "post": {
        "consumes": [
          "application/json"
        ], 
        "parameters": [
          {
            "required": true, 
            "in": "query", 
            "name": "var1", 
            "schema": {
              "$ref": "#/definitions/DeepObject"
            }
          }
        ], 
        "operationId": "basic3"
      }
    }, 
    "/": {
      "post": {
        "consumes": [
          "application/json"
        ], 
        "parameters": [
          {
            "required": true, 
            "in": "body", 
            "name": "body", 
            "schema": {
              "$ref": "#/definitions/DeepObject"
            }
          }
        ], 
        "operationId": "basic1"
      }
    }
  }, 
  "host": "default.local", 
  "schemes": [
    "https"
  ], 
  "definitions": {
    "DeepObject": {
      "required": [
        "Data", 
        "DataType"
      ], 
      "type": "object", 
      "properties": {
        "DataType": {
          "type": "string"
        }, 
        "Data": {
          "minItems": 1, 
          "items": {
            "$ref": "#/definitions/DeeperObject"
          }, 
          "type": "array", 
          "maxItems": 1000
        }
      }
    }, 
    "DeeperObject": {
      "type": "string"
    }
  }, 
  "swagger": "2.0"
}`), &doc)
    if err != nil {
        log.Fatalf("Couldn't parse schema: %v")
    }
        analyzed, err := loads.Analyzed(doc, "2.0")
        if err != nil {
        log.Fatalf("Couldn't analyze: %v", err)
        }
    log.Printf("POST /")
    pf := analyzed.Analyzer.ParamsFor("POST", "/")
    for _, v := range(pf) {
        vr := validate.NewParamValidator(&v, strfmt.Default).Validate(map[string]interface{}{ "foo" : "bar"})
        log.Printf("PVal: %+v", vr.AsError())
        vr = validate.NewSchemaValidator(v.Schema, analyzed.Schema, "", strfmt.Default).Validate(map[string]interface{}{"baz" : "buzz"})
        log.Printf("SVal: %v", vr.AsError())
    }

    log.Printf("POST /alt")
    pf = analyzed.Analyzer.ParamsFor("POST", "/alt")
    for _, v := range(pf) {
        vr := validate.NewParamValidator(&v, strfmt.Default).Validate(37)
        log.Printf("Vr: %v", vr.AsError())
    }



    log.Printf("POST /alt2")
    pf = analyzed.Analyzer.ParamsFor("POST", "/alt2")
    for _, v := range(pf) {
        vr := validate.NewParamValidator(&v, strfmt.Default).Validate(map[string]interface{}{ "foo" : "bar"})
        log.Printf("PVal: %+v", vr.AsError())
        vr = validate.NewSchemaValidator(v.Schema, analyzed.Schema, "", strfmt.Default).Validate(map[string]interface{}{"baz" : "buzz"})
        log.Printf("SVal: %v", vr.AsError())
    }
}

Resulting (locally) in:

2016/07/08 08:25:23 POST /
2016/07/08 08:25:23 PVal: validation failure list:
body in body must be of type : "object"
2016/07/08 08:25:23 SVal: <nil>
2016/07/08 08:25:23 POST /alt
2016/07/08 08:25:23 Vr: validation failure list:
var1 in query must be of type string: "integer"
2016/07/08 08:25:23 POST /alt2
2016/07/08 08:25:23 PVal: validation failure list:
var1 in query must be of type : "object"
2016/07/08 08:25:23 SVal: <nil>

(PVal's are ParamValidators, SVal's are SchemaValidators)
The first is an object in 'body' with required parameters omitted - PVal throws a confusing error, SVal indicates no failure.
Second is a simple in 'query' string/integer mismatch - ParamValidatorl works as expected
Third is an object in 'query' with required parameters omitted, and again PVal throws a confusing error, SVal indicates no failure.

Am I 'doing it wrong'? Or is object validation less robust than I might have hoped?

Failed to validate proper spec file

Trying to validate example spec file petstore with the following code

package main

import (
	"github.com/go-openapi/loads"
	"github.com/go-openapi/spec"
	"github.com/go-openapi/strfmt"
	"github.com/go-openapi/validate"
)

func main() {
	fpath := "./v1.yaml"
	document, err := loads.Spec(fpath)
	if err != nil {
		panic("Failed to load spec: " + err.Error())
	}

	document, err = document.Expanded(&spec.ExpandOptions{RelativeBase: fpath})
	if err != nil {
		panic("Failed to expand spec: " + err.Error())
	}

	if err := validate.Spec(document, strfmt.Default); err != nil {
		panic("Spec is invalid: " + err.Error())
	}
}

It returns an error

$ pwd
/home/tetafro/Dev/go/src/myapi
$ go run main.go
panic: Spec is invalid: validation failure list:
read /home/tetafro/Dev/go/src/myapi: is a directory

goroutine 1 [running]:
main.main()
        /home/tetafro/Dev/go/src/myapi/main.go:23 +0x1d4
exit status 2

I'm using the latest versions of all imported packages.

Pattern function could probably store compiled patterns.

While doing so some optimization for an application using swagger, I noticed patterns are being compiled repeatedly. This is wasting CPU cycles for garbage collection routines and also unnecessary repeated compilation. Is it possible to cache the the compiled patterns in some map which can be re-used if necessary.

// Pattern validates a string against a regular expression
func Pattern(path, in, data, pattern string) *errors.Validation {
    re := regexp.MustCompile(pattern)
    if !re.MatchString(data) {
        return errors.FailedPattern(path, in, pattern)
    }
    return nil
}

Improve validation messages

We should improve the quality of messages reported by the validation.
In particular, we should be able in one single validation pass, to report about most known errors.
Also, validate should more resilient to spec errors and avoid panicking as much as possible.

Fix the following issues

A number of issues have already been posted about this.
This issue recaps the ones that might be short term improvements.

Add the following validation features

(not in other existing issues)

  • Improve checks on garbled path params ({x/y} , ..)
  • Check for path param uniqueness
  • Check path params are declared as required
  • Optional "continue on error" mode, to allow for checks to continue and sweep through all
    detected errors.
  • Replace regexp.MustCompile based on external output by simple compile and error management
  • More unit testing, with stricter assertions on errors, warnings and their numbers
  • Add check on multipleOf factor which must be positive

Examples are not validated

There is not support to validate examples in spec, with the exception of the Examples section in responses.
It should follow how we validate default values.

Also referred by:

Stack overflow fatal error occurred if the json schema has circular reference

If the json schema has circular reference defined, the validator will go into stack overflow fatal error and cause the program crash. Part of log:

runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow

runtime stack:
runtime.throw(0xa7f810, 0xe)
/usr/local/go/src/runtime/panic.go:530 +0x90
runtime.newstack()
/usr/local/go/src/runtime/stack.go:940 +0xb11
runtime.morestack()
/usr/local/go/src/runtime/asm_amd64.s:359 +0x7f

goroutine 64 [stack growth]:
/github.com/go-openapi/spec.expandSchema(0xc820b46240, 0xc820150500, 0x5, 0x8, 0xc8201556c0, 0x0, 0x8674cc)
/github.com/go-openapi/spec/expander.go:413 fp=0xc840a007b8 sp=0xc840a007b0
/github.com/go-openapi/spec.expandItems(0xc840a02268, 0xc820150500, 0x5, 0x8, 0xc8201556c0, 0x0, 0x0)
/github.com/go-openapi/spec/expander.go:398 +0xa3 fp=0xc840a00840 sp=0xc840a007b8
/github.com/go-openapi/spec.expandSchema(0xc840a02268, 0xc820150500, 0x5, 0x8, 0xc8201556c0, 0x0, 0x0)
/github.com/go-openapi/spec/expander.go:445 +0x431 fp=0xc840a01ea0 sp=0xc840a00840
/github.com/go-openapi/spec.expandSchema(0xc820b46240, 0xc820150500, 0x5, 0x8, 0xc8201556c0, 0x0, 0x0)

This is the swagger file, and cyclic definition in schema part is "TableFieldSchema" -> "TableFieldSchema".

googleapis.com_bigquery_v2.txt

Unfortunately in golang, there's no way to catch the fatal error. Can this issue be treated as critical since it will cause program crash which is very bad?

Question: struggling to understand type.go

Hello.
I am cross-checking schema validations, particularly regarding formatting.

I am struggling to understand the inner workings of typeValidator, and especially the schemaInfoForType() function.

At first glance, it looked to me that this big reflected type switch was very much dependant on strfmt types and should be kept in sync.

Then I realized this type switch can never be fully explored, because schemaValidator replaces any provided struct by its json equivalent (using swag.ToDynamicJSON).

I can see that some old TODOs still remain about handling structs, etc...

Could anyone explain what was the intent with checking all these types here?

It looks like the initial intent was different, could not be completed for some reason, then worked around using JSON.

Thanks

FRED

Is there any documentation/tutorial?

I could not find any tutorial or examples on how to use this package (maybe I missed it). Please let me know if there are some simple examples mentioned anywhere. Thanks.

Split validate package

The validate package suports two related but different use-cases:

  • validating swagger specs
  • validating data against schemas

I would say that validating swagger specs is itself broken in:

  • validating a swagger schema
  • running extra rules

This mix of features makes the validate package difficult to document, maintain and guarantee against regression, especially the very sensitive data against schema part, which is used by go-swagger model generator.

In my opinion, we should split the package in two parts:

  • a package dedicated to spec validation, and possibly json-schema validation (errors as go-openapi/validate/Result)
  • a package dedicated to data validation against json schema (errors from go-openapi/errors)

We could achieve that without breaking the existing interfaces using Go 1.9 type aliasing (https://github.com/golang/proposal/blob/master/design/18130-type-alias.md). However, that would break our current commitment for compatibility with 1.8.

Standalone validation of http.Request objects

Hi,

I am currently investigating the idea of writing a simple middleware for validating http requests and responses against a swagger spec in a proxy server. I.e. I do not want to use the whole middleware and router implementation provided by go-openapi.

I was wondering, if there is an example for that or if it is possible in general?

Cheers, Igor.

Delegate type reverse lookup for formats

In type.go, function schemaInfoForType() is essentially a reverse lookup of the format registry.

Currently, there some types missing from the default registry published by go-openapi/strfmt.

PR #60 added support for "mac" (following report from go-swagger/go-swagger#1348), but some remain missing:
Formats:
[ ] TODO: missing password
[ ] TODO: missing binary

Overall, keeping this reverse lookup in sync with strfmt is a real chore. Unit testing is not very useful either.

I suggest such type reverse lookup function to be handed over to strfmt.
Custom formats could bring their own mapping too.

Any thought?

Build and document message catalog

Advertise and document in godoc all reported messages.

This doc should distinguish:

  • messages and warnings produced by swagger spec validation rules
  • messages and warnings produced by swagger schema validator

Use vendoring

I tried running a test but faced errors due to an old go-openapi/loads package. I believe vendoring would have solved such errors.

What do you think of introducing a vendor directory using any preferred dependency management system (maybe dep)?

@sttts fyi

Validation: invalid patterns in parameters are not detected

An invalid pattern (for example a closing ')' not opened) in a parameter specification is not detected as invalid.

Regexp syntax should be checked both in parameters and schemas.

Here is an invalid spec that should be rejected by swagger validate (9d534e75942c4c135190752f634216aa92a2997c) but isn't:

{
  "swagger": "2.0",
  "info": {
    "version": "0.0.1",
    "title": "test of Swagger invalid pattern in parameter"
  },
  "parameters": {
    "userId": {
      "name": "userId",
      "in": "path",
      "type": "string",
      "pattern": ")<-- bad pattern",
      "required": true
    }
  },
  "paths": {
    "/users/{userId}": {
      "parameters": [
        { "$ref": "#/parameters/userId" }
      ],
      "get": {
        "responses": {
          "200": {
            "description": "Successful"
          }
        }
      }
    }
  }
}

see: go-swagger/go-swagger#530

validation message list contains duplicates

When validating a spec or schema sometimes the same error occurs many times

For the following spec there is only 1 operation but it renders the same error message 4 times.

swagger: '2.0'
info:
  title: swagger validate out of memory
  version: 0.1.0
paths:
  /foos:
    post:
      operationId: createFoo
      responses:
        200:
          schema:
            $ref: '#/definitions/Foo'

definitions:
  Foo:
    type: object
    properties:
      bar:
        $ref: '#/definitions/Bar'
      baz:
        $ref: '#/definitions/Baz'

  Bar:
    type: string
    enum:
      - a
      - b

  Baz:
    type: array
    items:
      type: string

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.