validators 3.1.1 → 3.2.0

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -0
  3. data/README.md +20 -5
  4. data/bin/sync-disposable-hostnames +208 -23
  5. data/bin/sync-tld +11 -8
  6. data/data/country_tlds.json +237 -0
  7. data/data/disposable.json +42 -60317
  8. data/data/disposable/10minutemail.json +3 -0
  9. data/data/disposable/1secmail.json +5 -0
  10. data/data/disposable/FGRibreau_mailchecker.json +33602 -0
  11. data/data/disposable/andreis_disposable_email_domains.json +48320 -0
  12. data/data/disposable/clipmails.json +27 -0
  13. data/data/disposable/cs.json +15 -0
  14. data/data/disposable/emailfake.json +128 -0
  15. data/data/disposable/fake_email_generator.json +11 -0
  16. data/data/disposable/fnando_dafe542cac13f831bbf5521a55248116.json +20 -0
  17. data/data/disposable/gmailnator.json +3 -0
  18. data/data/disposable/guerrillamail.json +13 -0
  19. data/data/disposable/ically.json +28 -0
  20. data/data/disposable/itemp.json +4 -0
  21. data/data/disposable/ivolo_disposable_email_domains.json +48177 -0
  22. data/data/disposable/jespernissen_disposable_maildomain_list.json +2372 -0
  23. data/data/disposable/maxmalysh_disposable_emails.json +21372 -0
  24. data/data/disposable/moakt.json +12 -0
  25. data/data/disposable/receivemail.json +9 -0
  26. data/data/disposable/sneakykiwi_LeagueCreatorPublic.json +2364 -0
  27. data/data/disposable/tempemail.json +7 -0
  28. data/data/disposable/tempemails.json +10 -0
  29. data/data/disposable/tempmail.json +31 -0
  30. data/data/disposable/tempmail_io.json +8 -0
  31. data/data/disposable/tempmailaddress.json +4 -0
  32. data/data/disposable/tempomail.json +3 -0
  33. data/data/disposable/tempr.json +97 -0
  34. data/data/disposable/tmail.json +3 -0
  35. data/data/disposable/wesbos_burner_email_providers.json +4711 -0
  36. data/data/disposable/willwhite_freemail.json +352 -0
  37. data/data/disposable/yepmail.json +12 -0
  38. data/data/disposable_emails.json +3 -0
  39. data/data/disposable_patterns.json +3 -0
  40. data/data/disposable_raw.json +128 -0
  41. data/data/{reserved_hostnames.json → reserved_subdomains.json} +2 -0
  42. data/data/sld.json +5564 -0
  43. data/data/tld.json +2 -0
  44. data/lib/validators.rb +3 -3
  45. data/lib/validators/locale/en.yml +3 -1
  46. data/lib/validators/{reserved_hostnames.rb → reserved_subdomains.rb} +2 -2
  47. data/lib/validators/validates_subdomain.rb +67 -0
  48. data/lib/validators/validates_username.rb +15 -0
  49. data/lib/validators/version.rb +2 -2
  50. data/test/validators/validates_subdomain_test.rb +63 -0
  51. data/test/validators/{validates_reserved_username_test.rb → validates_username_test.rb} +27 -4
  52. data/validators.gemspec +6 -1
  53. metadata +87 -10
  54. data/lib/validators/validates_reserved_hostname.rb +0 -45
  55. data/lib/validators/validates_reserved_username.rb +0 -29
  56. data/test/validators/validates_reserved_hostname_test.rb +0 -40
data/data/tld.json CHANGED
@@ -1437,6 +1437,7 @@
1437
1437
  "xn--mgbbh1a71e",
1438
1438
  "xn--mgbc0a9azcg",
1439
1439
  "xn--mgbca7dzdo",
1440
+ "xn--mgbcpq6gpa1a",
1440
1441
  "xn--mgberp4a5d4ar",
1441
1442
  "xn--mgbgu82a",
1442
1443
  "xn--mgbi4ecexp",
@@ -1462,6 +1463,7 @@
1462
1463
  "xn--pbt977c",
1463
1464
  "xn--pgbs0dh",
1464
1465
  "xn--pssy2u",
1466
+ "xn--q7ce6a",
1465
1467
  "xn--q9jyb4c",
1466
1468
  "xn--qcka1pmc",
1467
1469
  "xn--qxa6a",
data/lib/validators.rb CHANGED
@@ -8,7 +8,7 @@ module Validators
8
8
  require "validators/tld"
9
9
  require "validators/hostname"
10
10
  require "validators/disposable_hostnames"
11
- require "validators/reserved_hostnames"
11
+ require "validators/reserved_subdomains"
12
12
 
13
13
  require "validators/validates_datetime"
14
14
  require "validators/validates_ip_address"
@@ -20,8 +20,8 @@ module Validators
20
20
  require "validators/validates_ssh_private_key"
21
21
  require "validators/validates_ssh_public_key"
22
22
  require "validators/validates_hostname_format_of"
23
- require "validators/validates_reserved_hostname"
24
- require "validators/validates_reserved_username"
23
+ require "validators/validates_subdomain"
24
+ require "validators/validates_username"
25
25
 
26
26
  I18n.load_path += Dir[File.join(__dir__, "validators/locale/*.yml")]
27
27
  end
@@ -20,8 +20,10 @@ en:
20
20
  invalid_ssh_private_key_type: "must be a %{value} key"
21
21
  invalid_ssh_public_key: "is not a valid public SSH key"
22
22
  invalid_url: "is not a valid address"
23
- reserved_hostname: "%{value} is a reserved hostname"
23
+ reserved_subdomain: "%{value} is a reserved subdomain"
24
+ invalid_subdomain: "is invalid"
24
25
  reserved_username: "%{value} is a reserved username"
26
+ invalid_username: "is invalid"
25
27
 
26
28
  activerecord:
27
29
  <<: *activemodel
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Validators
4
- class ReservedHostnames
5
- FILE_PATH = File.expand_path("../../data/reserved_hostnames.json", __dir__)
4
+ class ReservedSubdomains
5
+ FILE_PATH = File.expand_path("../../data/reserved_subdomains.json", __dir__)
6
6
 
7
7
  def self.reserved?(hostname, matchers = nil)
8
8
  matchers = parse_list(matchers) if matchers
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveModel
4
+ module Validations
5
+ class SubdomainValidator < EachValidator
6
+ def validate_each(record, attribute, value)
7
+ return if value.blank? && options[:allow_blank]
8
+ return if value.nil? && options[:allow_nil]
9
+
10
+ validate_reserved_subdomain(record, attribute, value)
11
+ validate_format(record, attribute, value)
12
+ end
13
+
14
+ def reserved?(subdomain)
15
+ ::Validators::ReservedSubdomains.reserved?(subdomain, options[:in])
16
+ end
17
+
18
+ def validate_reserved_subdomain(record, attribute, value)
19
+ return unless options.fetch(:reserved, true)
20
+ return unless reserved?(value)
21
+
22
+ record.errors.add(
23
+ attribute,
24
+ :"reserved_#{options[:error_name]}",
25
+ message: options[:message],
26
+ value: value
27
+ )
28
+ end
29
+
30
+ def validate_format(record, attribute, value)
31
+ return if Validators::Hostname.valid_label?(value)
32
+
33
+ record.errors.add(
34
+ attribute,
35
+ :"invalid_#{options[:error_name]}",
36
+ message: options[:message],
37
+ value: value
38
+ )
39
+ end
40
+ end
41
+
42
+ module ClassMethods
43
+ # Validates whether or not the specified host label is valid.
44
+ # The `in: array` can have strings and patterns. A pattern is everything
45
+ # that starts with `/` and will be parsed as a regular expression.
46
+ #
47
+ # Notice that subdomains will be normalized; it'll be downcased and have
48
+ # its underscores and hyphens stripped before validating.
49
+ #
50
+ # class User < ActiveRecord::Base
51
+ # # Validates format and rejects reserved subdomains.
52
+ # validates_subdomain :subdomain
53
+ #
54
+ # # Validates against a custom list.
55
+ # validates_subdomain :subdomain, in: %w[www]
56
+ #
57
+ # # Rejects reserved domains validation.
58
+ # validates_subdomain :subdomain, reserved: false
59
+ # end
60
+ #
61
+ def validates_subdomain(*attr_names)
62
+ options = _merge_attributes(attr_names).merge(error_name: :subdomain)
63
+ validates_with SubdomainValidator, options
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveModel
4
+ module Validations
5
+ class UsernameValidator < SubdomainValidator
6
+ end
7
+
8
+ module ClassMethods
9
+ def validates_username(*attr_names)
10
+ options = _merge_attributes(attr_names).merge(error_name: :username)
11
+ validates_with UsernameValidator, options
12
+ end
13
+ end
14
+ end
15
+ end
@@ -3,8 +3,8 @@
3
3
  module Validators
4
4
  module Version
5
5
  MAJOR = 3
6
- MINOR = 1
7
- PATCH = 1
6
+ MINOR = 2
7
+ PATCH = 0
8
8
  STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
9
9
  end
10
10
  end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class ValidatesSubdomainTest < Minitest::Test
6
+ test "rejects invalid subdomain" do
7
+ model = build_model do
8
+ attr_accessor :subdomain
9
+ validates_subdomain :subdomain
10
+ end
11
+
12
+ instance = model.new(subdomain: "1234")
13
+
14
+ refute instance.valid?
15
+ assert_includes instance.errors[:subdomain], "is invalid"
16
+ end
17
+
18
+ test "rejects reserved subdomain" do
19
+ model = build_model do
20
+ attr_accessor :subdomain
21
+ validates_subdomain :subdomain
22
+ end
23
+
24
+ instance = model.new(subdomain: "www")
25
+
26
+ refute instance.valid?
27
+ assert_includes instance.errors[:subdomain],
28
+ "www is a reserved subdomain"
29
+ end
30
+
31
+ test "rejects reserved subdomain with pattern" do
32
+ model = build_model do
33
+ attr_accessor :subdomain
34
+ validates_subdomain :subdomain
35
+ end
36
+
37
+ instance = model.new(subdomain: "www1234")
38
+
39
+ refute instance.valid?
40
+ end
41
+
42
+ test "uses custom list" do
43
+ model = build_model do
44
+ attr_accessor :subdomain
45
+ validates_subdomain :subdomain, in: %w[nope]
46
+ end
47
+
48
+ instance = model.new(subdomain: "nope")
49
+
50
+ refute instance.valid?
51
+ end
52
+
53
+ test "ignores reserved subdomain validation" do
54
+ model = build_model do
55
+ attr_accessor :subdomain
56
+ validates_subdomain :subdomain, reserved: false
57
+ end
58
+
59
+ instance = model.new(subdomain: "www")
60
+
61
+ assert instance.valid?
62
+ end
63
+ end
@@ -2,11 +2,23 @@
2
2
 
3
3
  require "test_helper"
4
4
 
5
- class ValidatesReservedUsernameTest < Minitest::Test
5
+ class ValidatesUsernameTest < Minitest::Test
6
+ test "rejects invalid username" do
7
+ model = build_model do
8
+ attr_accessor :username
9
+ validates_username :username
10
+ end
11
+
12
+ instance = model.new(username: "1234")
13
+
14
+ refute instance.valid?
15
+ assert_includes instance.errors[:username], "is invalid"
16
+ end
17
+
6
18
  test "rejects reserved username" do
7
19
  model = build_model do
8
20
  attr_accessor :username
9
- validates_reserved_username :username
21
+ validates_username :username
10
22
  end
11
23
 
12
24
  instance = model.new(username: "www")
@@ -19,7 +31,7 @@ class ValidatesReservedUsernameTest < Minitest::Test
19
31
  test "rejects reserved username with pattern" do
20
32
  model = build_model do
21
33
  attr_accessor :username
22
- validates_reserved_username :username
34
+ validates_username :username
23
35
  end
24
36
 
25
37
  instance = model.new(username: "www1234")
@@ -30,11 +42,22 @@ class ValidatesReservedUsernameTest < Minitest::Test
30
42
  test "uses custom list" do
31
43
  model = build_model do
32
44
  attr_accessor :username
33
- validates_reserved_username :username, in: %w[nope]
45
+ validates_username :username, in: %w[nope]
34
46
  end
35
47
 
36
48
  instance = model.new(username: "nope")
37
49
 
38
50
  refute instance.valid?
39
51
  end
52
+
53
+ test "ignores reserved username validation" do
54
+ model = build_model do
55
+ attr_accessor :username
56
+ validates_username :username, reserved: false
57
+ end
58
+
59
+ instance = model.new(username: "www")
60
+
61
+ assert instance.valid?
62
+ end
40
63
  end
data/validators.gemspec CHANGED
@@ -15,19 +15,24 @@ Gem::Specification.new do |s|
15
15
 
16
16
  s.files = `git ls-files`.split("\n")
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
- s.executables = `git ls-files -- bin/*`.split("\n").map {|f| File.basename(f) }
18
+ s.executables = `git ls-files -- bin/*`
19
+ .split("\n")
20
+ .map {|f| File.basename(f) }
19
21
  s.require_paths = ["lib"]
20
22
 
21
23
  s.add_development_dependency "activerecord"
24
+ s.add_development_dependency "aitch"
22
25
  s.add_development_dependency "cpf_cnpj"
23
26
  s.add_development_dependency "minitest-utils"
24
27
  s.add_development_dependency "mocha"
28
+ s.add_development_dependency "nokogiri"
25
29
  s.add_development_dependency "pry-meta"
26
30
  s.add_development_dependency "rake"
27
31
  s.add_development_dependency "rubocop"
28
32
  s.add_development_dependency "rubocop-fnando"
29
33
  s.add_development_dependency "simplecov"
30
34
  s.add_development_dependency "simplecov-console"
35
+ s.add_development_dependency "simpleidn"
31
36
  s.add_development_dependency "sqlite3", "~> 1.4"
32
37
  s.add_development_dependency "sshkey"
33
38
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: validators
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-26 00:00:00.000000000 Z
11
+ date: 2020-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: aitch
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: cpf_cnpj
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +80,20 @@ dependencies:
66
80
  - - ">="
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: nokogiri
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: pry-meta
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +178,20 @@ dependencies:
150
178
  - - ">="
151
179
  - !ruby/object:Gem::Version
152
180
  version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: simpleidn
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
153
195
  - !ruby/object:Gem::Dependency
154
196
  name: sqlite3
155
197
  requirement: !ruby/object:Gem::Requirement
@@ -195,8 +237,43 @@ files:
195
237
  - Rakefile
196
238
  - bin/sync-disposable-hostnames
197
239
  - bin/sync-tld
240
+ - data/country_tlds.json
198
241
  - data/disposable.json
199
- - data/reserved_hostnames.json
242
+ - data/disposable/10minutemail.json
243
+ - data/disposable/1secmail.json
244
+ - data/disposable/FGRibreau_mailchecker.json
245
+ - data/disposable/andreis_disposable_email_domains.json
246
+ - data/disposable/clipmails.json
247
+ - data/disposable/cs.json
248
+ - data/disposable/emailfake.json
249
+ - data/disposable/fake_email_generator.json
250
+ - data/disposable/fnando_dafe542cac13f831bbf5521a55248116.json
251
+ - data/disposable/gmailnator.json
252
+ - data/disposable/guerrillamail.json
253
+ - data/disposable/ically.json
254
+ - data/disposable/itemp.json
255
+ - data/disposable/ivolo_disposable_email_domains.json
256
+ - data/disposable/jespernissen_disposable_maildomain_list.json
257
+ - data/disposable/maxmalysh_disposable_emails.json
258
+ - data/disposable/moakt.json
259
+ - data/disposable/receivemail.json
260
+ - data/disposable/sneakykiwi_LeagueCreatorPublic.json
261
+ - data/disposable/tempemail.json
262
+ - data/disposable/tempemails.json
263
+ - data/disposable/tempmail.json
264
+ - data/disposable/tempmail_io.json
265
+ - data/disposable/tempmailaddress.json
266
+ - data/disposable/tempomail.json
267
+ - data/disposable/tempr.json
268
+ - data/disposable/tmail.json
269
+ - data/disposable/wesbos_burner_email_providers.json
270
+ - data/disposable/willwhite_freemail.json
271
+ - data/disposable/yepmail.json
272
+ - data/disposable_emails.json
273
+ - data/disposable_patterns.json
274
+ - data/disposable_raw.json
275
+ - data/reserved_subdomains.json
276
+ - data/sld.json
200
277
  - data/tld.json
201
278
  - lib/validators.rb
202
279
  - lib/validators/constants.rb
@@ -205,7 +282,7 @@ files:
205
282
  - lib/validators/ip.rb
206
283
  - lib/validators/locale/en.yml
207
284
  - lib/validators/locale/pt-BR.yml
208
- - lib/validators/reserved_hostnames.rb
285
+ - lib/validators/reserved_subdomains.rb
209
286
  - lib/validators/tld.rb
210
287
  - lib/validators/validates_cnpj_format_of.rb
211
288
  - lib/validators/validates_cpf_format_of.rb
@@ -214,11 +291,11 @@ files:
214
291
  - lib/validators/validates_hostname_format_of.rb
215
292
  - lib/validators/validates_ip_address.rb
216
293
  - lib/validators/validates_ownership_of.rb
217
- - lib/validators/validates_reserved_hostname.rb
218
- - lib/validators/validates_reserved_username.rb
219
294
  - lib/validators/validates_ssh_private_key.rb
220
295
  - lib/validators/validates_ssh_public_key.rb
296
+ - lib/validators/validates_subdomain.rb
221
297
  - lib/validators/validates_url_format_of.rb
298
+ - lib/validators/validates_username.rb
222
299
  - lib/validators/version.rb
223
300
  - test/schema.rb
224
301
  - test/support/dates.rb
@@ -242,15 +319,15 @@ files:
242
319
  - test/validators/validates_ip_address/ipv6_test.rb
243
320
  - test/validators/validates_ip_address_test.rb
244
321
  - test/validators/validates_ownership_of_test.rb
245
- - test/validators/validates_reserved_hostname_test.rb
246
- - test/validators/validates_reserved_username_test.rb
247
322
  - test/validators/validates_ssh_private_key/bits_test.rb
248
323
  - test/validators/validates_ssh_private_key/common_test.rb
249
324
  - test/validators/validates_ssh_private_key/dsa_test.rb
250
325
  - test/validators/validates_ssh_private_key/rsa_test.rb
251
326
  - test/validators/validates_ssh_public_key_test.rb
327
+ - test/validators/validates_subdomain_test.rb
252
328
  - test/validators/validates_url_format_of/with_tld_validation_test.rb
253
329
  - test/validators/validates_url_format_of/without_tld_validation_test.rb
330
+ - test/validators/validates_username_test.rb
254
331
  - validators.gemspec
255
332
  homepage: http://rubygems.org/gems/validators
256
333
  licenses:
@@ -298,12 +375,12 @@ test_files:
298
375
  - test/validators/validates_ip_address/ipv6_test.rb
299
376
  - test/validators/validates_ip_address_test.rb
300
377
  - test/validators/validates_ownership_of_test.rb
301
- - test/validators/validates_reserved_hostname_test.rb
302
- - test/validators/validates_reserved_username_test.rb
303
378
  - test/validators/validates_ssh_private_key/bits_test.rb
304
379
  - test/validators/validates_ssh_private_key/common_test.rb
305
380
  - test/validators/validates_ssh_private_key/dsa_test.rb
306
381
  - test/validators/validates_ssh_private_key/rsa_test.rb
307
382
  - test/validators/validates_ssh_public_key_test.rb
383
+ - test/validators/validates_subdomain_test.rb
308
384
  - test/validators/validates_url_format_of/with_tld_validation_test.rb
309
385
  - test/validators/validates_url_format_of/without_tld_validation_test.rb
386
+ - test/validators/validates_username_test.rb