From c259d401bbb355418413e5ffd7e3a8bba746d8c8 Mon Sep 17 00:00:00 2001 From: Douglas Gabriel Date: Thu, 21 Dec 2017 15:27:44 -0300 Subject: [PATCH] adding hostname format validation --- app/models/ext_management_system.rb | 8 ++++++- config/application.rb | 3 ++- lib/validators/hostname.rb | 18 ++++++++++++++++ spec/lib/validators/hostname_spec.rb | 31 ++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 lib/validators/hostname.rb create mode 100644 spec/lib/validators/hostname_spec.rb diff --git a/app/models/ext_management_system.rb b/app/models/ext_management_system.rb index 3d52177f4293..63c7242a348c 100644 --- a/app/models/ext_management_system.rb +++ b/app/models/ext_management_system.rb @@ -76,7 +76,7 @@ def self.supported_types_and_descriptions_hash validates :name, :presence => true, :uniqueness => {:scope => [:tenant_id]} validates :hostname, :presence => true, :if => :hostname_required? - validate :hostname_uniqueness_valid?, :if => :hostname_required? + validate :hostname_uniqueness_valid?, :hostname_format_valid?, :if => :hostname_required? scope :with_eligible_manager_types, ->(eligible_types) { where(:type => eligible_types) } @@ -92,6 +92,12 @@ def hostname_uniqueness_valid? errors.add(:hostname, N_("has to be unique per provider type")) if existing_hostnames.include?(hostname.downcase) end + def hostname_format_valid? + return if Validators::Hostname.valid?(hostname) + error_msg = N_("is in a wrong format.") + errors.add(:hostname, _(error_msg)) + end + include NewWithTypeStiMixin include UuidMixin include EmsRefresh::Manager diff --git a/config/application.rb b/config/application.rb index caacdc1dbac1..8f95a9f34c2d 100644 --- a/config/application.rb +++ b/config/application.rb @@ -97,6 +97,7 @@ class Application < Rails::Application config.autoload_paths << Rails.root.join("app", "controllers", "mixins") config.autoload_paths << Rails.root.join("lib") config.autoload_paths << Rails.root.join("lib", "services") + config.autoload_paths << Rails.root.join("lib", "validators") config.autoload_once_paths << Rails.root.join("lib", "vmdb", "console_methods.rb") @@ -166,4 +167,4 @@ class Application < Rails::Application TOPLEVEL_BINDING.eval('self').extend(Vmdb::ConsoleMethods) end end -end +end \ No newline at end of file diff --git a/lib/validators/hostname.rb b/lib/validators/hostname.rb new file mode 100644 index 000000000000..066006fa130f --- /dev/null +++ b/lib/validators/hostname.rb @@ -0,0 +1,18 @@ +module Validators + module Hostname + IS_IPV4_OR_IPV6 = /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))/ + IS_HOSTNAME = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])$/ + + def self.ipv4_or_ipv6?(hostname) + (hostname =~ IS_IPV4_OR_IPV6) ? true : false + end + + def self.valid_hostname?(hostname) + (hostname =~ IS_HOSTNAME) ? true : false + end + + def self.valid?(hostname) + self.valid_hostname?(hostname) || self.ipv4_or_ipv6?(hostname) + end + end +end \ No newline at end of file diff --git a/spec/lib/validators/hostname_spec.rb b/spec/lib/validators/hostname_spec.rb new file mode 100644 index 000000000000..d130cf9673e3 --- /dev/null +++ b/spec/lib/validators/hostname_spec.rb @@ -0,0 +1,31 @@ +describe Validators::Hostname do + context "invalid hostname" do + it "return false if hostname has protocol" do + hostname = "http://example.com" + expect(described_class.valid?(hostname)).to be false + end + it "return false if hostname has path" do + hostname = "example.com/path" + expect(described_class.valid?(hostname)).to be false + end + it "return false if hostname has port" do + hostname = "example.com:8080" + expect(described_class.valid?(hostname)).to be false + end + end + + context "valid hostname" do + it "return true if is a domain name" do + hostname = "example.com" + expect(described_class.valid?(hostname)).to be true + end + it "return true if is a ipv4" do + hostname = "10.10.10.10" + expect(described_class.valid?(hostname)).to be true + end + it "return true if is a ipv6" do + hostname = "2001:cdba:0000:0000:0000:0000:3257:9652" + expect(described_class.valid?(hostname)).to be true + end + end +end \ No newline at end of file