Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle readOnly #171

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/openapi_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ def parse_file(content, ext)

def parse_yaml(content)
# FIXME: when drop ruby 2.5, we should use permitted_classes
(Gem::Version.create(RUBY_VERSION) < Gem::Version.create("2.6.0")) ?
Psych.safe_load(content, [Date, Time]) :
(Gem::Version.create(RUBY_VERSION) < Gem::Version.create("2.6.0")) ?
Psych.safe_load(content, [Date, Time]) :
Psych.safe_load(content, permitted_classes: [Date, Time])
end

def parse_json(content)
raise "json content is nil" unless content
raise "json content is nil" unless content
JSON.parse(content)
end

Expand Down
8 changes: 7 additions & 1 deletion lib/openapi_parser/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,17 @@ def validate_header
@config.fetch(:validate_header, true)
end

# TODO: in a major version update, change this to default to `ignore`.
def handle_readOnly
@config.fetch(:handle_readOnly, nil)
end

# @return [OpenAPIParser::SchemaValidator::Options]
def request_validator_options
@request_validator_options ||= OpenAPIParser::SchemaValidator::Options.new(coerce_value: coerce_value,
datetime_coerce_class: datetime_coerce_class,
validate_header: validate_header)
validate_header: validate_header,
handle_readOnly: handle_readOnly)
end

alias_method :request_body_options, :request_validator_options
Expand Down
3 changes: 2 additions & 1 deletion lib/openapi_parser/schema_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def initialize(value, schema, options)
@schema = schema
@coerce_value = options.coerce_value
@datetime_coerce_class = options.datetime_coerce_class
@handle_readOnly = options.handle_readOnly
end

# execute validate data
Expand Down Expand Up @@ -135,7 +136,7 @@ def boolean_validator
end

def object_validator
@object_validator ||= OpenAPIParser::SchemaValidator::ObjectValidator.new(self, @coerce_value)
@object_validator ||= OpenAPIParser::SchemaValidator::ObjectValidator.new(self, @coerce_value, @handle_readOnly)
end

def array_validator
Expand Down
14 changes: 14 additions & 0 deletions lib/openapi_parser/schema_validator/object_validator.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
class OpenAPIParser::SchemaValidator
class ObjectValidator < Base

def initialize(validator, coerce_value, handle_readOnly)
super(validator, coerce_value)
@handle_readOnly = handle_readOnly
end
# @param [Hash] value
# @param [OpenAPIParser::Schemas::Schema] schema
# @param [Boolean] parent_all_of true if component is nested under allOf
Expand All @@ -10,6 +15,15 @@ def coerce_and_validate(value, schema, parent_all_of: false, parent_discriminato
properties = schema.properties || {}

required_set = schema.required ? schema.required.to_set : Set.new

if @handle_readOnly == :ignore
schema.properties.each do |name, property_value|
next unless property_value.read_only
required_set.delete(name)
value.delete(name)
end
end

remaining_keys = value.keys

if schema.discriminator && !parent_discriminator_schemas.include?(schema)
Expand Down
7 changes: 5 additions & 2 deletions lib/openapi_parser/schema_validator/options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ class Options
# @return [Object, nil] coerce datetime string by this Object class
# @!attribute [r] validate_header
# @return [Boolean] validate header or not
attr_reader :coerce_value, :datetime_coerce_class, :validate_header
# @!attribute [r] handle_readOnly
# @return [Object, nil] How to use readOnly property to process requests. Either :ignore or :raise
attr_reader :coerce_value, :datetime_coerce_class, :validate_header, :handle_readOnly

def initialize(coerce_value: nil, datetime_coerce_class: nil, validate_header: true)
def initialize(coerce_value: nil, datetime_coerce_class: nil, validate_header: true, handle_readOnly: nil)
@coerce_value = coerce_value
@datetime_coerce_class = datetime_coerce_class
@validate_header = validate_header
@handle_readOnly = handle_readOnly
end
end

Expand Down