openapi_parser 2.2.0 → 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e38224603546bc8818028b725452113a5c3b62811675e1bc7390aeb9b408a2a
4
- data.tar.gz: 6e6b0352a64a35d2a71a001931910d7e15ea4aa3a36a5aebee68f2aa6e6b367e
3
+ metadata.gz: ee47209ddc3182fdab488acfbda8e2fd628ab0bd0979bd04e60fcbf7f71365f3
4
+ data.tar.gz: 66a4c16d27ddeffd927ec5df1124572d3c885c3759630f0cae3edb9a122355f8
5
5
  SHA512:
6
- metadata.gz: 5bc8816e1059379a014e2bfc702068edcc31b6adeddb2f3747094314c01df680cf431774d1fb1bb407497501e454ff4b7571e969f83eec19b6276b3de21d302d
7
- data.tar.gz: e0819dbee935685d25793da062afb1dd850adeac72ba25efe917a86e46e46fb23e969f02d0402ab39a5111d765e4501ebdb93d679dc36322ddb69cae3bf6dcb8
6
+ metadata.gz: 3a7d3ec2c6e75fa903203dbae2a607f152e59e1299ab053df8923b9c8b69539a89dfa98a757481d8cb8dedec7e8e362c1f13f01a7087baff6dd017cd2c3dc3e9
7
+ data.tar.gz: 19cd5e1d6079c0b69f2ed4e849cc23a0d7b7e67fd780ad4cf2bb430d9ffbe86d4f84c36c8173e74f25905460c51af4d579f2fe19f3db215837ddef763c1fd1da
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## Unreleased
2
2
 
3
+ ## 2.2.2 (2024-11-21)
4
+ * make content-type lookup case-insensitive #178
5
+
6
+ ## 2.2.1 (2024-10-23)
7
+ * revert schemas validation in additionalProperties and remove additionalProperties logic from allof (breaking things for me, will revisit)
8
+
3
9
  ## 2.2.0 (2024-10-23)
4
10
  ### Fixed
5
11
  * support schemas validation in additionalProperties and remove additionalProperties logic from allof
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![Yard Docs](https://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/gems/openapi_parser)
5
5
  [![Inch CI](https://inch-ci.org/github/ota42y/openapi_parser.svg?branch=master)](https://inch-ci.org/github/ota42y/openapi_parser)
6
6
 
7
- This is OpenAPI3 parser and validator.
7
+ This is OpenAPI3 parser and validator.
8
8
 
9
9
  ## Usage
10
10
 
@@ -27,8 +27,8 @@ request_operation.path_params
27
27
  # => {"template_name"=>"1"}
28
28
 
29
29
  # coerce parameter
30
- root = OpenAPIParser.parse(YAML.load_file('open_api_3/schema.yml'), {coerce_value: true, datetime_coerce_class: DateTime})
31
- request_operation = root.request_operation(:get, '/string_params_coercer')
30
+ root = OpenAPIParser.parse(YAML.load_file('open_api_3/schema.yml'), {coerce_value: true, datetime_coerce_class: DateTime})
31
+ request_operation = root.request_operation(:get, '/string_params_coercer')
32
32
  request_operation.validate_request_parameter({'integer_1' => '1', 'datetime_string' => '2016-04-01T16:00:00+09:00'})
33
33
  # => {"integer_1"=>1, "datetime_string"=>#<DateTime: 2016-04-01T16:00:00+09:00 ((2457480j,25200s,0n),+32400s,2299161j)>
34
34
  # convert number string to Integer and datetime string to DateTime class
@@ -52,7 +52,7 @@ Or install it yourself as:
52
52
  $ gem install openapi_parser
53
53
 
54
54
  ## Additional features
55
- OpenAPI Parser's validation based on [OpenAPI spec](https://github.com/OAI/OpenAPI-Specification)
55
+ OpenAPI Parser's validation based on [OpenAPI spec](https://github.com/OAI/OpenAPI-Specification)
56
56
  But we support few useful features.
57
57
 
58
58
  ### type validation
@@ -109,4 +109,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
109
109
 
110
110
  ## Code of Conduct
111
111
 
112
- Everyone interacting in the OpenAPIParser project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/openapi_parser/blob/master/CODE_OF_CONDUCT.md).
112
+ Everyone interacting in the OpenAPIParser project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/ota42y/openapi_parser/blob/master/CODE_OF_CONDUCT.md).
data/SECURITY.md ADDED
@@ -0,0 +1,6 @@
1
+ ## Security contact information
2
+
3
+ To report a security vulnerability, please contact
4
+ [Tidelift security](https://tidelift.com/security).
5
+
6
+ Tidelift will coordinate the fix and disclosure.
@@ -160,6 +160,28 @@ module OpenAPIParser
160
160
  end
161
161
  end
162
162
 
163
+ class LessThanMinProperties < OpenAPIError
164
+ def initialize(value, reference)
165
+ super(reference)
166
+ @value = value
167
+ end
168
+
169
+ def message
170
+ "#{@reference} #{@value.size} is less than minProperties value"
171
+ end
172
+ end
173
+
174
+ class MoreThanMaxProperties < OpenAPIError
175
+ def initialize(value, reference)
176
+ super(reference)
177
+ @value = value
178
+ end
179
+
180
+ def message
181
+ "#{@reference} #{@value.size} is more than maxProperties value"
182
+ end
183
+ end
184
+
163
185
  class InvalidPattern < OpenAPIError
164
186
  def initialize(value, pattern, reference, example)
165
187
  super(reference)
@@ -78,7 +78,8 @@ class OpenAPIParser::RequestOperation
78
78
  end
79
79
 
80
80
  def content_type
81
- headers['Content-Type'].to_s.split(';').first.to_s
81
+ content_type_key = headers.keys.detect { |k| k.casecmp?('Content-Type') }
82
+ headers[content_type_key].to_s.split(';').first.to_s
82
83
  end
83
84
  end
84
85
  end
@@ -10,6 +10,8 @@ class OpenAPIParser::SchemaValidator
10
10
  end
11
11
 
12
12
  # if any schema return error, it's not valida all of value
13
+ remaining_keys = value.kind_of?(Hash) ? value.keys : []
14
+ nested_additional_properties = false
13
15
  schema.all_of.each do |s|
14
16
  # We need to store the reference to all of, so we can perform strict check on allowed properties
15
17
  _coerced, err = validatable.validate_schema(
@@ -18,9 +20,24 @@ class OpenAPIParser::SchemaValidator
18
20
  :parent_all_of => true,
19
21
  parent_discriminator_schemas: keyword_args[:parent_discriminator_schemas]
20
22
  )
23
+
24
+ if s.type == "object"
25
+ remaining_keys -= (s.properties || {}).keys
26
+ nested_additional_properties = true if s.additional_properties
27
+ else
28
+ # If this is not allOf having array of objects inside, but e.g. having another anyOf/oneOf nested
29
+ remaining_keys.clear
30
+ end
31
+
21
32
  return [nil, err] if err
22
33
  end
23
34
 
35
+ # If there are nested additionalProperites, we allow not defined extra properties and lean on the specific
36
+ # additionalProperties validation
37
+ if !nested_additional_properties && !remaining_keys.empty?
38
+ return [nil, OpenAPIParser::NotExistPropertyDefinition.new(remaining_keys, schema.object_reference)]
39
+ end
40
+
24
41
  [value, nil]
25
42
  end
26
43
  end
@@ -1,5 +1,7 @@
1
1
  class OpenAPIParser::SchemaValidator
2
2
  class ObjectValidator < Base
3
+ include ::OpenAPIParser::SchemaValidator::PropertiesNumber
4
+
3
5
  # @param [Hash] value
4
6
  # @param [OpenAPIParser::Schemas::Schema] schema
5
7
  # @param [Boolean] parent_all_of true if component is nested under allOf
@@ -27,9 +29,9 @@ class OpenAPIParser::SchemaValidator
27
29
  coerced, err = if s
28
30
  remaining_keys.delete(name)
29
31
  validatable.validate_schema(v, s)
30
- elsif schema.additional_properties != true && schema.additional_properties != false
31
- validatable.validate_schema(v, schema.additional_properties)
32
32
  else
33
+ # TODO: we need to perform a validation based on schema.additional_properties here, if
34
+ # additionalProperties are defined
33
35
  [v, nil]
34
36
  end
35
37
 
@@ -41,14 +43,16 @@ class OpenAPIParser::SchemaValidator
41
43
 
42
44
  remaining_keys.delete(discriminator_property_name) if discriminator_property_name
43
45
 
44
- if !remaining_keys.empty? && !schema.additional_properties
46
+ if !remaining_keys.empty? && !parent_all_of && !schema.additional_properties
47
+ # If object is nested in all of, the validation is already done in allOf validator. Or if
48
+ # additionalProperties are defined, we will validate using that
45
49
  return [nil, OpenAPIParser::NotExistPropertyDefinition.new(remaining_keys, schema.object_reference)]
46
50
  end
47
51
  return [nil, OpenAPIParser::NotExistRequiredKey.new(required_set.to_a, schema.object_reference)] unless required_set.empty?
48
52
 
49
53
  value.merge!(coerced_values.to_h) if @coerce_value
50
54
 
51
- [value, nil]
55
+ check_properties_number(value, schema)
52
56
  end
53
57
  end
54
58
  end
@@ -0,0 +1,30 @@
1
+ class OpenAPIParser::SchemaValidator
2
+ module PropertiesNumber
3
+ # check minProperties and manProperties value by schema
4
+ # @param [Object] value
5
+ # @param [OpenAPIParser::Schemas::Schema] schema
6
+ def check_properties_number(value, schema)
7
+ include_properties_num = schema.minProperties || schema.maxProperties
8
+ return [value, nil] unless include_properties_num
9
+
10
+ validate(value, schema)
11
+ [value, nil]
12
+ rescue OpenAPIParser::OpenAPIError => e
13
+ return [nil, e]
14
+ end
15
+
16
+ private
17
+
18
+ def validate(value, schema)
19
+ reference = schema.object_reference
20
+
21
+ if schema.minProperties && (value.size < schema.minProperties)
22
+ raise OpenAPIParser::LessThanMinProperties.new(value, reference)
23
+ end
24
+
25
+ if schema.maxProperties && (value.size > schema.maxProperties)
26
+ raise OpenAPIParser::MoreThanMaxProperties.new(value, reference)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -71,6 +71,8 @@ class OpenAPIParser::SchemaValidator
71
71
  def validate_date_format(value, schema)
72
72
  return [value, nil] unless schema.format == 'date'
73
73
 
74
+ return [nil, OpenAPIParser::InvalidDateFormat.new(value, schema.object_reference)] unless value =~ /^\d{4}-\d{2}-\d{2}$/
75
+
74
76
  begin
75
77
  parsed_date = Date.iso8601(value)
76
78
  rescue ArgumentError
@@ -1,6 +1,7 @@
1
1
  require_relative 'schema_validator/options'
2
2
  require_relative 'schema_validator/enumable'
3
3
  require_relative 'schema_validator/minimum_maximum'
4
+ require_relative 'schema_validator/properties_number'
4
5
  require_relative 'schema_validator/base'
5
6
  require_relative 'schema_validator/string_validator'
6
7
  require_relative 'schema_validator/integer_validator'
@@ -21,9 +21,11 @@ module OpenAPIParser::Schemas
21
21
 
22
22
  media_type = select_media_type(response_body.content_type)
23
23
  unless media_type
24
- raise ::OpenAPIParser::NotExistContentTypeDefinition, object_reference if response_validate_options.strict
24
+ if response_validate_options.strict && response_body_not_blank(response_body)
25
+ raise ::OpenAPIParser::NotExistContentTypeDefinition, object_reference
26
+ end
25
27
 
26
- return nil
28
+ return true
27
29
  end
28
30
 
29
31
  options = ::OpenAPIParser::SchemaValidator::Options.new # response validator not support any options
@@ -39,6 +41,11 @@ module OpenAPIParser::Schemas
39
41
 
40
42
  private
41
43
 
44
+ # @param [OpenAPIParser::RequestOperation::ValidatableResponseBody]
45
+ def response_body_not_blank(response_body)
46
+ !(response_body.response_data.nil? || response_body.response_data.empty?)
47
+ end
48
+
42
49
  # @param [Hash] response_headers
43
50
  def validate_header(response_headers)
44
51
  return unless headers
@@ -1,3 +1,3 @@
1
1
  module OpenAPIParser
2
- VERSION = '2.2.0'.freeze
2
+ VERSION = '2.2.2'.freeze
3
3
  end
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: 2.2.0
4
+ version: 2.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ota42y
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-23 00:00:00.000000000 Z
11
+ date: 2024-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -142,6 +142,7 @@ files:
142
142
  - LICENSE.txt
143
143
  - README.md
144
144
  - Rakefile
145
+ - SECURITY.md
145
146
  - Steepfile
146
147
  - bin/console
147
148
  - bin/setup
@@ -186,6 +187,7 @@ files:
186
187
  - lib/openapi_parser/schema_validator/object_validator.rb
187
188
  - lib/openapi_parser/schema_validator/one_of_validator.rb
188
189
  - lib/openapi_parser/schema_validator/options.rb
190
+ - lib/openapi_parser/schema_validator/properties_number.rb
189
191
  - lib/openapi_parser/schema_validator/string_validator.rb
190
192
  - lib/openapi_parser/schema_validator/unspecified_type_validator.rb
191
193
  - lib/openapi_parser/schemas.rb