openapi_parser 0.2.7 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/lib/openapi_parser/errors.rb +15 -4
- data/lib/openapi_parser/parameter_validator.rb +8 -2
- data/lib/openapi_parser/schema_validator.rb +7 -3
- data/lib/openapi_parser/schema_validators/all_of_validator.rb +21 -2
- data/lib/openapi_parser/schema_validators/any_of_validator.rb +1 -1
- data/lib/openapi_parser/schema_validators/array_validator.rb +1 -1
- data/lib/openapi_parser/schema_validators/base.rb +8 -7
- data/lib/openapi_parser/schema_validators/boolean_validator.rb +1 -1
- data/lib/openapi_parser/schema_validators/float_validator.rb +1 -1
- data/lib/openapi_parser/schema_validators/integer_validator.rb +1 -1
- data/lib/openapi_parser/schema_validators/nil_validator.rb +1 -1
- data/lib/openapi_parser/schema_validators/object_validator.rb +20 -2
- data/lib/openapi_parser/schema_validators/one_of_validator.rb +1 -1
- data/lib/openapi_parser/schema_validators/string_validator.rb +1 -1
- data/lib/openapi_parser/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc1cad9d7c07f7d5ce382429089820959ac182353a6b8daf545fc6408384af85
|
4
|
+
data.tar.gz: 00bef8afe01fbfddf5feceec03ef7bd1daba208ea0efce36b1413bbd2be28e32
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9888a1912dc0ea3bace51771ee7524492bbb152a765b5c312c39bb94af3bfe17b108899c567377a1e1e51fc426804c94beb0bd0156d14561e9c1e7dc0229fe0
|
7
|
+
data.tar.gz: 95111afc9c980cc707cc81cfe4551ade4aadd0e24e69c9bb951d92c293806b63983e535a0ba7ea5d16f1c6bf8decb053f114c98b7114b00108c494972868e9cb
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
## Unreleased
|
2
2
|
|
3
|
+
## 0.3.0 (2019-06-01)
|
4
|
+
|
5
|
+
### features
|
6
|
+
* Perform a strict check on object properties (#33)
|
7
|
+
|
8
|
+
### Bugfix
|
9
|
+
* Support discriminator without mapping (#35)
|
10
|
+
* Fix upper case request param validation (#38)
|
11
|
+
|
3
12
|
## 0.2.7 (2019-05-20)
|
4
13
|
* Fix for release miss
|
5
14
|
|
@@ -43,14 +43,25 @@ module OpenAPIParser
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
class
|
47
|
-
def initialize(
|
46
|
+
class NotExistPropertyDefinition < OpenAPIError
|
47
|
+
def initialize(keys, reference)
|
48
|
+
super(reference)
|
49
|
+
@keys = keys
|
50
|
+
end
|
51
|
+
|
52
|
+
def message
|
53
|
+
"properties #{@keys.join(",")} are not defined in #{@reference}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class NotExistDiscriminatorMappedSchema < OpenAPIError
|
58
|
+
def initialize(mapped_schema_reference, reference)
|
48
59
|
super(reference)
|
49
|
-
@
|
60
|
+
@mapped_schema_reference = mapped_schema_reference
|
50
61
|
end
|
51
62
|
|
52
63
|
def message
|
53
|
-
"discriminator
|
64
|
+
"discriminator mapped schema #{@mapped_schema_reference} does not exist in #{@reference}"
|
54
65
|
end
|
55
66
|
end
|
56
67
|
|
@@ -8,9 +8,9 @@ class OpenAPIParser::ParameterValidator
|
|
8
8
|
def validate_parameter(parameters_hash, params, object_reference, options, is_header = false)
|
9
9
|
no_exist_required_key = []
|
10
10
|
|
11
|
-
params_key_converted = params.keys.map { |k| [(
|
11
|
+
params_key_converted = params.keys.map { |k| [convert_key(k, is_header), k] }.to_h
|
12
12
|
parameters_hash.each do |k, v|
|
13
|
-
key = params_key_converted[k
|
13
|
+
key = params_key_converted[convert_key(k, is_header)]
|
14
14
|
if params.include?(key)
|
15
15
|
coerced = v.validate_params(params[key], options)
|
16
16
|
params[key] = coerced if options.coerce_value
|
@@ -23,5 +23,11 @@ class OpenAPIParser::ParameterValidator
|
|
23
23
|
|
24
24
|
params
|
25
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def convert_key(k, is_header)
|
30
|
+
is_header ? k&.downcase : k
|
31
|
+
end
|
26
32
|
end
|
27
33
|
end
|
@@ -18,7 +18,7 @@ class OpenAPIParser::SchemaValidator
|
|
18
18
|
# @param [Object] value
|
19
19
|
# @param [OpenAPIParser::Schemas::Schema] schema
|
20
20
|
module Validatable
|
21
|
-
def validate_schema(value, schema)
|
21
|
+
def validate_schema(value, schema, **keyword_args)
|
22
22
|
raise 'implement'
|
23
23
|
end
|
24
24
|
|
@@ -66,11 +66,15 @@ class OpenAPIParser::SchemaValidator
|
|
66
66
|
# validate value eby schema
|
67
67
|
# @param [Object] value
|
68
68
|
# @param [OpenAPIParser::Schemas::Schema] schema
|
69
|
-
def validate_schema(value, schema)
|
69
|
+
def validate_schema(value, schema, **keyword_args)
|
70
70
|
return [value, nil] unless schema
|
71
71
|
|
72
72
|
if (v = validator(value, schema))
|
73
|
-
|
73
|
+
if keyword_args.empty?
|
74
|
+
return v.coerce_and_validate(value, schema)
|
75
|
+
else
|
76
|
+
return v.coerce_and_validate(value, schema, **keyword_args)
|
77
|
+
end
|
74
78
|
end
|
75
79
|
|
76
80
|
# unknown return error
|
@@ -4,12 +4,31 @@ class OpenAPIParser::SchemaValidator
|
|
4
4
|
# coerce and validate value
|
5
5
|
# @param [Object] value
|
6
6
|
# @param [OpenAPIParser::Schemas::Schema] schema
|
7
|
-
def coerce_and_validate(value, schema)
|
7
|
+
def coerce_and_validate(value, schema, **_keyword_args)
|
8
8
|
# if any schema return error, it's not valida all of value
|
9
|
+
remaining_keys = value.kind_of?(Hash) ? value.keys : []
|
10
|
+
nested_additional_properties = false
|
9
11
|
schema.all_of.each do |s|
|
10
|
-
|
12
|
+
# We need to store the reference to all of, so we can perform strict check on allowed properties
|
13
|
+
_coerced, err = validatable.validate_schema(value, s, :parent_all_of => true)
|
14
|
+
|
15
|
+
if s.type == "object"
|
16
|
+
remaining_keys -= (s.properties || {}).keys
|
17
|
+
nested_additional_properties = true if s.additional_properties
|
18
|
+
else
|
19
|
+
# If this is not allOf having array of objects inside, but e.g. having another anyOf/oneOf nested
|
20
|
+
remaining_keys.clear
|
21
|
+
end
|
22
|
+
|
11
23
|
return [nil, err] if err
|
12
24
|
end
|
25
|
+
|
26
|
+
# If there are nested additionalProperites, we allow not defined extra properties and lean on the specific
|
27
|
+
# additionalProperties validation
|
28
|
+
if !nested_additional_properties && !remaining_keys.empty?
|
29
|
+
return [nil, OpenAPIParser::NotExistPropertyDefinition.new(remaining_keys, schema.object_reference)]
|
30
|
+
end
|
31
|
+
|
13
32
|
[value, nil]
|
14
33
|
end
|
15
34
|
end
|
@@ -2,7 +2,7 @@ class OpenAPIParser::SchemaValidator
|
|
2
2
|
class AnyOfValidator < Base
|
3
3
|
# @param [Object] value
|
4
4
|
# @param [OpenAPIParser::Schemas::Schema] schema
|
5
|
-
def coerce_and_validate(value, schema)
|
5
|
+
def coerce_and_validate(value, schema, **_keyword_args)
|
6
6
|
if schema.discriminator
|
7
7
|
return validate_discriminator_schema(schema.discriminator, value)
|
8
8
|
end
|
@@ -2,7 +2,7 @@ class OpenAPIParser::SchemaValidator
|
|
2
2
|
class ArrayValidator < Base
|
3
3
|
# @param [Array] value
|
4
4
|
# @param [OpenAPIParser::Schemas::Schema] schema
|
5
|
-
def coerce_and_validate(value, schema)
|
5
|
+
def coerce_and_validate(value, schema, **_keyword_args)
|
6
6
|
return OpenAPIParser::ValidateError.build_error_result(value, schema) unless value.kind_of?(Array)
|
7
7
|
|
8
8
|
# array type have an schema in items property
|
@@ -14,7 +14,7 @@ class OpenAPIParser::SchemaValidator
|
|
14
14
|
# need override
|
15
15
|
# @param [Array] _value
|
16
16
|
# @param [OpenAPIParser::Schemas::Schema] _schema
|
17
|
-
def coerce_and_validate(_value, _schema)
|
17
|
+
def coerce_and_validate(_value, _schema, **_keyword_args)
|
18
18
|
raise 'need implement'
|
19
19
|
end
|
20
20
|
|
@@ -24,16 +24,17 @@ class OpenAPIParser::SchemaValidator
|
|
24
24
|
end
|
25
25
|
mapping_key = value[discriminator.property_name]
|
26
26
|
|
27
|
-
#
|
27
|
+
# it's allowed to have discriminator without mapping, then we need to lookup discriminator.property_name
|
28
28
|
# but the format is not the full path, just model name in the components
|
29
|
-
mapping_target = discriminator.mapping[mapping_key
|
30
|
-
unless mapping_target
|
31
|
-
return [nil, OpenAPIParser::NotExistDiscriminatorMappingTarget.new(mapping_key, discriminator.object_reference)]
|
32
|
-
end
|
29
|
+
mapping_target = discriminator.mapping&.[](mapping_key) || "#/components/schemas/#{mapping_key}"
|
33
30
|
|
34
31
|
# Find object does O(n) search at worst, then caches the result, so this is ok for repeated search
|
35
32
|
resolved_schema = discriminator.root.find_object(mapping_target)
|
36
|
-
|
33
|
+
|
34
|
+
unless resolved_schema
|
35
|
+
return [nil, OpenAPIParser::NotExistDiscriminatorMappedSchema.new(mapping_target, discriminator.object_reference)]
|
36
|
+
end
|
37
|
+
validatable.validate_schema(value, resolved_schema, {discriminator_property_name: discriminator.property_name})
|
37
38
|
end
|
38
39
|
end
|
39
40
|
end
|
@@ -3,7 +3,7 @@ class OpenAPIParser::SchemaValidator
|
|
3
3
|
TRUE_VALUES = ['true', '1'].freeze
|
4
4
|
FALSE_VALUES = ['false', '0'].freeze
|
5
5
|
|
6
|
-
def coerce_and_validate(value, schema)
|
6
|
+
def coerce_and_validate(value, schema, **_keyword_args)
|
7
7
|
value = coerce(value) if @coerce_value
|
8
8
|
|
9
9
|
return OpenAPIParser::ValidateError.build_error_result(value, schema) unless value.kind_of?(TrueClass) || value.kind_of?(FalseClass)
|
@@ -5,7 +5,7 @@ class OpenAPIParser::SchemaValidator
|
|
5
5
|
# validate float value by schema
|
6
6
|
# @param [Object] value
|
7
7
|
# @param [OpenAPIParser::Schemas::Schema] schema
|
8
|
-
def coerce_and_validate(value, schema)
|
8
|
+
def coerce_and_validate(value, schema, **_keyword_args)
|
9
9
|
value = coerce(value) if @coerce_value
|
10
10
|
|
11
11
|
return validatable.validate_integer(value, schema) if value.kind_of?(Integer)
|
@@ -5,7 +5,7 @@ class OpenAPIParser::SchemaValidator
|
|
5
5
|
# validate integer value by schema
|
6
6
|
# @param [Object] value
|
7
7
|
# @param [OpenAPIParser::Schemas::Schema] schema
|
8
|
-
def coerce_and_validate(value, schema)
|
8
|
+
def coerce_and_validate(value, schema, **_keyword_args)
|
9
9
|
value = coerce(value) if @coerce_value
|
10
10
|
|
11
11
|
return OpenAPIParser::ValidateError.build_error_result(value, schema) unless value.kind_of?(Integer)
|
@@ -2,7 +2,7 @@ class OpenAPIParser::SchemaValidator
|
|
2
2
|
class NilValidator < Base
|
3
3
|
# @param [Object] value
|
4
4
|
# @param [OpenAPIParser::Schemas::Schema] schema
|
5
|
-
def coerce_and_validate(value, schema)
|
5
|
+
def coerce_and_validate(value, schema, **_keyword_args)
|
6
6
|
return [value, nil] if schema.nullable
|
7
7
|
|
8
8
|
[nil, OpenAPIParser::NotNullError.new(schema.object_reference)]
|
@@ -2,22 +2,40 @@ class OpenAPIParser::SchemaValidator
|
|
2
2
|
class ObjectValidator < Base
|
3
3
|
# @param [Hash] value
|
4
4
|
# @param [OpenAPIParser::Schemas::Schema] schema
|
5
|
-
|
5
|
+
# @param [Boolean] parent_all_of true if component is nested under allOf
|
6
|
+
# @param [String, nil] discriminator_property_name discriminator.property_name to ignore checking additional_properties
|
7
|
+
def coerce_and_validate(value, schema, parent_all_of: false, discriminator_property_name: nil)
|
6
8
|
return OpenAPIParser::ValidateError.build_error_result(value, schema) unless value.kind_of?(Hash)
|
7
9
|
|
8
10
|
return [value, nil] unless schema.properties
|
9
11
|
|
10
12
|
required_set = schema.required ? schema.required.to_set : Set.new
|
13
|
+
remaining_keys = value.keys
|
11
14
|
|
12
15
|
coerced_values = value.map do |name, v|
|
13
16
|
s = schema.properties[name]
|
14
|
-
coerced, err =
|
17
|
+
coerced, err = if s
|
18
|
+
remaining_keys.delete(name)
|
19
|
+
validatable.validate_schema(v, s)
|
20
|
+
else
|
21
|
+
# TODO: we need to perform a validation based on schema.additional_properties here, if
|
22
|
+
# additionalProperties are defined
|
23
|
+
[v, nil]
|
24
|
+
end
|
25
|
+
|
15
26
|
return [nil, err] if err
|
16
27
|
|
17
28
|
required_set.delete(name)
|
18
29
|
[name, coerced]
|
19
30
|
end
|
20
31
|
|
32
|
+
remaining_keys.delete(discriminator_property_name) if discriminator_property_name
|
33
|
+
|
34
|
+
if !remaining_keys.empty? && !parent_all_of && !schema.additional_properties
|
35
|
+
# If object is nested in all of, the validation is already done in allOf validator. Or if
|
36
|
+
# additionalProperties are defined, we will validate using that
|
37
|
+
return [nil, OpenAPIParser::NotExistPropertyDefinition.new(remaining_keys, schema.object_reference)]
|
38
|
+
end
|
21
39
|
return [nil, OpenAPIParser::NotExistRequiredKey.new(required_set.to_a, schema.object_reference)] unless required_set.empty?
|
22
40
|
|
23
41
|
value.merge!(coerced_values.to_h) if @coerce_value
|
@@ -2,7 +2,7 @@ class OpenAPIParser::SchemaValidator
|
|
2
2
|
class OneOfValidator < Base
|
3
3
|
# @param [Object] value
|
4
4
|
# @param [OpenAPIParser::Schemas::Schema] schema
|
5
|
-
def coerce_and_validate(value, schema)
|
5
|
+
def coerce_and_validate(value, schema, **_keyword_args)
|
6
6
|
if schema.discriminator
|
7
7
|
return validate_discriminator_schema(schema.discriminator, value)
|
8
8
|
end
|
@@ -7,7 +7,7 @@ class OpenAPIParser::SchemaValidator
|
|
7
7
|
@datetime_coerce_class = datetime_coerce_class
|
8
8
|
end
|
9
9
|
|
10
|
-
def coerce_and_validate(value, schema)
|
10
|
+
def coerce_and_validate(value, schema, **_keyword_args)
|
11
11
|
return OpenAPIParser::ValidateError.build_error_result(value, schema) unless value.kind_of?(String)
|
12
12
|
|
13
13
|
value, err = check_enum_include(value, schema)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openapi_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ota42y
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|