validates_hostname 1.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6b93ae9e0bcc94ecaf79a327d3120bab167699f8
4
+ data.tar.gz: bf5b1a9a2ab5bcf9791a26fe9dfff850395ca208
5
+ SHA512:
6
+ metadata.gz: 991c1be00d6f1b489451c342e3f885cb850b4555026d79f6d46d6aefffbc493e45046548bb03bc3b66bdf3f4c2b1be860e2e7cbd5f5359b19be51fbc6a3a45e3
7
+ data.tar.gz: 3d1ef718057891a9594f4b72b410bf2fa8a0cb64166809838a13c8179c1046bac82fe5f0d8f8ccb9ebae36c3b140f625384a9bd0625242b71fece4a3e5edeee8
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,2 @@
1
+ * 1.0.0 [2011-01-12]
2
+ * Initial commit
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Sean Huber (shuber@huberry.com)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,205 @@
1
+ = ValidatesHostname
2
+
3
+ * Source: https://github.com/KimNorgaard/validates_hostname
4
+ * Bugs: https://github.com/KimNorgaard/validates_hostname/issues
5
+
6
+ == Description
7
+
8
+ Extension to ActiveRecord::Base for validating hostnames and domain names.
9
+
10
+
11
+ == Features
12
+
13
+ * Adds validation for hostnames to ActiveModel
14
+
15
+ * Supports I18n for the error messages
16
+
17
+ == Installation
18
+
19
+ As plugin (from master)
20
+
21
+ rails plugin install git://github.com/KimNorgaard/validates_hostname.git
22
+
23
+ As gem
24
+
25
+ # in Gemfile
26
+ gem 'validates_hostname', '-> 1.0.0'
27
+
28
+ # Run bundler
29
+ $ bundle install
30
+
31
+
32
+ == Validations performed
33
+
34
+ * maximum length of hostname is 255 characters
35
+
36
+ * maximum length of each hostname label is 63 characters
37
+
38
+ * characters allowed in hostname labels are a-z, A-Z, 0-9 and hyphen
39
+
40
+ * labels do not begin or end with a hyphen
41
+
42
+ * labels do not consist of numeric values only
43
+
44
+
45
+ == Options
46
+
47
+ * option to allow for underscores in hostname labels
48
+
49
+ * option to require that the last label is a valid TLD (ie. require that the name is a FQDN)
50
+
51
+ * option to allow numeric values in the first label of the hostname (exception: the hostname cannot consist of a single numeric label)
52
+
53
+ * option to specify a list of valid TLDs
54
+
55
+ * options to allow for wildcard hostname in first label (for use with DNS)
56
+
57
+ See also http://www.zytrax.com/books/dns/apa/names.html
58
+
59
+
60
+ == How to use
61
+
62
+ Simple usage
63
+
64
+ class Record < ActiveRecord::Base
65
+ validates :name, :hostname => true
66
+ end
67
+
68
+ With options
69
+
70
+ class Record < ActiveRecord::Base
71
+ validates :name, :hostname => { OPTIONS }
72
+ end
73
+
74
+
75
+ == Options and their defaults:
76
+
77
+ * :allow_underscore => false
78
+
79
+ * :require_valid_tld => false
80
+
81
+ * :valid_tlds => Array of allowed TLDs (can only be used with :require_fqdn => true)
82
+
83
+ * :allow_numeric_hostname => false
84
+
85
+
86
+ == Examples
87
+
88
+ Without options
89
+
90
+ class Record < ActiveRecord::Base
91
+ validates :host, :hostname => true
92
+ end
93
+
94
+ >> @record = Record.new :name => 'horse'
95
+ >> @record.save
96
+ => true
97
+
98
+ >> @record2 = Record.new :name => '_horse'
99
+ >> @record2.save
100
+ => false
101
+
102
+ With :allow_underscore
103
+
104
+ class Record < ActiveRecord::Base
105
+ validates :name, :hostname => { :allow_underscore => true }
106
+ end
107
+
108
+ >> @record3 = Record.new :name => '_horse'
109
+ >> @record3.save
110
+ => true
111
+
112
+ With :require_valid_tld
113
+
114
+ class Record < ActiveRecord::Base
115
+ validates :name, :hostname => { :require_valid_tld => true }
116
+ end
117
+
118
+ >> @record4 = Record.new :name => 'horse'
119
+ >> @record4.save
120
+ => false
121
+
122
+ >> @record5 = Record.new :name => 'horse.com'
123
+ >> @record5.save
124
+ => true
125
+
126
+ With :valid_tlds
127
+
128
+ class Record < ActiveRecord::Base
129
+ validates :name, :hostname => { :require_valid_tld, :valid_tlds => %w(com org net) }
130
+ end
131
+
132
+ >> @record6 = Record.new :name => 'horse.info'
133
+ >> @record6.save
134
+ => false
135
+
136
+ With :allow_numeric_hostname
137
+
138
+ class Record < ActiveRecord::Base
139
+ validates :name, :hostname => { :allow_numeric_hostname => false }
140
+ end
141
+
142
+ >> @record7 = Record.new :name => '123.info'
143
+ >> @record7.save
144
+ => false
145
+
146
+ With :allow_wildcard_hostname
147
+
148
+ class Record < ActiveRecord::Base
149
+ validates :name, :hostname => { :allow_wildcard_hostname => true }
150
+ end
151
+
152
+ >> @record8 = Record.new :name => '*.123.info'
153
+ >> @record8.save
154
+ => true
155
+
156
+
157
+ == Extra validators
158
+
159
+ A few extra validators are included.
160
+
161
+ === domainname
162
+
163
+ * sets require_valid_tld => true
164
+
165
+ * sets allow_numeric_hostname => true
166
+
167
+ * returns error if there is only one label and this label is numeric
168
+
169
+ === fqdn
170
+
171
+ * sets require_valid_tld => true
172
+
173
+ === wildcard
174
+
175
+ * sets allow_wildcard_hostname => true
176
+
177
+
178
+ == Error messages
179
+
180
+ Using the I18n system to define new defaults:
181
+
182
+ en:
183
+ errors:
184
+ messages:
185
+ invalid_label_length: "label must be between 1 and 63 characters long"
186
+ label_begins_or_ends_with_hyphen: "label begins or ends with a hyphen"
187
+ hostname_label_is_numeric: "unqualified hostname part cannot consist of numeric values only"
188
+ single_numeric_hostname_label: "hostnames cannot consist of a single numeric label"
189
+ label_contains_invalid_characters: "label contains invalid characters (valid characters: [%{valid_chars}])"
190
+ invalid_hostname_length: "hostname must be between 1 and 255 characters long"
191
+ tld_is_invalid: "tld of hostname is invalid"
192
+
193
+ The %{valid_chars} signifies the range of valid characters allowed in labels.
194
+
195
+ It is highly recommended you use the I18n system for error messages.
196
+
197
+
198
+ == Maintainers
199
+
200
+ * {Kim Nørgaard}[<jasen@jasen.dk>]
201
+
202
+
203
+ == License
204
+
205
+ Copyright (c) 2009-2011 Kim Norgaard, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,66 @@
1
+ require 'rubygems'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'rake/gempackagetask'
5
+ require 'rubygems/specification'
6
+ require 'rspec/core/rake_task'
7
+ require './lib/validates_hostname/version'
8
+
9
+ GEM_NAME = "validates_hostname"
10
+ GEM_VERSION = PAK::ValidatesHostname::VERSION
11
+
12
+ spec = Gem::Specification.new do |s|
13
+ s.name = GEM_NAME
14
+ s.version = GEM_VERSION
15
+ s.platform = Gem::Platform::RUBY
16
+ s.rubyforge_project = "validates_hostname"
17
+ s.has_rdoc = true
18
+ s.extra_rdoc_files = ["README.rdoc", "CHANGELOG.rdoc", "MIT-LICENSE"]
19
+ s.summary = %q{Checks for valid hostnames}
20
+ s.description = %q{Extension to ActiveRecord::Base for validating hostnames}
21
+ s.author = "Kim Norgaard"
22
+ s.email = "jasen@jasen.dk"
23
+ s.homepage = "https://github.com/KimNorgaard/validates_hostname"
24
+ s.require_path = 'lib'
25
+ s.files = %w(validates_hostname.gemspec MIT-LICENSE CHANGELOG.rdoc README.rdoc Rakefile) + Dir.glob("{lib,spec}/**/*")
26
+ end
27
+
28
+ desc 'Test the validates_as_hostname gem/plugin.'
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'lib'
31
+ t.pattern = 'test/*_test.rb'
32
+ t.verbose = true
33
+ end
34
+
35
+ desc 'Default: run specs.'
36
+ task :default => :spec
37
+
38
+ desc "Run specs"
39
+ RSpec::Core::RakeTask.new do |t|
40
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
41
+ end
42
+
43
+ desc 'Generate documentation for plugin.'
44
+ Rake::RDocTask.new(:rdoc) do |rdoc|
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = 'ValidatesHostname'
47
+ rdoc.rdoc_files.include('README.rdoc')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
50
+
51
+ Rake::GemPackageTask.new(spec) do |pkg|
52
+ pkg.gem_spec = spec
53
+ end
54
+
55
+ desc "Install the gem locally"
56
+ task :install => [:package] do
57
+ sh %{gem install pkg/#{GEM_NAME}-#{GEM_VERSION}}
58
+ end
59
+
60
+ desc "Create a gemspec file"
61
+ task :make_spec do
62
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
63
+ file.puts spec.to_ruby
64
+ end
65
+ end
66
+
@@ -0,0 +1,176 @@
1
+ require 'active_support/concern'
2
+ require 'active_model'
3
+
4
+ module PAK
5
+ module ValidatesHostname
6
+ autoload :VERSION, 'validates_hostname/version'
7
+
8
+ # List from IANA: http://www.iana.org/domains/root/db/
9
+ ALLOWED_TLDS = %w(
10
+ ac ad ae aero af ag ai al am an ao aq ar arpa as asia at au aw ax az
11
+ ba bb bd be bf bg bh bi biz bj bl bm bn bo br bs bt bv bw by bz
12
+ ca cat cc cd cf cg ch ci ck cl cm cn co com coop cr cu cv cx cy cz
13
+ de dj dk dm do dz
14
+ ec edu ee eg eh er es et eu
15
+ fi fj fk fm fo fr
16
+ ga gb gd ge gf gg gh gi gl gm gn gov gp gq gr gs gt gu gw gy
17
+ hk hm hn hr ht hu
18
+ id ie il im in info int io iq ir is it
19
+ je jm jo jobs jp
20
+ ke kg kh ki km kn kp kr kw ky kz
21
+ la lb lc li lk lr ls lt lu lv ly
22
+ ma mc md me mf mg mh mil mk ml mm mn mo mobi mp mq mr ms mt mu museum
23
+ mv mw mx my mz
24
+ na name nc ne net nf ng ni nl no np nr nu nz
25
+ om org
26
+ pa pe pf pg ph pk pl pm pn pr pro ps pt pw py
27
+ qa
28
+ re ro rs ru rw
29
+ sa sb sc sd se sg sh si sj sk sl sm sn so sr st su sv sy sz
30
+ tc td tel tf tg th tj tk tl tm tn to tp tr travel tt tv tw tz
31
+ ua ug uk um us uy uz
32
+ va vc ve vg vi vn vu
33
+ wf ws
34
+ ye yt yu
35
+ za zm zw
36
+ )
37
+
38
+ DEFAULT_ERROR_MSG = {
39
+ :invalid_hostname_length => 'hostname must be between 1 and 255 characters long',
40
+ :invalid_label_length => 'label must be between 1 and 63 characters long',
41
+ :label_begins_or_ends_with_hyphen => 'label begins or ends with hyphen',
42
+ :label_contains_invalid_characters => "label contains invalid characters (valid characters: [%{valid_chars}])",
43
+ :hostname_label_is_numeric => 'unqualified hostname part cannot consist of numeric values only',
44
+ :hostname_is_not_fqdn => 'hostname is not a fully qualified domain name',
45
+ :single_numeric_hostname_label => 'hostnames cannot consist of a single numeric label'
46
+ }.freeze
47
+
48
+ class HostnameValidator < ActiveModel::EachValidator
49
+ def initialize(options)
50
+ opts = {
51
+ :allow_underscore => false,
52
+ :require_valid_tld => false,
53
+ :valid_tlds => ALLOWED_TLDS,
54
+ :allow_numeric_hostname => false,
55
+ :allow_wildcard_hostname => false
56
+ }.merge(options)
57
+ super(opts)
58
+ end
59
+
60
+ def validate_each(record, attribute, value)
61
+ value ||= ''
62
+ # maximum hostname length: 255 characters
63
+ add_error(record, attribute, :invalid_hostname_length) unless value.length.between?(1, 255)
64
+
65
+ # split each hostname into labels and do various checks
66
+ if value.is_a?(String)
67
+ labels = value.split '.'
68
+ labels.each_with_index do |label, index|
69
+ # CHECK 1: hostname label cannot be longer than 63 characters
70
+ add_error(record, attribute, :invalid_label_length) unless value.length.between?(1, 63)
71
+
72
+ # CHECK 2: hostname label cannot begin or end with hyphen
73
+ add_error(record, attribute, :label_begins_or_ends_with_hyphen) if label =~ /^[-]/i or label =~ /[-]$/
74
+
75
+ # Take care of wildcard first label
76
+ next if options[:allow_wildcard_hostname] and label == '*' and index == 0
77
+
78
+ # CHECK 3: hostname can only contain characters:
79
+ # a-z, 0-9, hyphen, optional underscore, optional asterisk
80
+ valid_chars = 'a-z0-9\-'
81
+ valid_chars << '_' if options[:allow_underscore] == true
82
+ add_error(record, attribute, :label_contains_invalid_characters, :valid_chars => valid_chars) unless label =~ /^[#{valid_chars}]+$/i
83
+ end
84
+
85
+ # CHECK 4: the unqualified hostname portion cannot consist of
86
+ # numeric values only
87
+ if options[:allow_numeric_hostname] == false
88
+ is_numeric_only = (
89
+ (
90
+ Integer(labels[0]) rescue false
91
+ ) ? true : false
92
+ )
93
+ add_error(record, attribute, :hostname_label_is_numeric) if is_numeric_only
94
+ end
95
+
96
+ # CHECK 5: in order to be fully qualified, the full hostname's
97
+ # TLD must be valid
98
+ if options[:require_valid_tld] == true
99
+ has_tld = options[:valid_tlds].select {
100
+ |tld| tld =~ /^#{Regexp.escape(labels.last || '')}$/i
101
+ }.empty? ? false : true
102
+ add_error(record, attribute, :hostname_is_not_fqdn) unless has_tld
103
+ end
104
+ end
105
+ end
106
+
107
+ def add_error(record, attr_name, message, *interpolators)
108
+ args = {
109
+ :default => [DEFAULT_ERROR_MSG[message], options[:message]],
110
+ :scope => [:errors, :messages]
111
+ }.merge(interpolators.last.is_a?(Hash) ? interpolators.pop : {})
112
+ record.errors.add(attr_name, I18n.t( message, args ))
113
+ end
114
+ end
115
+
116
+ class DomainnameValidator < HostnameValidator
117
+ def initialize(options)
118
+ opts = {
119
+ :require_valid_tld => true,
120
+ :allow_numeric_hostname => true
121
+ }.merge(options)
122
+ super(opts)
123
+ end
124
+
125
+ def validate_each(record, attribute, value)
126
+ super
127
+
128
+ if value.is_a?(String)
129
+ labels = value.split '.'
130
+ labels.each do |label|
131
+ # CHECK 1: if there is only one label it cannot be numeric even
132
+ # though numeric hostnames are allowed
133
+ if options[:allow_numeric_hostname] == true
134
+ is_numeric_only = (
135
+ (
136
+ Integer(labels[0]) rescue false
137
+ ) ? true : false
138
+ )
139
+ if is_numeric_only and labels.size == 1
140
+ add_error(record, attribute, :single_numeric_hostname_label)
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+
147
+ def add_error(record, attr_name, message, *interpolators)
148
+ args = {
149
+ :default => [DEFAULT_ERROR_MSG[message], options[:message]],
150
+ :scope => [:errors, :messages]
151
+ }.merge(interpolators.last.is_a?(Hash) ? interpolators.pop : {})
152
+ record.errors.add(attr_name, I18n.t( message, args ))
153
+ end
154
+ end
155
+
156
+ class FqdnValidator < HostnameValidator
157
+ def initialize(options)
158
+ opts = {
159
+ :require_valid_tld => true,
160
+ }.merge(options)
161
+ super(opts)
162
+ end
163
+ end
164
+
165
+ class WildcardValidator < HostnameValidator
166
+ def initialize(options)
167
+ opts = {
168
+ :allow_wildcard_hostname => true,
169
+ }.merge(options)
170
+ super(opts)
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ ActiveRecord::Base.send(:include, PAK::ValidatesHostname)
@@ -0,0 +1,5 @@
1
+ module PAK
2
+ module ValidatesHostname
3
+ VERSION = '1.0.1'
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "validates_hostname/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'validates_hostname'
7
+ s.version = PAK::ValidatesHostname::VERSION
8
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
+ s.authors = ["Kim Nørgaard"]
10
+ s.description = 'Extension to ActiveRecord::Base for validating hostnames'
11
+ s.summary = 'Checks for valid hostnames'
12
+ s.email = 'jasen@jasen.dk'
13
+ s.extra_rdoc_files = ["README.rdoc", "CHANGELOG.rdoc", "MIT-LICENSE"]
14
+ s.files = ["validates_hostname.gemspec", "MIT-LICENSE", "CHANGELOG.rdoc", "README.rdoc", "Rakefile", "lib/validates_hostname", "lib/validates_hostname/version.rb", "lib/validates_hostname.rb"]
15
+ s.homepage = %q{https://github.com/KimNorgaard/validates_hostname}
16
+ s.licenses = 'MIT'
17
+ s.require_paths = ["lib"]
18
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: validates_hostname
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Kim Nørgaard
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-07 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Extension to ActiveRecord::Base for validating hostnames
14
+ email: jasen@jasen.dk
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files:
18
+ - README.rdoc
19
+ - CHANGELOG.rdoc
20
+ - MIT-LICENSE
21
+ files:
22
+ - validates_hostname.gemspec
23
+ - MIT-LICENSE
24
+ - CHANGELOG.rdoc
25
+ - README.rdoc
26
+ - Rakefile
27
+ - lib/validates_hostname/version.rb
28
+ - lib/validates_hostname.rb
29
+ homepage: https://github.com/KimNorgaard/validates_hostname
30
+ licenses:
31
+ - MIT
32
+ metadata: {}
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubyforge_project:
49
+ rubygems_version: 2.0.3
50
+ signing_key:
51
+ specification_version: 4
52
+ summary: Checks for valid hostnames
53
+ test_files: []