From fbd40f2f8e85159448d18858e17770864835d281 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Thu, 14 Feb 2013 13:25:05 -0800 Subject: [PATCH] Only allow defined formats. We've been accidentally using invalid formats like "timestamp" in some places, so this helps ensure we use formats that will actually have a validation effect. --- lib/interpol/endpoint.rb | 26 ++++++++++++++++++++++++++ spec/unit/interpol/endpoint_spec.rb | 20 ++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/lib/interpol/endpoint.rb b/lib/interpol/endpoint.rb index 12d2504..5c9346d 100644 --- a/lib/interpol/endpoint.rb +++ b/lib/interpol/endpoint.rb @@ -21,6 +21,32 @@ def data_valid_for_type?(data, type) end end end + + # Monkey patch json-schema to only allow the defined formats. + # We've been accidentally using invalid formats like "timestamp", + # so this will help ensure we only use valid ones. + class Validator + VALID_FORMATS = %w[ + date-time date time utc-millisec regex color style + phone uri email ip-address ipv6 host-name + ] + + def open(uri) + return super unless uri.start_with?('file://') && uri.end_with?('draft-03.json') + return StringIO.new(Validator.overriden_draft_03) if Validator.overriden_draft_03 + + schema = JSON.parse(super.read) + schema.fetch("properties").fetch("format")["enum"] = VALID_FORMATS + + override = JSON.dump(schema) + Validator.overriden_draft_03 = override + StringIO.new(override) + end + + class << self + attr_accessor :overriden_draft_03 + end + end end module Interpol diff --git a/spec/unit/interpol/endpoint_spec.rb b/spec/unit/interpol/endpoint_spec.rb index ddd3cae..540498d 100644 --- a/spec/unit/interpol/endpoint_spec.rb +++ b/spec/unit/interpol/endpoint_spec.rb @@ -323,6 +323,26 @@ def new_with(hash) }.to raise_error(ValidationError) end + let(:date_time_string) { "2012-12-12T08:23:12Z" } + + it 'rejects unrecognized format options' do + schema['properties']['foo']['type'] = 'string' + schema['properties']['foo']['format'] = 'timestamp' # the valid format is date-time + + expect { + subject.validate_data!('foo' => date_time_string) + }.to raise_error(ValidationError, %r|'#/properties/foo/format' value "timestamp"|) + end + + it 'allows recognized format options' do + schema['properties']['foo']['type'] = 'string' + schema['properties']['foo']['format'] = 'date-time' + + expect { + subject.validate_data!('foo' => date_time_string) + }.not_to raise_error + end + it 'requires all properties' do expect { subject.validate_data!({})